1 // YJIT combined compilation unit. This setup allows spreading functions
2 // across different files without having to worry about putting things
3 // in headers and prefixing function names.
6 #include "vm_callinfo.h"
9 #include "insns_info.inc"
13 #ifndef YJIT_CHECK_MODE
14 # define YJIT_CHECK_MODE 0
17 // >= 1: print when output code invalidation happens
18 // >= 2: dump list of instructions when regions compile
19 #ifndef YJIT_DUMP_MODE
20 # define YJIT_DUMP_MODE 0
23 // USE_MJIT comes from configure options
24 #define JIT_ENABLED USE_MJIT
26 // Check if we need to include YJIT in the build
27 #if JIT_ENABLED && YJIT_SUPPORTED_P
31 // Code block into which we write machine code
32 static codeblock_t block
;
33 static codeblock_t
*cb
= NULL
;
35 // Code block into which we write out-of-line machine code
36 static codeblock_t outline_block
;
37 static codeblock_t
*ocb
= NULL
;
40 // Comments for generated code
46 typedef rb_darray(struct yjit_comment
) yjit_comment_array_t
;
47 static yjit_comment_array_t yjit_code_comments
;
49 // Counters for generated code
50 #define YJIT_DECLARE_COUNTERS(...) struct rb_yjit_runtime_counters { \
51 int64_t __VA_ARGS__; \
53 static char yjit_counter_names[] = #__VA_ARGS__;
55 YJIT_DECLARE_COUNTERS(
65 send_optimized_method
,
66 send_optimized_method_send
,
67 send_optimized_method_call
,
68 send_optimized_method_block_call
,
72 send_cfunc_argc_mismatch
,
73 send_cfunc_toomany_args
,
78 send_iseq_arity_error
,
79 send_iseq_only_keywords
,
80 send_iseq_kwargs_req_and_opt_missing
,
81 send_iseq_kwargs_mismatch
,
82 send_iseq_complex_callee
,
83 send_not_implemented_method
,
86 send_se_protected_check_failed
,
90 invokesuper_me_changed
,
95 leave_start_pc_non_zero
,
97 getivar_se_self_not_heap
,
98 getivar_idx_out_of_range
,
101 setivar_se_self_not_heap
,
102 setivar_idx_out_of_range
,
103 setivar_val_heapobject
,
104 setivar_name_not_mapped
,
109 oaref_arg_not_fixnum
,
111 opt_getinlinecache_miss
,
118 compiled_block_count
,
121 exit_from_branch_stub
,
124 invalidate_method_lookup
,
125 invalidate_bop_redefined
,
126 invalidate_ractor_spawn
,
127 invalidate_constant_state_bump
,
128 invalidate_constant_ic_fill
,
130 constant_state_bumps
,
134 expandarray_not_array
,
135 expandarray_rhs_too_small
,
137 gbpp_block_param_modified
,
138 gbpp_block_handler_not_iseq
,
140 // Member with known name for iterating over counters
144 static struct rb_yjit_runtime_counters yjit_runtime_counters
= { 0 };
145 #undef YJIT_DECLARE_COUNTERS
149 // The number of bytes counting from the beginning of the inline code block
150 // that should not be changed. After patching for global invalidation, no one
151 // should make changes to the invalidated code region anymore. This is used to
152 // break out of invalidation race when there are multiple ractors.
153 static uint32_t yjit_codepage_frozen_bytes
= 0;
155 #include "yjit_utils.c"
156 #include "yjit_core.c"
157 #include "yjit_iface.c"
158 #include "yjit_codegen.c"
161 // !JIT_ENABLED || !YJIT_SUPPORTED_P
162 // In these builds, YJIT could never be turned on. Provide dummy
163 // implementations for YJIT functions exposed to the rest of the code base.
166 void Init_builtin_yjit(void) {}
167 bool rb_yjit_enabled_p(void) { return false; }
168 unsigned rb_yjit_call_threshold(void) { return UINT_MAX
; }
169 void rb_yjit_invalidate_all_method_lookup_assumptions(void) {};
170 void rb_yjit_method_lookup_change(VALUE klass
, ID mid
) {};
171 void rb_yjit_cme_invalidate(VALUE cme
) {}
172 void rb_yjit_collect_vm_usage_insn(int insn
) {}
173 void rb_yjit_collect_binding_alloc(void) {}
174 void rb_yjit_collect_binding_set(void) {}
175 bool rb_yjit_compile_iseq(const rb_iseq_t
*iseq
, rb_execution_context_t
*ec
) { return false; }
176 void rb_yjit_init(struct rb_yjit_options
*options
) {}
177 void rb_yjit_bop_redefined(VALUE klass
, const rb_method_entry_t
*me
, enum ruby_basic_operators bop
) {}
178 void rb_yjit_constant_state_changed(void) {}
179 void rb_yjit_iseq_mark(const struct rb_iseq_constant_body
*body
) {}
180 void rb_yjit_iseq_update_references(const struct rb_iseq_constant_body
*body
) {}
181 void rb_yjit_iseq_free(const struct rb_iseq_constant_body
*body
) {}
182 void rb_yjit_before_ractor_spawn(void) {}
183 void rb_yjit_constant_ic_update(const rb_iseq_t
*const iseq
, IC ic
) {}
184 void rb_yjit_tracing_invalidate_all(void) {}
186 #endif // if JIT_ENABLED && YJIT_SUPPORTED_P