summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <[email protected]>2021-04-22 11:55:30 -0400
committerAlan Wu <[email protected]>2021-10-20 18:19:34 -0400
commit3e80104024b8663ab99d2571f2cf1cdf054a89f6 (patch)
treeccdcb17416cc7e44e5f7af2c6ce6bf189be061b4
parent8106a95efb19fa0a11e2cc7ecc4889b216239896 (diff)
Aesthetic changes and add missing counter
-rw-r--r--yjit_codegen.c133
1 files changed, 66 insertions, 67 deletions
diff --git a/yjit_codegen.c b/yjit_codegen.c
index b1fa38813a..c043d53e9f 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -27,8 +27,8 @@ codeblock_t* cb = NULL;
static codeblock_t outline_block;
codeblock_t* ocb = NULL;
-// Code for exiting back to the interpreter
-static void *interp_exit;
+// Code for exiting back to the interpreter from the leave insn
+static void *leave_exit_code;
// Print the current source location for debugging purposes
RBIMPL_ATTR_MAYBE_UNUSED()
@@ -116,6 +116,61 @@ jit_peek_at_self(jitstate_t *jit, ctx_t *ctx)
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);
+#if RUBY_DEBUG
+
+// Increment a profiling counter with counter_name
+#define GEN_COUNTER_INC(cb, counter_name) _gen_counter_inc(cb, &(yjit_runtime_counters . counter_name))
+static void
+_gen_counter_inc(codeblock_t *cb, int64_t *counter)
+{
+ if (!rb_yjit_opts.gen_stats) return;
+ mov(cb, REG0, const_ptr_opnd(counter));
+ cb_write_lock_prefix(cb); // for ractors.
+ add(cb, mem_opnd(64, REG0, 0), imm_opnd(1));
+}
+
+// Increment a counter then take an existing side exit.
+#define COUNTED_EXIT(side_exit, counter_name) _counted_side_exit(side_exit, &(yjit_runtime_counters . counter_name))
+static uint8_t *
+_counted_side_exit(uint8_t *existing_side_exit, int64_t *counter)
+{
+ if (!rb_yjit_opts.gen_stats) return existing_side_exit;
+
+ uint8_t *start = cb_get_ptr(ocb, ocb->write_pos);
+ _gen_counter_inc(ocb, counter);
+ jmp_ptr(ocb, existing_side_exit);
+ return start;
+}
+
+// Add a comment at the current position in the code block
+static void
+_add_comment(codeblock_t* cb, const char* comment_str)
+{
+ // Avoid adding duplicate comment strings (can happen due to deferred codegen)
+ size_t num_comments = rb_darray_size(yjit_code_comments);
+ if (num_comments > 0) {
+ struct yjit_comment last_comment = rb_darray_get(yjit_code_comments, num_comments - 1);
+ if (last_comment.offset == cb->write_pos && strcmp(last_comment.comment, comment_str) == 0) {
+ return;
+ }
+ }
+
+ struct yjit_comment new_comment = (struct yjit_comment){ cb->write_pos, comment_str };
+ rb_darray_append(&yjit_code_comments, new_comment);
+}
+
+// Comments for generated machine code
+#define ADD_COMMENT(cb, comment) _add_comment((cb), (comment))
+yjit_comment_array_t yjit_code_comments;
+
+#else
+
+#define GEN_COUNTER_INC(cb, counter_name) ((void)0)
+#define COUNTED_EXIT(side_exit, counter_name) side_exit
+#define ADD_COMMENT(cb, comment) ((void)0)
+
+#endif // if RUBY_DEBUG
+
// Save YJIT registers prior to a C call
static void
yjit_save_regs(codeblock_t* cb)
@@ -189,25 +244,24 @@ yjit_gen_exit(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb)
// Generate an interpreter to REG_CFP->pc.
static uint8_t *
-yjit_gen_context_free_exit(codeblock_t *cb)
+yjit_gen_leave_exit(codeblock_t *cb)
{
uint8_t *code_ptr = cb_get_ptr(cb, cb->write_pos);
// Update the CFP on the EC
- mov(cb, member_opnd(REG_EC, rb_execution_context_t, cfp), REG_CFP);
+ //mov(cb, member_opnd(REG_EC, rb_execution_context_t, cfp), REG_CFP);
+
+ // Every exit to the interpreter should be counted
+ GEN_COUNTER_INC(cb, leave_interp_return);
// Put PC into the return register, which the post call bytes dispatches to
mov(cb, RAX, member_opnd(REG_CFP, rb_control_frame_t, pc));
cb_write_post_call_bytes(cb);
- // Note, not incrementing stats here since this exit is the natural end to
- // executing output code.
-
return code_ptr;
}
-
// A shorthand for generating an exit in the outline block
static uint8_t *
yjit_side_exit(jitstate_t *jit, ctx_t *ctx)
@@ -215,61 +269,6 @@ yjit_side_exit(jitstate_t *jit, ctx_t *ctx)
return yjit_gen_exit(jit, ctx, ocb);
}
-#if RUBY_DEBUG
-
-// Increment a profiling counter with counter_name
-#define GEN_COUNTER_INC(cb, counter_name) _gen_counter_inc(cb, &(yjit_runtime_counters . counter_name))
-static void
-_gen_counter_inc(codeblock_t *cb, int64_t *counter)
-{
- if (!rb_yjit_opts.gen_stats) return;
- mov(cb, REG0, const_ptr_opnd(counter));
- cb_write_lock_prefix(cb); // for ractors.
- add(cb, mem_opnd(64, REG0, 0), imm_opnd(1));
-}
-
-// Increment a counter then take an existing side exit.
-#define COUNTED_EXIT(side_exit, counter_name) _counted_side_exit(side_exit, &(yjit_runtime_counters . counter_name))
-static uint8_t *
-_counted_side_exit(uint8_t *existing_side_exit, int64_t *counter)
-{
- if (!rb_yjit_opts.gen_stats) return existing_side_exit;
-
- uint8_t *start = cb_get_ptr(ocb, ocb->write_pos);
- _gen_counter_inc(ocb, counter);
- jmp_ptr(ocb, existing_side_exit);
- return start;
-}
-
-// Add a comment at the current position in the code block
-static void
-_add_comment(codeblock_t* cb, const char* comment_str)
-{
- // Avoid adding duplicate comment strings (can happen due to deferred codegen)
- size_t num_comments = rb_darray_size(yjit_code_comments);
- if (num_comments > 0) {
- struct yjit_comment last_comment = rb_darray_get(yjit_code_comments, num_comments - 1);
- if (last_comment.offset == cb->write_pos && strcmp(last_comment.comment, comment_str) == 0) {
- return;
- }
- }
-
- struct yjit_comment new_comment = (struct yjit_comment){ cb->write_pos, comment_str };
- rb_darray_append(&yjit_code_comments, new_comment);
-}
-
-// Comments for generated machine code
-#define ADD_COMMENT(cb, comment) _add_comment((cb), (comment))
-yjit_comment_array_t yjit_code_comments;
-
-#else
-
-#define GEN_COUNTER_INC(cb, counter_name) ((void)0)
-#define COUNTED_EXIT(side_exit, counter_name) side_exit
-#define ADD_COMMENT(cb, comment) ((void)0)
-
-#endif // if RUBY_DEBUG
-
/*
Compile an interpreter entry block to be inserted into an iseq
Returns `NULL` if compilation fails.
@@ -296,7 +295,7 @@ yjit_entry_prologue(void)
// Setup cfp->jit_return
// TODO: this could use an IP relative LEA instead of an 8 byte immediate
- mov(cb, REG0, const_ptr_opnd(interp_exit));
+ mov(cb, REG0, const_ptr_opnd(leave_exit_code));
mov(cb, member_opnd(REG_CFP, rb_control_frame_t, jit_return), REG0);
return code_ptr;
@@ -2101,7 +2100,7 @@ gen_leave(jitstate_t* jit, ctx_t* ctx)
mov(cb, REG_SP, member_opnd(REG_CFP, rb_control_frame_t, sp));
mov(cb, mem_opnd(64, REG_SP, -SIZEOF_VALUE), REG0);
- // Jump to the JIT return address in the frame that was popped
+ // Jump to the JIT return address on the frame that was just popped
const int32_t offset_to_jit_return = -((int32_t)sizeof(rb_control_frame_t)) + (int32_t)offsetof(rb_control_frame_t, jit_return);
jmp_rm(cb, mem_opnd(64, REG_CFP, offset_to_jit_return));
@@ -2173,8 +2172,8 @@ yjit_init_codegen(void)
ocb = &outline_block;
cb_init(ocb, mem_block + mem_size/2, mem_size/2);
- // Generate interp_exit
- interp_exit = yjit_gen_context_free_exit(cb);
+ // Generate the interpreter exit code for leave
+ leave_exit_code = yjit_gen_leave_exit(cb);
// Map YARV opcodes to the corresponding codegen functions
yjit_reg_op(BIN(dup), gen_dup);