Ruby  3.1.4p223 (2023-03-30 revision HEAD)
yjit.c
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.
4 #include "internal.h"
5 #include "vm_core.h"
6 #include "vm_callinfo.h"
7 #include "builtin.h"
8 #include "insns.inc"
9 #include "insns_info.inc"
10 #include "vm_sync.h"
11 #include "yjit.h"
12 
13 #ifndef YJIT_CHECK_MODE
14 # define YJIT_CHECK_MODE 0
15 #endif
16 
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
21 #endif
22 
23 // USE_MJIT comes from configure options
24 #define JIT_ENABLED USE_MJIT
25 
26 // Check if we need to include YJIT in the build
27 #if JIT_ENABLED && YJIT_SUPPORTED_P
28 
29 #include "yjit_asm.c"
30 
31 // Code block into which we write machine code
32 static codeblock_t block;
33 static codeblock_t *cb = NULL;
34 
35 // Code block into which we write out-of-line machine code
36 static codeblock_t outline_block;
37 static codeblock_t *ocb = NULL;
38 
39 #if YJIT_STATS
40 // Comments for generated code
41 struct yjit_comment {
42  uint32_t offset;
43  const char *comment;
44 };
45 
46 typedef rb_darray(struct yjit_comment) yjit_comment_array_t;
47 static yjit_comment_array_t yjit_code_comments;
48 
49 // Counters for generated code
50 #define YJIT_DECLARE_COUNTERS(...) struct rb_yjit_runtime_counters { \
51  int64_t __VA_ARGS__; \
52 }; \
53 static char yjit_counter_names[] = #__VA_ARGS__;
54 
55 YJIT_DECLARE_COUNTERS(
56  exec_instruction,
57 
58  send_keywords,
59  send_kw_splat,
60  send_args_splat,
61  send_block_arg,
62  send_ivar_set_method,
63  send_zsuper_method,
64  send_undef_method,
65  send_optimized_method,
66  send_optimized_method_send,
67  send_optimized_method_call,
68  send_optimized_method_block_call,
69  send_missing_method,
70  send_bmethod,
71  send_refined_method,
72  send_cfunc_ruby_array_varg,
73  send_cfunc_argc_mismatch,
74  send_cfunc_toomany_args,
75  send_cfunc_tracing,
76  send_cfunc_kwargs,
77  send_attrset_kwargs,
78  send_iseq_tailcall,
79  send_iseq_arity_error,
80  send_iseq_only_keywords,
81  send_iseq_kwargs_req_and_opt_missing,
82  send_iseq_kwargs_mismatch,
83  send_iseq_complex_callee,
84  send_not_implemented_method,
85  send_getter_arity,
86  send_se_cf_overflow,
87  send_se_protected_check_failed,
88 
89  traced_cfunc_return,
90 
91  invokesuper_me_changed,
92  invokesuper_block,
93 
94  leave_se_interrupt,
95  leave_interp_return,
96  leave_start_pc_non_zero,
97 
98  getivar_se_self_not_heap,
99  getivar_idx_out_of_range,
100  getivar_megamorphic,
101 
102  setivar_se_self_not_heap,
103  setivar_idx_out_of_range,
104  setivar_val_heapobject,
105  setivar_name_not_mapped,
106  setivar_not_object,
107  setivar_frozen,
108 
109  oaref_argc_not_one,
110  oaref_arg_not_fixnum,
111 
112  opt_getinlinecache_miss,
113 
114  binding_allocations,
115  binding_set,
116 
117  vm_insns_count,
118  compiled_iseq_count,
119  compiled_block_count,
120  compilation_failure,
121 
122  exit_from_branch_stub,
123 
124  invalidation_count,
125  invalidate_method_lookup,
126  invalidate_bop_redefined,
127  invalidate_ractor_spawn,
128  invalidate_constant_state_bump,
129  invalidate_constant_ic_fill,
130 
131  constant_state_bumps,
132 
133  expandarray_splat,
134  expandarray_postarg,
135  expandarray_not_array,
136  expandarray_rhs_too_small,
137 
138  gbpp_block_param_modified,
139  gbpp_block_handler_not_iseq,
140 
141  // Member with known name for iterating over counters
142  last_member
143 )
144 
145 static struct rb_yjit_runtime_counters yjit_runtime_counters = { 0 };
146 #undef YJIT_DECLARE_COUNTERS
147 
148 #endif // YJIT_STATS
149 
150 // The number of bytes counting from the beginning of the inline code block
151 // that should not be changed. After patching for global invalidation, no one
152 // should make changes to the invalidated code region anymore. This is used to
153 // break out of invalidation race when there are multiple ractors.
154 static uint32_t yjit_codepage_frozen_bytes = 0;
155 
156 #include "yjit_utils.c"
157 #include "yjit_core.c"
158 #include "yjit_iface.c"
159 #include "yjit_codegen.c"
160 
161 #else
162 // !JIT_ENABLED || !YJIT_SUPPORTED_P
163 // In these builds, YJIT could never be turned on. Provide dummy
164 // implementations for YJIT functions exposed to the rest of the code base.
165 // See yjit.h.
166 
167 void Init_builtin_yjit(void) {}
168 bool rb_yjit_enabled_p(void) { return false; }
169 unsigned rb_yjit_call_threshold(void) { return UINT_MAX; }
170 void rb_yjit_invalidate_all_method_lookup_assumptions(void) {};
171 void rb_yjit_method_lookup_change(VALUE klass, ID mid) {};
172 void rb_yjit_cme_invalidate(VALUE cme) {}
173 void rb_yjit_collect_vm_usage_insn(int insn) {}
174 void rb_yjit_collect_binding_alloc(void) {}
175 void rb_yjit_collect_binding_set(void) {}
176 bool rb_yjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec) { return false; }
177 void rb_yjit_init(struct rb_yjit_options *options) {}
178 void rb_yjit_bop_redefined(VALUE klass, const rb_method_entry_t *me, enum ruby_basic_operators bop) {}
179 void rb_yjit_constant_state_changed(void) {}
180 void rb_yjit_iseq_mark(const struct rb_iseq_constant_body *body) {}
181 void rb_yjit_iseq_update_references(const struct rb_iseq_constant_body *body) {}
182 void rb_yjit_iseq_free(const struct rb_iseq_constant_body *body) {}
183 void rb_yjit_before_ractor_spawn(void) {}
184 void rb_yjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic) {}
185 void rb_yjit_tracing_invalidate_all(void) {}
186 
187 #endif // if JIT_ENABLED && YJIT_SUPPORTED_P
Defines RBIMPL_HAS_BUILTIN.
Definition: method.h:54
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition: value.h:52
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40