summaryrefslogtreecommitdiff
path: root/yjit_codegen.c
diff options
context:
space:
mode:
authorAlan Wu <[email protected]>2021-09-24 18:03:10 -0400
committerAlan Wu <[email protected]>2021-10-20 18:19:41 -0400
commit1a5109cb5f8945f52f90ee420cde669f117b90c4 (patch)
treeff09ac4ecb2f1e37fda2915255cdc672aa5474f6 /yjit_codegen.c
parenta09adac2d76342fd4a0d97905b3397758689c817 (diff)
Comment edits and moving functions around in the file
Diffstat (limited to 'yjit_codegen.c')
-rw-r--r--yjit_codegen.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/yjit_codegen.c b/yjit_codegen.c
index 0669bdee91..c284fc2551 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -2954,10 +2954,32 @@ jit_protected_callee_ancestry_guard(jitstate_t *jit, codeblock_t *cb, const rb_c
}
// Return true when the codegen function generates code.
-// known_recv_klass is non-NULL when the caller has used jit_guard_known_klass
-// See yjit_reg_method.
+// known_recv_klass is non-NULL when the caller has used jit_guard_known_klass().
+// See yjit_reg_method().
typedef bool (*method_codegen_t)(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const rb_callable_method_entry_t *cme, rb_iseq_t *block, const int32_t argc, VALUE *known_recv_klass);
+// Register a specialized codegen function for a particular method. Note that
+// the if the function returns true, the code it generates runs without a
+// control frame and without interrupt checks. To avoid creating observable
+// behavior changes, the codegen function should only target simple code paths
+// that do not allocate and do not make method calls.
+static void
+yjit_reg_method(VALUE klass, const char *mid_str, method_codegen_t gen_fn)
+{
+ ID mid = rb_intern(mid_str);
+ const rb_method_entry_t *me = rb_method_entry_at(klass, mid);
+
+ if (!me) {
+ rb_bug("undefined optimized method: %s", rb_id2name(mid));
+ }
+
+ // For now, only cfuncs are supported
+ RUBY_ASSERT(me && me->def);
+ RUBY_ASSERT(me->def->type == VM_METHOD_TYPE_CFUNC);
+
+ st_insert(yjit_method_codegen_table, (st_data_t)me->def->method_serial, (st_data_t)gen_fn);
+}
+
// Codegen for rb_obj_not().
// Note, caller is responsible for generating all the right guards, including
// arity guards.
@@ -3031,9 +3053,9 @@ jit_rb_obj_equal(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, cons
}
// Codegen for rb_str_to_s()
-// When String#to_s is called on a String instance, the method returns self and most
-// of the overhead comes from setting up the method call. We observed that this situation
-// happens a lot in some workloads.
+// When String#to_s is called on a String instance, the method returns self and
+// most of the overhead comes from setting up the method call. We observed that
+// this situation happens a lot in some workloads.
static bool
jit_rb_str_to_s(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const rb_callable_method_entry_t *cme, rb_iseq_t *block, const int32_t argc, VALUE *recv_known_klass)
{
@@ -4363,23 +4385,6 @@ invalidate_all_blocks_for_tracing(const rb_iseq_t *iseq)
}
static void
-yjit_reg_method(VALUE klass, const char *mid_str, method_codegen_t gen_fn)
-{
- ID mid = rb_intern(mid_str);
- const rb_method_entry_t *me = rb_method_entry_at(klass, mid);
-
- if (!me) {
- rb_bug("undefined optimized method: %s", rb_id2name(mid));
- }
-
- // For now, only cfuncs are supported
- VM_ASSERT(me && me->def);
- VM_ASSERT(me->def->type == VM_METHOD_TYPE_CFUNC);
-
- st_insert(yjit_method_codegen_table, (st_data_t)me->def->method_serial, (st_data_t)gen_fn);
-}
-
-static void
yjit_reg_op(int opcode, codegen_fn gen_fn)
{
RUBY_ASSERT(opcode >= 0 && opcode < VM_INSTRUCTION_SIZE);
@@ -4487,6 +4492,7 @@ yjit_init_codegen(void)
yjit_method_codegen_table = st_init_numtable();
+ // Specialization for C methods. See yjit_reg_method() for details.
yjit_reg_method(rb_cBasicObject, "!", jit_rb_obj_not);
yjit_reg_method(rb_cNilClass, "nil?", jit_rb_true);