@@ -27,8 +27,8 @@ codeblock_t* cb = NULL;
27
27
static codeblock_t outline_block ;
28
28
codeblock_t * ocb = NULL ;
29
29
30
- // Code for exiting back to the interpreter
31
- static void * interp_exit ;
30
+ // Code for exiting back to the interpreter from the leave insn
31
+ static void * leave_exit_code ;
32
32
33
33
// Print the current source location for debugging purposes
34
34
RBIMPL_ATTR_MAYBE_UNUSED ()
@@ -116,6 +116,61 @@ jit_peek_at_self(jitstate_t *jit, ctx_t *ctx)
116
116
117
117
static bool jit_guard_known_klass (jitstate_t * jit , ctx_t * ctx , VALUE known_klass , insn_opnd_t insn_opnd , const int max_chain_depth , uint8_t * side_exit );
118
118
119
+ #if RUBY_DEBUG
120
+
121
+ // Increment a profiling counter with counter_name
122
+ #define GEN_COUNTER_INC (cb , counter_name ) _gen_counter_inc(cb, &(yjit_runtime_counters . counter_name))
123
+ static void
124
+ _gen_counter_inc (codeblock_t * cb , int64_t * counter )
125
+ {
126
+ if (!rb_yjit_opts .gen_stats ) return ;
127
+ mov (cb , REG0 , const_ptr_opnd (counter ));
128
+ cb_write_lock_prefix (cb ); // for ractors.
129
+ add (cb , mem_opnd (64 , REG0 , 0 ), imm_opnd (1 ));
130
+ }
131
+
132
+ // Increment a counter then take an existing side exit.
133
+ #define COUNTED_EXIT (side_exit , counter_name ) _counted_side_exit(side_exit, &(yjit_runtime_counters . counter_name))
134
+ static uint8_t *
135
+ _counted_side_exit (uint8_t * existing_side_exit , int64_t * counter )
136
+ {
137
+ if (!rb_yjit_opts .gen_stats ) return existing_side_exit ;
138
+
139
+ uint8_t * start = cb_get_ptr (ocb , ocb -> write_pos );
140
+ _gen_counter_inc (ocb , counter );
141
+ jmp_ptr (ocb , existing_side_exit );
142
+ return start ;
143
+ }
144
+
145
+ // Add a comment at the current position in the code block
146
+ static void
147
+ _add_comment (codeblock_t * cb , const char * comment_str )
148
+ {
149
+ // Avoid adding duplicate comment strings (can happen due to deferred codegen)
150
+ size_t num_comments = rb_darray_size (yjit_code_comments );
151
+ if (num_comments > 0 ) {
152
+ struct yjit_comment last_comment = rb_darray_get (yjit_code_comments , num_comments - 1 );
153
+ if (last_comment .offset == cb -> write_pos && strcmp (last_comment .comment , comment_str ) == 0 ) {
154
+ return ;
155
+ }
156
+ }
157
+
158
+ struct yjit_comment new_comment = (struct yjit_comment ){ cb -> write_pos , comment_str };
159
+ rb_darray_append (& yjit_code_comments , new_comment );
160
+ }
161
+
162
+ // Comments for generated machine code
163
+ #define ADD_COMMENT (cb , comment ) _add_comment((cb), (comment))
164
+ yjit_comment_array_t yjit_code_comments ;
165
+
166
+ #else
167
+
168
+ #define GEN_COUNTER_INC (cb , counter_name ) ((void)0)
169
+ #define COUNTED_EXIT (side_exit , counter_name ) side_exit
170
+ #define ADD_COMMENT (cb , comment ) ((void)0)
171
+
172
+ #endif // if RUBY_DEBUG
173
+
119
174
// Save YJIT registers prior to a C call
120
175
static void
121
176
yjit_save_regs (codeblock_t * cb )
@@ -189,87 +244,31 @@ yjit_gen_exit(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb)
189
244
190
245
// Generate an interpreter to REG_CFP->pc.
191
246
static uint8_t *
192
- yjit_gen_context_free_exit (codeblock_t * cb )
247
+ yjit_gen_leave_exit (codeblock_t * cb )
193
248
{
194
249
uint8_t * code_ptr = cb_get_ptr (cb , cb -> write_pos );
195
250
196
251
// Update the CFP on the EC
197
- mov (cb , member_opnd (REG_EC , rb_execution_context_t , cfp ), REG_CFP );
252
+ //mov(cb, member_opnd(REG_EC, rb_execution_context_t, cfp), REG_CFP);
253
+
254
+ // Every exit to the interpreter should be counted
255
+ GEN_COUNTER_INC (cb , leave_interp_return );
198
256
199
257
// Put PC into the return register, which the post call bytes dispatches to
200
258
mov (cb , RAX , member_opnd (REG_CFP , rb_control_frame_t , pc ));
201
259
202
260
cb_write_post_call_bytes (cb );
203
261
204
- // Note, not incrementing stats here since this exit is the natural end to
205
- // executing output code.
206
-
207
262
return code_ptr ;
208
263
}
209
264
210
-
211
265
// A shorthand for generating an exit in the outline block
212
266
static uint8_t *
213
267
yjit_side_exit (jitstate_t * jit , ctx_t * ctx )
214
268
{
215
269
return yjit_gen_exit (jit , ctx , ocb );
216
270
}
217
271
218
- #if RUBY_DEBUG
219
-
220
- // Increment a profiling counter with counter_name
221
- #define GEN_COUNTER_INC (cb , counter_name ) _gen_counter_inc(cb, &(yjit_runtime_counters . counter_name))
222
- static void
223
- _gen_counter_inc (codeblock_t * cb , int64_t * counter )
224
- {
225
- if (!rb_yjit_opts .gen_stats ) return ;
226
- mov (cb , REG0 , const_ptr_opnd (counter ));
227
- cb_write_lock_prefix (cb ); // for ractors.
228
- add (cb , mem_opnd (64 , REG0 , 0 ), imm_opnd (1 ));
229
- }
230
-
231
- // Increment a counter then take an existing side exit.
232
- #define COUNTED_EXIT (side_exit , counter_name ) _counted_side_exit(side_exit, &(yjit_runtime_counters . counter_name))
233
- static uint8_t *
234
- _counted_side_exit (uint8_t * existing_side_exit , int64_t * counter )
235
- {
236
- if (!rb_yjit_opts .gen_stats ) return existing_side_exit ;
237
-
238
- uint8_t * start = cb_get_ptr (ocb , ocb -> write_pos );
239
- _gen_counter_inc (ocb , counter );
240
- jmp_ptr (ocb , existing_side_exit );
241
- return start ;
242
- }
243
-
244
- // Add a comment at the current position in the code block
245
- static void
246
- _add_comment (codeblock_t * cb , const char * comment_str )
247
- {
248
- // Avoid adding duplicate comment strings (can happen due to deferred codegen)
249
- size_t num_comments = rb_darray_size (yjit_code_comments );
250
- if (num_comments > 0 ) {
251
- struct yjit_comment last_comment = rb_darray_get (yjit_code_comments , num_comments - 1 );
252
- if (last_comment .offset == cb -> write_pos && strcmp (last_comment .comment , comment_str ) == 0 ) {
253
- return ;
254
- }
255
- }
256
-
257
- struct yjit_comment new_comment = (struct yjit_comment ){ cb -> write_pos , comment_str };
258
- rb_darray_append (& yjit_code_comments , new_comment );
259
- }
260
-
261
- // Comments for generated machine code
262
- #define ADD_COMMENT (cb , comment ) _add_comment((cb), (comment))
263
- yjit_comment_array_t yjit_code_comments ;
264
-
265
- #else
266
-
267
- #define GEN_COUNTER_INC (cb , counter_name ) ((void)0)
268
- #define COUNTED_EXIT (side_exit , counter_name ) side_exit
269
- #define ADD_COMMENT (cb , comment ) ((void)0)
270
-
271
- #endif // if RUBY_DEBUG
272
-
273
272
/*
274
273
Compile an interpreter entry block to be inserted into an iseq
275
274
Returns `NULL` if compilation fails.
@@ -296,7 +295,7 @@ yjit_entry_prologue(void)
296
295
297
296
// Setup cfp->jit_return
298
297
// TODO: this could use an IP relative LEA instead of an 8 byte immediate
299
- mov (cb , REG0 , const_ptr_opnd (interp_exit ));
298
+ mov (cb , REG0 , const_ptr_opnd (leave_exit_code ));
300
299
mov (cb , member_opnd (REG_CFP , rb_control_frame_t , jit_return ), REG0 );
301
300
302
301
return code_ptr ;
@@ -2101,7 +2100,7 @@ gen_leave(jitstate_t* jit, ctx_t* ctx)
2101
2100
mov (cb , REG_SP , member_opnd (REG_CFP , rb_control_frame_t , sp ));
2102
2101
mov (cb , mem_opnd (64 , REG_SP , - SIZEOF_VALUE ), REG0 );
2103
2102
2104
- // Jump to the JIT return address in the frame that was popped
2103
+ // Jump to the JIT return address on the frame that was just popped
2105
2104
const int32_t offset_to_jit_return = - ((int32_t )sizeof (rb_control_frame_t )) + (int32_t )offsetof(rb_control_frame_t , jit_return );
2106
2105
jmp_rm (cb , mem_opnd (64 , REG_CFP , offset_to_jit_return ));
2107
2106
@@ -2173,8 +2172,8 @@ yjit_init_codegen(void)
2173
2172
ocb = & outline_block ;
2174
2173
cb_init (ocb , mem_block + mem_size /2 , mem_size /2 );
2175
2174
2176
- // Generate interp_exit
2177
- interp_exit = yjit_gen_context_free_exit (cb );
2175
+ // Generate the interpreter exit code for leave
2176
+ leave_exit_code = yjit_gen_leave_exit (cb );
2178
2177
2179
2178
// Map YARV opcodes to the corresponding codegen functions
2180
2179
yjit_reg_op (BIN (dup ), gen_dup );
0 commit comments