Skip to content

Commit 572eb16

Browse files
authored
Merge pull request ruby#92 from jhawthorn/optimized_method_st_lookup
Use an st_table for optimized method codegen
2 parents 0f09623 + 7e7a016 commit 572eb16

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

yjit_codegen.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
// Map from YARV opcodes to code generation functions
2020
static codegen_fn gen_fns[VM_INSTRUCTION_SIZE] = { NULL };
2121

22+
// Map from method entries to code generation functions
23+
static st_table *yjit_method_codegen_table = NULL;
24+
2225
// Code block into which we write machine code
2326
static codeblock_t block;
2427
codeblock_t* cb = NULL;
@@ -2270,7 +2273,7 @@ jit_protected_callee_ancestry_guard(jitstate_t *jit, codeblock_t *cb, const rb_c
22702273
}
22712274

22722275
// Return true when the codegen function generates code.
2273-
typedef bool (*cfunc_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);
2276+
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);
22742277

22752278
// Codegen for rb_obj_not().
22762279
// Note, caller is responsible for generating all the right guards, including
@@ -2302,11 +2305,12 @@ jit_rb_obj_not(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const
23022305
}
23032306

23042307
// Check if we know how to codegen for a particular cfunc method
2305-
static cfunc_codegen_t
2306-
lookup_cfunc_codegen(const rb_method_cfunc_t *cfunc)
2308+
static method_codegen_t
2309+
lookup_cfunc_codegen(const rb_method_definition_t *def)
23072310
{
2308-
if (cfunc->func == rb_obj_not) {
2309-
return jit_rb_obj_not;
2311+
method_codegen_t gen_fn;
2312+
if (st_lookup(yjit_method_codegen_table, def->method_serial, (st_data_t *)&gen_fn)) {
2313+
return gen_fn;
23102314
}
23112315
return NULL;
23122316
}
@@ -2336,8 +2340,8 @@ gen_send_cfunc(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const
23362340

23372341
// Delegate to codegen for C methods if we have it.
23382342
{
2339-
cfunc_codegen_t known_cfunc_codegen;
2340-
if ((known_cfunc_codegen = lookup_cfunc_codegen(cfunc))) {
2343+
method_codegen_t known_cfunc_codegen;
2344+
if ((known_cfunc_codegen = lookup_cfunc_codegen(cme->def))) {
23412345
if (known_cfunc_codegen(jit, ctx, ci, cme, block, argc)) {
23422346
// cfunc codegen generated code. Terminate the block so
23432347
// there isn't multiple calls in the same block.
@@ -3280,6 +3284,23 @@ gen_opt_invokebuiltin_delegate(jitstate_t *jit, ctx_t *ctx)
32803284
return YJIT_KEEP_COMPILING;
32813285
}
32823286

3287+
static void
3288+
yjit_reg_method(VALUE klass, const char *mid_str, method_codegen_t gen_fn)
3289+
{
3290+
ID mid = rb_intern(mid_str);
3291+
const rb_method_entry_t *me = rb_method_entry_at(klass, mid);
3292+
3293+
if (!me) {
3294+
rb_bug("undefined optimized method: %s", rb_id2name(mid));
3295+
}
3296+
3297+
// For now, only cfuncs are supported
3298+
VM_ASSERT(me && me->def);
3299+
VM_ASSERT(me->def->type == VM_METHOD_TYPE_CFUNC);
3300+
3301+
st_insert(yjit_method_codegen_table, (st_data_t)me->def->method_serial, (st_data_t)gen_fn);
3302+
}
3303+
32833304
static void
32843305
yjit_reg_op(int opcode, codegen_fn gen_fn)
32853306
{
@@ -3360,4 +3381,8 @@ yjit_init_codegen(void)
33603381
yjit_reg_op(BIN(opt_send_without_block), gen_opt_send_without_block);
33613382
yjit_reg_op(BIN(send), gen_send);
33623383
yjit_reg_op(BIN(leave), gen_leave);
3384+
3385+
yjit_method_codegen_table = st_init_numtable();
3386+
3387+
yjit_reg_method(rb_cBasicObject, "!", jit_rb_obj_not);
33633388
}

0 commit comments

Comments
 (0)