@@ -26,8 +26,8 @@ codeblock_t* cb = NULL;
2626static codeblock_t outline_block ;
2727codeblock_t * ocb = NULL ;
2828
29- // Code for exiting back to the interpreter
30- static void * interp_exit ;
29+ // Code for exiting back to the interpreter from the leave insn
30+ static void * leave_exit_code ;
3131
3232// Print the current source location for debugging purposes
3333RBIMPL_ATTR_MAYBE_UNUSED ()
@@ -115,6 +115,61 @@ jit_peek_at_self(jitstate_t *jit, ctx_t *ctx)
115115
116116static 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 );
117117
118+ #if RUBY_DEBUG
119+
120+ // Increment a profiling counter with counter_name
121+ #define GEN_COUNTER_INC (cb , counter_name ) _gen_counter_inc(cb, &(yjit_runtime_counters . counter_name))
122+ static void
123+ _gen_counter_inc (codeblock_t * cb , int64_t * counter )
124+ {
125+ if (!rb_yjit_opts .gen_stats ) return ;
126+ mov (cb , REG0 , const_ptr_opnd (counter ));
127+ cb_write_lock_prefix (cb ); // for ractors.
128+ add (cb , mem_opnd (64 , REG0 , 0 ), imm_opnd (1 ));
129+ }
130+
131+ // Increment a counter then take an existing side exit.
132+ #define COUNTED_EXIT (side_exit , counter_name ) _counted_side_exit(side_exit, &(yjit_runtime_counters . counter_name))
133+ static uint8_t *
134+ _counted_side_exit (uint8_t * existing_side_exit , int64_t * counter )
135+ {
136+ if (!rb_yjit_opts .gen_stats ) return existing_side_exit ;
137+
138+ uint8_t * start = cb_get_ptr (ocb , ocb -> write_pos );
139+ _gen_counter_inc (ocb , counter );
140+ jmp_ptr (ocb , existing_side_exit );
141+ return start ;
142+ }
143+
144+ // Add a comment at the current position in the code block
145+ static void
146+ _add_comment (codeblock_t * cb , const char * comment_str )
147+ {
148+ // Avoid adding duplicate comment strings (can happen due to deferred codegen)
149+ size_t num_comments = rb_darray_size (yjit_code_comments );
150+ if (num_comments > 0 ) {
151+ struct yjit_comment last_comment = rb_darray_get (yjit_code_comments , num_comments - 1 );
152+ if (last_comment .offset == cb -> write_pos && strcmp (last_comment .comment , comment_str ) == 0 ) {
153+ return ;
154+ }
155+ }
156+
157+ struct yjit_comment new_comment = (struct yjit_comment ){ cb -> write_pos , comment_str };
158+ rb_darray_append (& yjit_code_comments , new_comment );
159+ }
160+
161+ // Comments for generated machine code
162+ #define ADD_COMMENT (cb , comment ) _add_comment((cb), (comment))
163+ yjit_comment_array_t yjit_code_comments ;
164+
165+ #else
166+
167+ #define GEN_COUNTER_INC (cb , counter_name ) ((void)0)
168+ #define COUNTED_EXIT (side_exit , counter_name ) side_exit
169+ #define ADD_COMMENT (cb , comment ) ((void)0)
170+
171+ #endif // if RUBY_DEBUG
172+
118173// Save YJIT registers prior to a C call
119174static void
120175yjit_save_regs (codeblock_t * cb )
@@ -188,87 +243,31 @@ yjit_gen_exit(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb)
188243
189244// Generate an interpreter to REG_CFP->pc.
190245static uint8_t *
191- yjit_gen_context_free_exit (codeblock_t * cb )
246+ yjit_gen_leave_exit (codeblock_t * cb )
192247{
193248 uint8_t * code_ptr = cb_get_ptr (cb , cb -> write_pos );
194249
195250 // Update the CFP on the EC
196- mov (cb , member_opnd (REG_EC , rb_execution_context_t , cfp ), REG_CFP );
251+ //mov(cb, member_opnd(REG_EC, rb_execution_context_t, cfp), REG_CFP);
252+
253+ // Every exit to the interpreter should be counted
254+ GEN_COUNTER_INC (cb , leave_interp_return );
197255
198256 // Put PC into the return register, which the post call bytes dispatches to
199257 mov (cb , RAX , member_opnd (REG_CFP , rb_control_frame_t , pc ));
200258
201259 cb_write_post_call_bytes (cb );
202260
203- // Note, not incrementing stats here since this exit is the natural end to
204- // executing output code.
205-
206261 return code_ptr ;
207262}
208263
209-
210264// A shorthand for generating an exit in the outline block
211265static uint8_t *
212266yjit_side_exit (jitstate_t * jit , ctx_t * ctx )
213267{
214268 return yjit_gen_exit (jit , ctx , ocb );
215269}
216270
217- #if RUBY_DEBUG
218-
219- // Increment a profiling counter with counter_name
220- #define GEN_COUNTER_INC (cb , counter_name ) _gen_counter_inc(cb, &(yjit_runtime_counters . counter_name))
221- static void
222- _gen_counter_inc (codeblock_t * cb , int64_t * counter )
223- {
224- if (!rb_yjit_opts .gen_stats ) return ;
225- mov (cb , REG0 , const_ptr_opnd (counter ));
226- cb_write_lock_prefix (cb ); // for ractors.
227- add (cb , mem_opnd (64 , REG0 , 0 ), imm_opnd (1 ));
228- }
229-
230- // Increment a counter then take an existing side exit.
231- #define COUNTED_EXIT (side_exit , counter_name ) _counted_side_exit(side_exit, &(yjit_runtime_counters . counter_name))
232- static uint8_t *
233- _counted_side_exit (uint8_t * existing_side_exit , int64_t * counter )
234- {
235- if (!rb_yjit_opts .gen_stats ) return existing_side_exit ;
236-
237- uint8_t * start = cb_get_ptr (ocb , ocb -> write_pos );
238- _gen_counter_inc (ocb , counter );
239- jmp_ptr (ocb , existing_side_exit );
240- return start ;
241- }
242-
243- // Add a comment at the current position in the code block
244- static void
245- _add_comment (codeblock_t * cb , const char * comment_str )
246- {
247- // Avoid adding duplicate comment strings (can happen due to deferred codegen)
248- size_t num_comments = rb_darray_size (yjit_code_comments );
249- if (num_comments > 0 ) {
250- struct yjit_comment last_comment = rb_darray_get (yjit_code_comments , num_comments - 1 );
251- if (last_comment .offset == cb -> write_pos && strcmp (last_comment .comment , comment_str ) == 0 ) {
252- return ;
253- }
254- }
255-
256- struct yjit_comment new_comment = (struct yjit_comment ){ cb -> write_pos , comment_str };
257- rb_darray_append (& yjit_code_comments , new_comment );
258- }
259-
260- // Comments for generated machine code
261- #define ADD_COMMENT (cb , comment ) _add_comment((cb), (comment))
262- yjit_comment_array_t yjit_code_comments ;
263-
264- #else
265-
266- #define GEN_COUNTER_INC (cb , counter_name ) ((void)0)
267- #define COUNTED_EXIT (side_exit , counter_name ) side_exit
268- #define ADD_COMMENT (cb , comment ) ((void)0)
269-
270- #endif // if RUBY_DEBUG
271-
272271/*
273272Compile an interpreter entry block to be inserted into an iseq
274273Returns `NULL` if compilation fails.
@@ -295,7 +294,7 @@ yjit_entry_prologue(void)
295294
296295 // Setup cfp->jit_return
297296 // TODO: this could use an IP relative LEA instead of an 8 byte immediate
298- mov (cb , REG0 , const_ptr_opnd (interp_exit ));
297+ mov (cb , REG0 , const_ptr_opnd (leave_exit_code ));
299298 mov (cb , member_opnd (REG_CFP , rb_control_frame_t , jit_return ), REG0 );
300299
301300 return code_ptr ;
@@ -2030,7 +2029,7 @@ gen_leave(jitstate_t* jit, ctx_t* ctx)
20302029 mov (cb , REG_SP , member_opnd (REG_CFP , rb_control_frame_t , sp ));
20312030 mov (cb , mem_opnd (64 , REG_SP , - SIZEOF_VALUE ), REG0 );
20322031
2033- // Jump to the JIT return address in the frame that was popped
2032+ // Jump to the JIT return address on the frame that was just popped
20342033 const int32_t offset_to_jit_return = - ((int32_t )sizeof (rb_control_frame_t )) + (int32_t )offsetof(rb_control_frame_t , jit_return );
20352034 jmp_rm (cb , mem_opnd (64 , REG_CFP , offset_to_jit_return ));
20362035
@@ -2102,8 +2101,8 @@ yjit_init_codegen(void)
21022101 ocb = & outline_block ;
21032102 cb_init (ocb , mem_block + mem_size /2 , mem_size /2 );
21042103
2105- // Generate interp_exit
2106- interp_exit = yjit_gen_context_free_exit (cb );
2104+ // Generate the interpreter exit code for leave
2105+ leave_exit_code = yjit_gen_leave_exit (cb );
21072106
21082107 // Map YARV opcodes to the corresponding codegen functions
21092108 yjit_reg_op (BIN (dup ), gen_dup );
0 commit comments