github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-internal.h (about) 1 /* 2 * jit-internal.h - Internal definitions for the JIT. 3 * 4 * Copyright (C) 2004 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 #ifndef _JIT_INTERNAL_H 24 #define _JIT_INTERNAL_H 25 26 #include <jit/jit.h> 27 #include "jit-config.h" 28 29 #if defined(HAVE_STRING_H) 30 # include <string.h> 31 #elif defined(HAVE_STRINGS_H) 32 # include <strings.h> 33 #endif 34 #if defined(HAVE_MEMORY_H) 35 # include <memory.h> 36 #endif 37 38 /* 39 * Macros that replace the routines in <jit/jit-util.h> 40 * with direct calls on the underlying library functions. 41 */ 42 #if defined(HAVE_MEMSET) 43 # define jit_memset(s, c, len) (memset((s), (c), (len))) 44 # define jit_memzero(s, len) (memset((s), 0, (len))) 45 #elif defined(HAVE_BZERO) 46 # define jit_memzero(s, len) (bzero((char *)(s), (len))) 47 #else 48 # define jit_memzero(s, len) (jit_memset((char *)(s), 0, (len))) 49 #endif 50 #if defined(HAVE_MEMCPY) 51 # define jit_memcpy(s1, s2, len) (memcpy((s1), (s2), (len))) 52 #endif 53 #if defined(HAVE_MEMMOVE) 54 # define jit_memmove(s1, s2, len) (memmove((s1), (s2), (len))) 55 #endif 56 #if defined(HAVE_MEMCMP) 57 # define jit_memcmp(s1, s2, len) (memcmp((s1), (s2), (len))) 58 #elif defined(HAVE_BCMP) 59 # define jit_memcmp(s1, s2, len) (bcmp((char *)(s1), (char *)(s2), (len))) 60 #endif 61 #if defined(HAVE_MEMCHR) 62 # define jit_memchr(s, c, len) (memchr((s), (c), (len))) 63 #endif 64 65 /* 66 * We need the apply rules for "jit_redirector_size". 67 */ 68 #include "jit-apply-func.h" 69 70 /* 71 * Include the thread routines. 72 */ 73 #include "jit-thread.h" 74 75 /* 76 * Include varint encoding for bytecode offset data. 77 */ 78 #include "jit-varint.h" 79 80 #ifdef __cplusplus 81 extern "C" { 82 #endif 83 84 /* 85 * The following is some macro magic that attempts to detect 86 * the best alignment to use on the target platform. The final 87 * value, "JIT_BEST_ALIGNMENT", will be a compile-time constant. 88 */ 89 90 #define _JIT_ALIGN_CHECK_TYPE(type,name) \ 91 struct _JIT_align_##name { \ 92 jit_sbyte pad; \ 93 type field; \ 94 } 95 96 #define _JIT_ALIGN_FOR_TYPE(name) \ 97 ((jit_nuint)(&(((struct _JIT_align_##name *)0)->field))) 98 99 #define _JIT_ALIGN_MAX(a,b) \ 100 ((a) > (b) ? (a) : (b)) 101 102 #define _JIT_ALIGN_MAX3(a,b,c) \ 103 (_JIT_ALIGN_MAX((a), _JIT_ALIGN_MAX((b), (c)))) 104 105 _JIT_ALIGN_CHECK_TYPE(jit_sbyte, sbyte); 106 _JIT_ALIGN_CHECK_TYPE(jit_short, short); 107 _JIT_ALIGN_CHECK_TYPE(jit_int, int); 108 _JIT_ALIGN_CHECK_TYPE(jit_long, long); 109 _JIT_ALIGN_CHECK_TYPE(jit_ptr, ptr); 110 _JIT_ALIGN_CHECK_TYPE(jit_float32, float); 111 _JIT_ALIGN_CHECK_TYPE(jit_float64, double); 112 _JIT_ALIGN_CHECK_TYPE(jit_nfloat, nfloat); 113 114 #if defined(JIT_X86) 115 /* Sometimes the code below guesses wrong on Win32 platforms */ 116 #define JIT_BEST_ALIGNMENT 4 117 #else 118 #define JIT_BEST_ALIGNMENT \ 119 _JIT_ALIGN_MAX(_JIT_ALIGN_MAX3(_JIT_ALIGN_FOR_TYPE(int), \ 120 _JIT_ALIGN_FOR_TYPE(long), \ 121 _JIT_ALIGN_FOR_TYPE(ptr)), \ 122 _JIT_ALIGN_MAX3(_JIT_ALIGN_FOR_TYPE(float), \ 123 _JIT_ALIGN_FOR_TYPE(double), \ 124 _JIT_ALIGN_FOR_TYPE(nfloat))) 125 #endif 126 127 /* 128 * Get the alignment values for various system types. 129 * These will also be compile-time constants. 130 */ 131 #define JIT_ALIGN_SBYTE _JIT_ALIGN_FOR_TYPE(sbyte) 132 #define JIT_ALIGN_UBYTE _JIT_ALIGN_FOR_TYPE(sbyte) 133 #define JIT_ALIGN_SHORT _JIT_ALIGN_FOR_TYPE(short) 134 #define JIT_ALIGN_USHORT _JIT_ALIGN_FOR_TYPE(short) 135 #define JIT_ALIGN_CHAR _JIT_ALIGN_FOR_TYPE(char) 136 #define JIT_ALIGN_INT _JIT_ALIGN_FOR_TYPE(int) 137 #define JIT_ALIGN_UINT _JIT_ALIGN_FOR_TYPE(int) 138 #define JIT_ALIGN_NINT _JIT_ALIGN_FOR_TYPE(ptr) 139 #define JIT_ALIGN_NUINT _JIT_ALIGN_FOR_TYPE(ptr) 140 #define JIT_ALIGN_LONG _JIT_ALIGN_FOR_TYPE(long) 141 #define JIT_ALIGN_ULONG _JIT_ALIGN_FOR_TYPE(long) 142 #define JIT_ALIGN_FLOAT32 _JIT_ALIGN_FOR_TYPE(float) 143 #define JIT_ALIGN_FLOAT64 _JIT_ALIGN_FOR_TYPE(double) 144 #define JIT_ALIGN_NFLOAT _JIT_ALIGN_FOR_TYPE(nfloat) 145 #define JIT_ALIGN_PTR _JIT_ALIGN_FOR_TYPE(ptr) 146 147 /* 148 * Structure of a memory pool. 149 */ 150 typedef struct jit_pool_block *jit_pool_block_t; 151 struct jit_pool_block 152 { 153 jit_pool_block_t next; 154 char data[1]; 155 }; 156 typedef struct 157 { 158 unsigned int elem_size; 159 unsigned int elems_per_block; 160 unsigned int elems_in_last; 161 jit_pool_block_t blocks; 162 void *free_list; 163 164 } jit_memory_pool; 165 166 /* 167 * Initialize a memory pool. 168 */ 169 void _jit_memory_pool_init(jit_memory_pool *pool, unsigned int elem_size); 170 #define jit_memory_pool_init(pool,type) \ 171 _jit_memory_pool_init((pool), sizeof(type)) 172 173 /* 174 * Free the contents of a memory pool. 175 */ 176 void _jit_memory_pool_free(jit_memory_pool *pool, jit_meta_free_func func); 177 #define jit_memory_pool_free(pool,func) _jit_memory_pool_free((pool), (func)) 178 179 /* 180 * Allocate an item from a memory pool. 181 */ 182 void *_jit_memory_pool_alloc(jit_memory_pool *pool); 183 #define jit_memory_pool_alloc(pool,type) \ 184 ((type *)_jit_memory_pool_alloc((pool))) 185 186 /* 187 * Deallocate an item back to a memory pool. 188 */ 189 void _jit_memory_pool_dealloc(jit_memory_pool *pool, void *item); 190 #define jit_memory_pool_dealloc(pool,item) \ 191 (_jit_memory_pool_dealloc((pool), (item))) 192 193 /* 194 * Storage for metadata. 195 */ 196 struct _jit_meta 197 { 198 int type; 199 void *data; 200 jit_meta_free_func free_data; 201 jit_meta_t next; 202 jit_function_t pool_owner; 203 }; 204 205 /* 206 * Control flow graph edge. 207 */ 208 typedef struct _jit_edge *_jit_edge_t; 209 struct _jit_edge 210 { 211 /* Source node of the edge */ 212 jit_block_t src; 213 214 /* Destination node of the edge */ 215 jit_block_t dst; 216 217 /* Edge flags */ 218 int flags; 219 }; 220 221 #define _JIT_EDGE_FALLTHRU 0 222 #define _JIT_EDGE_BRANCH 1 223 #define _JIT_EDGE_RETURN 2 224 #define _JIT_EDGE_EXCEPT 3 225 226 /* 227 * Internal structure of a basic block. 228 */ 229 struct _jit_block 230 { 231 jit_function_t func; 232 jit_label_t label; 233 234 /* List of all instructions in this block */ 235 jit_insn_t insns; 236 int num_insns; 237 int max_insns; 238 239 /* Next and previous blocks in the function's linear block list */ 240 jit_block_t next; 241 jit_block_t prev; 242 243 /* Edges to successor blocks in control flow graph */ 244 _jit_edge_t *succs; 245 int num_succs; 246 247 /* Edges to predecessor blocks in control flow graph */ 248 _jit_edge_t *preds; 249 int num_preds; 250 251 /* Control flow flags */ 252 unsigned visited : 1; 253 unsigned ends_in_dead : 1; 254 unsigned address_of : 1; 255 256 /* Metadata */ 257 jit_meta_t meta; 258 259 /* Code generation data */ 260 void *address; 261 void *fixup_list; 262 void *fixup_absolute_list; 263 }; 264 265 /* 266 * Internal structure of a value. 267 */ 268 struct _jit_value 269 { 270 jit_block_t block; 271 jit_type_t type; 272 unsigned is_temporary : 1; 273 unsigned is_local : 1; 274 unsigned is_volatile : 1; 275 unsigned is_addressable : 1; 276 unsigned is_constant : 1; 277 unsigned is_nint_constant : 1; 278 unsigned is_parameter : 1; 279 unsigned is_reg_parameter : 1; 280 unsigned has_address : 1; 281 unsigned free_address : 1; 282 unsigned in_register : 1; 283 unsigned in_frame : 1; 284 unsigned in_global_register : 1; 285 unsigned live : 1; 286 unsigned next_use : 1; 287 unsigned has_frame_offset : 1; 288 unsigned global_candidate : 1; 289 unsigned has_global_register : 1; 290 short reg; 291 short global_reg; 292 jit_nint address; 293 jit_nint frame_offset; 294 jit_nuint usage_count; 295 int index; 296 }; 297 #define JIT_INVALID_FRAME_OFFSET ((jit_nint)0x7FFFFFFF) 298 299 /* 300 * Free the structures that are associated with a value. 301 */ 302 void _jit_value_free(void *value); 303 304 /* 305 * Add references to all of the parameter values in a function. 306 * This is used when the initialization block is split during a 307 * "jit_insn_move_blocks_to_start" instruction. 308 */ 309 void _jit_value_ref_params(jit_function_t func); 310 311 /* 312 * Internal structure of an instruction. 313 */ 314 struct _jit_insn 315 { 316 short opcode; 317 short flags; 318 jit_value_t dest; 319 jit_value_t value1; 320 jit_value_t value2; 321 }; 322 323 /* 324 * Instruction flags. 325 */ 326 #define JIT_INSN_DEST_LIVE 0x0001 327 #define JIT_INSN_DEST_NEXT_USE 0x0002 328 #define JIT_INSN_VALUE1_LIVE 0x0004 329 #define JIT_INSN_VALUE1_NEXT_USE 0x0008 330 #define JIT_INSN_VALUE2_LIVE 0x0010 331 #define JIT_INSN_VALUE2_NEXT_USE 0x0020 332 #define JIT_INSN_LIVENESS_FLAGS 0x003F 333 #define JIT_INSN_DEST_IS_LABEL 0x0040 334 #define JIT_INSN_DEST_IS_FUNCTION 0x0080 335 #define JIT_INSN_DEST_IS_NATIVE 0x0100 336 #define JIT_INSN_DEST_OTHER_FLAGS 0x01C0 337 #define JIT_INSN_VALUE1_IS_NAME 0x0200 338 #define JIT_INSN_VALUE1_IS_LABEL 0x0400 339 #define JIT_INSN_VALUE1_OTHER_FLAGS 0x0600 340 #define JIT_INSN_VALUE2_IS_SIGNATURE 0x0800 341 #define JIT_INSN_VALUE2_OTHER_FLAGS 0x0800 342 #define JIT_INSN_DEST_IS_VALUE 0x1000 343 344 /* 345 * Information about each label associated with a function. 346 * 347 * Multiple labels may belong to the same basic block. Such labels are 348 * linked into list. 349 */ 350 typedef struct _jit_label_info _jit_label_info_t; 351 struct _jit_label_info 352 { 353 /* Block the label assigned to */ 354 jit_block_t block; 355 356 /* Next label that might belong to the same block */ 357 jit_label_t alias; 358 359 /* Label flags */ 360 int flags; 361 }; 362 363 #define JIT_LABEL_ADDRESS_OF 0x0001 364 365 366 /* 367 * Information that is associated with a function for building 368 * the instructions and values. This structure can be discarded 369 * once the function has been fully compiled. 370 */ 371 typedef struct _jit_builder *jit_builder_t; 372 struct _jit_builder 373 { 374 /* Entry point for the function (and the head of the block list) */ 375 jit_block_t entry_block; 376 377 /* Exit point for the function (and the tail of the block list) */ 378 jit_block_t exit_block; 379 380 /* The position to insert initialization blocks */ 381 jit_block_t init_block; 382 383 /* The current block that is being constructed */ 384 jit_block_t current_block; 385 386 /* The list of deleted blocks */ 387 jit_block_t deleted_blocks; 388 389 /* Blocks sorted in order required by an optimization pass */ 390 jit_block_t *block_order; 391 int num_block_order; 392 393 /* The next block label to be allocated */ 394 jit_label_t next_label; 395 396 /* Mapping from label numbers to blocks */ 397 _jit_label_info_t *label_info; 398 jit_label_t max_label_info; 399 400 /* Exception handling definitions for the function */ 401 jit_value_t setjmp_value; 402 jit_value_t thrown_exception; 403 jit_value_t thrown_pc; 404 jit_label_t catcher_label; 405 jit_value_t eh_frame_info; 406 407 /* Flag that is set to indicate that this function is not a leaf */ 408 unsigned non_leaf : 1; 409 410 /* Flag that indicates if we've seen code that may throw an exception */ 411 unsigned may_throw : 1; 412 413 /* Flag that indicates if the function has an ordinary return */ 414 unsigned ordinary_return : 1; 415 416 /* Flag that indicates that the current function contains a tail call */ 417 unsigned has_tail_call : 1; 418 419 /* Generate position-independent code */ 420 unsigned position_independent : 1; 421 422 /* Memory pools that contain values, instructions, and metadata blocks */ 423 jit_memory_pool value_pool; 424 jit_memory_pool edge_pool; 425 jit_memory_pool meta_pool; 426 427 /* Common constants that have been cached */ 428 jit_value_t null_constant; 429 jit_value_t zero_constant; 430 431 /* The values for the parameters, structure return, and parent frame */ 432 jit_value_t *param_values; 433 jit_value_t struct_return; 434 jit_value_t parent_frame; 435 436 /* Metadata that is stored only while the function is being built */ 437 jit_meta_t meta; 438 439 /* Current size of the local variable frame (used by the back end) */ 440 jit_nint frame_size; 441 442 /* Number of stack items that are queued for a deferred pop */ 443 jit_nint deferred_items; 444 445 /* Size of the outgoing parameter area in the frame */ 446 jit_nint param_area_size; 447 448 #ifdef _JIT_COMPILE_DEBUG 449 int block_count; 450 int insn_count; 451 #endif 452 }; 453 454 /* 455 * Internal structure of a function. 456 */ 457 struct _jit_function 458 { 459 /* The context that the function is associated with */ 460 jit_context_t context; 461 jit_function_t next; 462 jit_function_t prev; 463 464 /* Containing function in a nested context */ 465 jit_function_t nested_parent; 466 jit_value_t parent_frame; 467 #ifdef JIT_BACKEND_INTERP 468 jit_value_t arguments_pointer; 469 jit_nint arguments_pointer_offset; 470 #endif 471 jit_function_t cached_parent; 472 jit_value_t cached_parent_frame; 473 474 /* Metadata that survives once the builder is discarded */ 475 jit_meta_t meta; 476 477 /* The signature for this function */ 478 jit_type_t signature; 479 480 /* The builder information for this function */ 481 jit_builder_t builder; 482 483 /* Debug information for this function */ 484 jit_varint_data_t bytecode_offset; 485 486 /* Cookie value for this function */ 487 void *cookie; 488 489 /* Flag bits for this function */ 490 unsigned is_recompilable : 1; 491 unsigned is_optimized : 1; 492 unsigned no_throw : 1; 493 unsigned no_return : 1; 494 unsigned has_try : 1; 495 unsigned optimization_level : 8; 496 497 /* Flag set once the function is compiled */ 498 int volatile is_compiled; 499 500 /* The entry point for the function's compiled code */ 501 void * volatile entry_point; 502 503 /* The function to call to perform on-demand compilation */ 504 jit_on_demand_func on_demand; 505 506 #ifndef JIT_BACKEND_INTERP 507 # ifdef jit_redirector_size 508 /* Buffer that contains the redirector for this function. 509 Redirectors are used to support on-demand compilation */ 510 unsigned char *redirector; 511 # endif 512 513 /* Buffer that contains the indirector for this function. 514 The indirector jumps to the address that is currently 515 stored in the entry_point field. Indirectors are used 516 to support recompilation and on-demand compilation. */ 517 unsigned char *indirector; 518 #endif 519 }; 520 521 /* 522 * Ensure that there is a builder associated with a function. 523 */ 524 int _jit_function_ensure_builder(jit_function_t func); 525 526 /* 527 * Free the builder associated with a function. 528 */ 529 void _jit_function_free_builder(jit_function_t func); 530 531 /* 532 * Destroy all memory associated with a function. 533 */ 534 void _jit_function_destroy(jit_function_t func); 535 536 /* 537 * Compute value liveness and "next use" information for a function. 538 */ 539 void _jit_function_compute_liveness(jit_function_t func); 540 541 /* 542 * Compile a function on-demand. Returns the entry point. 543 */ 544 void *_jit_function_compile_on_demand(jit_function_t func); 545 546 /* 547 * Get the bytecode offset that is associated with a native 548 * offset within a method. Returns JIT_CACHE_NO_OFFSET 549 * if the bytecode offset could not be determined. 550 */ 551 unsigned long _jit_function_get_bytecode(jit_function_t func, void *func_info, void *pc, int exact); 552 553 /* 554 * Information about a registered external symbol. 555 */ 556 typedef struct jit_regsym *jit_regsym_t; 557 struct jit_regsym 558 { 559 void *value; 560 int after; 561 char name[1]; 562 }; 563 564 /* 565 * Internal structure of a context. 566 */ 567 struct _jit_context 568 { 569 /* The context's memory control */ 570 jit_memory_manager_t memory_manager; 571 jit_memory_context_t memory_context; 572 jit_mutex_t memory_lock; 573 574 /* Lock that controls access to the building process */ 575 jit_mutex_t builder_lock; 576 577 /* List of functions that are currently registered with the context */ 578 jit_function_t functions; 579 jit_function_t last_function; 580 581 /* Metadata that is associated with the context */ 582 jit_meta_t meta; 583 584 /* ELF binaries that have been loaded into this context */ 585 jit_readelf_t elf_binaries; 586 587 /* Table of symbols that have been registered with this context */ 588 jit_regsym_t *registered_symbols; 589 int num_registered_symbols; 590 591 /* Debugger support */ 592 jit_debugger_hook_func debug_hook; 593 jit_debugger_t debugger; 594 595 /* On-demand compilation driver */ 596 jit_on_demand_driver_func on_demand_driver; 597 }; 598 599 void *_jit_malloc_exec(unsigned int size); 600 void _jit_free_exec(void *ptr, unsigned int size); 601 void _jit_flush_exec(void *ptr, unsigned int size); 602 603 void _jit_memory_lock(jit_context_t context); 604 void _jit_memory_unlock(jit_context_t context); 605 606 int _jit_memory_ensure(jit_context_t context); 607 void _jit_memory_destroy(jit_context_t context); 608 609 jit_function_info_t _jit_memory_find_function_info(jit_context_t context, void *pc); 610 jit_function_t _jit_memory_get_function(jit_context_t context, jit_function_info_t info); 611 void *_jit_memory_get_function_start(jit_context_t context, jit_function_info_t info); 612 void *_jit_memory_get_function_end(jit_context_t context, jit_function_info_t info); 613 614 jit_function_t _jit_memory_alloc_function(jit_context_t context); 615 void _jit_memory_free_function(jit_context_t context, jit_function_t func); 616 int _jit_memory_start_function(jit_context_t context, jit_function_t func); 617 int _jit_memory_end_function(jit_context_t context, int result); 618 int _jit_memory_extend_limit(jit_context_t context, int count); 619 void *_jit_memory_get_limit(jit_context_t context); 620 void *_jit_memory_get_break(jit_context_t context); 621 void _jit_memory_set_break(jit_context_t context, void *brk); 622 void *_jit_memory_alloc_trampoline(jit_context_t context); 623 void _jit_memory_free_trampoline(jit_context_t context, void *ptr); 624 void *_jit_memory_alloc_closure(jit_context_t context); 625 void _jit_memory_free_closure(jit_context_t context, void *ptr); 626 void *_jit_memory_alloc_data(jit_context_t context, jit_size_t size, jit_size_t align); 627 628 /* 629 * Backtrace control structure, for managing stack traces. 630 * These structures must be allocated on the stack. 631 */ 632 typedef struct jit_backtrace *jit_backtrace_t; 633 struct jit_backtrace 634 { 635 jit_backtrace_t parent; 636 void *pc; 637 void *security_object; 638 jit_meta_free_func free_security_object; 639 }; 640 641 /* 642 * Push a new backtrace onto the stack. The fields in "trace" are filled in. 643 */ 644 void _jit_backtrace_push(jit_backtrace_t trace, void *pc); 645 646 /* 647 * Pop the top-most backtrace item. 648 */ 649 void _jit_backtrace_pop(void); 650 651 /* 652 * Reset the backtrace stack to "trace". Used in exception catch 653 * blocks to fix up the backtrace information. 654 */ 655 void _jit_backtrace_set(jit_backtrace_t trace); 656 657 /* 658 * Control information that is associated with a thread. 659 */ 660 struct jit_thread_control 661 { 662 void *last_exception; 663 jit_exception_func exception_handler; 664 jit_backtrace_t backtrace_head; 665 struct jit_jmp_buf *setjmp_head; 666 }; 667 668 /* 669 * Initialize the block list for a function. 670 */ 671 int _jit_block_init(jit_function_t func); 672 673 /* 674 * Free all blocks that are associated with a function. 675 */ 676 void _jit_block_free(jit_function_t func); 677 678 /* 679 * Build control flow graph edges for all blocks associated with a 680 * function. 681 */ 682 void _jit_block_build_cfg(jit_function_t func); 683 684 /* 685 * Eliminate useless control flow between blocks in a function. 686 */ 687 void _jit_block_clean_cfg(jit_function_t func); 688 689 /* 690 * Compute block postorder for control flow graph depth first traversal. 691 */ 692 int _jit_block_compute_postorder(jit_function_t func); 693 694 /* 695 * Create a new block and associate it with a function. 696 */ 697 jit_block_t _jit_block_create(jit_function_t func); 698 699 /* 700 * Destroy a block. 701 */ 702 void _jit_block_destroy(jit_block_t block); 703 704 /* 705 * Detach blocks from their current position in a function. 706 */ 707 void _jit_block_detach(jit_block_t first, jit_block_t last); 708 709 /* 710 * Attach blocks to a function after a specific position. 711 */ 712 void _jit_block_attach_after(jit_block_t block, jit_block_t first, jit_block_t last); 713 714 /* 715 * Attach blocks to a function before a specific position. 716 */ 717 void _jit_block_attach_before(jit_block_t block, jit_block_t first, jit_block_t last); 718 719 /* 720 * Record the label mapping for a block. 721 */ 722 int _jit_block_record_label(jit_block_t block, jit_label_t label); 723 724 /* 725 * Record the label flags. 726 */ 727 int _jit_block_record_label_flags(jit_function_t func, jit_label_t label, int flags); 728 729 /* 730 * Add an instruction to a block. 731 */ 732 jit_insn_t _jit_block_add_insn(jit_block_t block); 733 734 /* 735 * Get the last instruction in a block. NULL if the block is empty. 736 */ 737 jit_insn_t _jit_block_get_last(jit_block_t block); 738 739 /* 740 * The block goes just before the function end possibly excluding 741 * some empty blocks. 742 */ 743 int _jit_block_is_final(jit_block_t block); 744 745 /* 746 * Free one element in a metadata list. 747 */ 748 void _jit_meta_free_one(void *meta); 749 750 /* 751 * Determine if a NULL pointer check is redundant. The specified 752 * iterator is assumed to be positioned one place beyond the 753 * "check_null" instruction that we are testing. 754 */ 755 int _jit_insn_check_is_redundant(const jit_insn_iter_t *iter); 756 757 /* 758 * Get the correct opcode to use for a "load" instruction, 759 * starting at a particular opcode base. We assume that the 760 * instructions are laid out as "sbyte", "ubyte", "short", 761 * "ushort", "int", "long", "float32", "float64", "nfloat", 762 * and "struct". 763 */ 764 int _jit_load_opcode(int base_opcode, jit_type_t type); 765 766 /* 767 * Get the correct opcode to use for a "store" instruction. 768 * We assume that the instructions are laid out as "byte", 769 * "short", "int", "long", "float32", "float64", "nfloat", 770 * and "struct". 771 */ 772 int _jit_store_opcode(int base_opcode, int small_base, jit_type_t type); 773 774 /* 775 * Function that is called upon each breakpoint location. 776 */ 777 void _jit_debugger_hook(jit_function_t func, jit_nint data1, jit_nint data2); 778 779 /* 780 * Internal structure of a type descriptor. 781 */ 782 struct jit_component 783 { 784 jit_type_t type; 785 jit_nuint offset; 786 char *name; 787 }; 788 struct _jit_type 789 { 790 unsigned int ref_count; 791 int kind : 19; 792 int abi : 8; 793 int is_fixed : 1; 794 int layout_flags : 4; 795 jit_nuint size; 796 jit_nuint alignment; 797 jit_type_t sub_type; 798 unsigned int num_components; 799 struct jit_component components[1]; 800 }; 801 struct jit_tagged_type 802 { 803 struct _jit_type type; 804 void *data; 805 jit_meta_free_func free_func; 806 807 }; 808 809 /* 810 * Pre-defined type descriptors. 811 */ 812 extern struct _jit_type const _jit_type_void_def; 813 extern struct _jit_type const _jit_type_sbyte_def; 814 extern struct _jit_type const _jit_type_ubyte_def; 815 extern struct _jit_type const _jit_type_short_def; 816 extern struct _jit_type const _jit_type_ushort_def; 817 extern struct _jit_type const _jit_type_int_def; 818 extern struct _jit_type const _jit_type_uint_def; 819 extern struct _jit_type const _jit_type_nint_def; 820 extern struct _jit_type const _jit_type_nuint_def; 821 extern struct _jit_type const _jit_type_long_def; 822 extern struct _jit_type const _jit_type_ulong_def; 823 extern struct _jit_type const _jit_type_float32_def; 824 extern struct _jit_type const _jit_type_float64_def; 825 extern struct _jit_type const _jit_type_nfloat_def; 826 extern struct _jit_type const _jit_type_void_ptr_def; 827 828 /* 829 * Intrinsic signatures. 830 * 831 * Naming convention is return type folowed by an underscore and the 832 * argument types. 833 * 834 * jit_int -> i (lower case I) 835 * jit_uint -> I 836 * jit_long -> l (lower case L) 837 * jit_ulong -> L 838 * jit_float32 -> f 839 * jit_float64 -> d 840 * jit_nflloat -> D 841 * 842 * pointer -> p followed by the type 843 * 844 * Special signatures are conv and conv_ovf for type conversions without 845 * and with overflow checks. 846 */ 847 typedef enum 848 { 849 JIT_SIG_NONE = 0, 850 JIT_SIG_i_i = 1, 851 JIT_SIG_i_ii = 2, 852 JIT_SIG_i_piii = 3, 853 JIT_SIG_i_iI = 4, 854 JIT_SIG_i_II = 5, 855 JIT_SIG_I_I = 6, 856 JIT_SIG_I_II = 7, 857 JIT_SIG_i_pIII = 8, 858 JIT_SIG_l_l = 9, 859 JIT_SIG_l_ll = 10, 860 JIT_SIG_i_plll = 11, 861 JIT_SIG_i_l = 12, 862 JIT_SIG_i_ll = 13, 863 JIT_SIG_l_lI = 14, 864 JIT_SIG_L_L = 15, 865 JIT_SIG_L_LL = 16, 866 JIT_SIG_i_pLLL = 17, 867 JIT_SIG_i_LL = 18, 868 JIT_SIG_L_LI = 19, 869 JIT_SIG_f_f = 20, 870 JIT_SIG_f_ff = 21, 871 JIT_SIG_i_f = 22, 872 JIT_SIG_i_ff = 23, 873 JIT_SIG_d_d = 24, 874 JIT_SIG_d_dd = 25, 875 JIT_SIG_i_d = 26, 876 JIT_SIG_i_dd = 27, 877 JIT_SIG_D_D = 28, 878 JIT_SIG_D_DD = 29, 879 JIT_SIG_i_D = 30, 880 JIT_SIG_i_DD = 31, 881 JIT_SIG_conv = 32, 882 JIT_SIG_conv_ovf= 33 883 } _jit_intrinsic_signature; 884 885 /* 886 * Flags for the intrinsic info. 887 */ 888 #define _JIT_INTRINSIC_FLAG_NONE 0x0000 889 #define _JIT_INTRINSIC_FLAG_BRANCH 0x8000 890 #define _JIT_INTRINSIC_FLAG_BRANCH_UNARY 0xC000 891 #define _JIT_INTRINSIC_FLAG_NOT 0x4000 892 #define _JIT_INTRINSIC_FLAG_MASK 0xC000 893 894 /* 895 * Additional intrinsic flags for the unary branches. 896 */ 897 #define _JIT_INTRINSIC_FLAG_IFALSE 0x0000 898 #define _JIT_INTRINSIC_FLAG_ITRUE 0x0001 899 #define _JIT_INTRINSIC_FLAG_LFALSE 0x0002 900 #define _JIT_INTRINSIC_FLAG_LTRUE 0x0003 901 902 /* 903 * Description for the implementation of an opcode by an intrinsic. 904 */ 905 typedef struct _jit_intrinsic_info _jit_intrinsic_info_t; 906 struct _jit_intrinsic_info 907 { 908 int flags; 909 jit_short signature; 910 void *intrinsic; 911 }; 912 913 extern _jit_intrinsic_info_t const _jit_intrinsics[JIT_OP_NUM_OPCODES]; 914 915 /* 916 * Apply an opcode to one or two constant values. 917 * Returns the constant result value on success and NULL otherwise. 918 * NOTE: The type argument MUST be the correct destination type for the 919 * opcode or a tagged type of the correct destination type. 920 */ 921 jit_value_t 922 _jit_opcode_apply_unary(jit_function_t func, jit_uint opcode, jit_value_t value, 923 jit_type_t type); 924 jit_value_t 925 _jit_opcode_apply(jit_function_t func, jit_uint opcode, jit_value_t value1, 926 jit_value_t value2, jit_type_t type); 927 928 /* 929 * Extra call flags for internal use. 930 */ 931 #define JIT_CALL_NATIVE (1 << 14) 932 933 #ifdef JIT_USE_SIGNALS 934 935 /* 936 * Initialize the signal handlers. 937 */ 938 void _jit_signal_init(void); 939 940 #endif 941 942 #ifdef __cplusplus 943 }; 944 #endif 945 946 #endif /* _JIT_INTERNAL_H */