Ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e0ba6b95ab71a441357ed5484e33498)
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
32static codeblock_t block;
33static codeblock_t *cb = NULL;
34
35// Code block into which we write out-of-line machine code
36static codeblock_t outline_block;
37static codeblock_t *ocb = NULL;
38
39#if YJIT_STATS
40// Comments for generated code
41struct yjit_comment {
42 uint32_t offset;
43 const char *comment;
44};
45
46typedef rb_darray(struct yjit_comment) yjit_comment_array_t;
47static 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}; \
53static char yjit_counter_names[] = #__VA_ARGS__;
54
55YJIT_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
145static 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.
154static 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
167void Init_builtin_yjit(void) {}
168bool rb_yjit_enabled_p(void) { return false; }
169unsigned rb_yjit_call_threshold(void) { return UINT_MAX; }
170void rb_yjit_invalidate_all_method_lookup_assumptions(void) {};
171void rb_yjit_method_lookup_change(VALUE klass, ID mid) {};
172void rb_yjit_cme_invalidate(VALUE cme) {}
173void rb_yjit_collect_vm_usage_insn(int insn) {}
174void rb_yjit_collect_binding_alloc(void) {}
175void rb_yjit_collect_binding_set(void) {}
176bool rb_yjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec) { return false; }
177void rb_yjit_init(struct rb_yjit_options *options) {}
178void rb_yjit_bop_redefined(VALUE klass, const rb_method_entry_t *me, enum ruby_basic_operators bop) {}
179void rb_yjit_constant_state_changed(void) {}
180void rb_yjit_iseq_mark(const struct rb_iseq_constant_body *body) {}
181void rb_yjit_iseq_update_references(const struct rb_iseq_constant_body *body) {}
182void rb_yjit_iseq_free(const struct rb_iseq_constant_body *body) {}
183void rb_yjit_before_ractor_spawn(void) {}
184void rb_yjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic) {}
185void rb_yjit_tracing_invalidate_all(void) {}
186
187#endif // if JIT_ENABLED && YJIT_SUPPORTED_P
Defines RBIMPL_HAS_BUILTIN.