8000 Port remaining code-gen methods for specific C functions like to_s, t… · kddnewton/ruby@9bfce8f · GitHub
[go: up one dir, main page]

Skip to content

Commit 9bfce8f

Browse files
authored
Port remaining code-gen methods for specific C functions like to_s, to_str (ruby#204)
1 parent cd6aa4b commit 9bfce8f

File tree

5 files changed

+36
-22
lines changed

5 files changed

+36
-22
lines changed

yjit.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,13 @@ rb_iseq_opcode_at_pc(const rb_iseq_t *iseq, const VALUE *pc)
254254
return rb_vm_insn_addr2opcode((const void *)at_pc);
255255
}
256256

257+
// used by jit_rb_str_bytesize in codegen.rs
258+
VALUE
259+
rb_str_bytesize(VALUE str)
260+
{
261+
return LONG2NUM(RSTRING_LEN(str));
262+
}
263+
257264
const char*
258265
rb_insn_name(VALUE insn)
259266
{

yjit/bindgen/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ fn main() {
6363
// From internal/array.h
6464
.allowlist_function("rb_ec_ary_new_from_values")
6565

66+
// From include/ruby/internal/intern/class.h
67+
.allowlist_function("rb_singleton_class")
68+
6669
// VALUE variables for Ruby class objects
6770
// From include/ruby/internal/globals.h
6871
.allowlist_var("rb_cBasicObject")
@@ -74,6 +77,7 @@ fn main() {
7477
.allowlist_var("rb_cSymbol")
7578
.allowlist_var("rb_cFloat")
7679
.allowlist_var("rb_cString")
80+
.allowlist_var("rb_cThread")
7781

7882
// From ruby/internal/globals.h
7983
.allowlist_var("rb_mKernel")

yjit/src/codegen.rs

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3331,26 +3331,25 @@ fn yjit_reg_method(klass: VALUE, mid_str: &str, gen_fn: MethodGenFn)
33313331
CodegenGlobals::register_codegen_method(method_serial, gen_fn);
33323332
}
33333333

3334-
/*
33353334
// Codegen for rb_obj_not().
33363335
// Note, caller is responsible for generating all the right guards, including
33373336
// arity guards.
33383337
fn jit_rb_obj_not(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb, ci: *const rb_callinfo, cme: *const rb_callable_method_entry_t, block: Option<IseqPtr>, argc: i32, known_recv_class: *const VALUE) -> bool
33393338
{
3340-
const val_type_t recv_opnd = ctx.get_opnd_type(StackOpnd(0));
3339+
let recv_opnd = ctx.get_opnd_type(StackOpnd(0));
33413340

3342-
if (recv_opnd == Type::Nil || recv_opnd == Type::False) {
3341+
if recv_opnd == Type::Nil || recv_opnd == Type::False {
33433342
add_comment(cb, "rb_obj_not(nil_or_false)");
33443343
ctx.stack_pop(1);
33453344
let out_opnd = ctx.stack_push(Type::True);
3346-
mov(cb, out_opnd, imm_opnd(Qtrue));
3345+
mov(cb, out_opnd, uimm_opnd(Qtrue.into()));
33473346
}
3348-
else if (recv_opnd.is_heap || recv_opnd != Type::Unknown) {
3347+
else if recv_opnd.is_heap() || recv_opnd != Type::Unknown {
33493348
// Note: recv_opnd != Type::Nil && recv_opnd != Type::False.
33503349
add_comment(cb, "rb_obj_not(truthy)");
33513350
ctx.stack_pop(1);
33523351
let out_opnd = ctx.stack_push(Type::False);
3353-
mov(cb, out_opnd, imm_opnd(Qfalse));
3352+
mov(cb, out_opnd, uimm_opnd(Qfalse.into()));
33543353
}
33553354
else {
33563355
// jit_guard_known_klass() already ran on the receiver which should
@@ -3360,7 +3359,6 @@ fn jit_rb_obj_not(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb
33603359
}
33613360
true
33623361
}
3363-
*/
33643362

33653363
// Codegen for rb_true()
33663364
fn jit_rb_true(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb, ci: *const rb_callinfo, cme: *const rb_callable_method_entry_t, block: Option<IseqPtr>, argc: i32, known_recv_class: *const VALUE) -> bool
@@ -3401,20 +3399,13 @@ fn jit_rb_obj_equal(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, o
34013399
true
34023400
}
34033401

3404-
/*
3405-
static VALUE
3406-
yjit_str_bytesize(VALUE str)
3407-
{
3408-
return LONG2NUM(RSTRING_LEN(str));
3409-
}
3410-
34113402
fn jit_rb_str_bytesize(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb, ci: *const rb_callinfo, cme: *const rb_callable_method_entry_t, block: Option<IseqPtr>, argc: i32, known_recv_class: *const VALUE) -> bool
34123403
{
34133404
add_comment(cb, "String#bytesize");
34143405

34153406
let recv = ctx.stack_pop(1);
34163407
mov(cb, C_ARG_REGS[0], recv);
3417-
call_ptr(cb, REG0, (void *)&yjit_str_bytesize);
3408+
call_ptr(cb, REG0, rb_str_bytesize as *const u8);
34183409

34193410
let out_opnd = ctx.stack_push(Type::Fixnum);
34203411
mov(cb, out_opnd, RAX);
@@ -3428,7 +3419,7 @@ fn jit_rb_str_bytesize(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock
34283419
// this situation happens a lot in some workloads.
34293420
fn jit_rb_str_to_s(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb, ci: *const rb_callinfo, cme: *const rb_callable_method_entry_t, block: Option<IseqPtr>, argc: i32, known_recv_class: *const VALUE) -> bool
34303421
{
3431-
if (recv_known_klass && *recv_known_klass == rb_cString) {
3422+
if !known_recv_class.is_null() && unsafe { *known_recv_class == rb_cString } {
34323423
add_comment(cb, "to_s on plain string");
34333424
// The method returns the receiver, which is already on the stack.
34343425
// No stack movement.
@@ -3443,16 +3434,18 @@ fn jit_thread_s_current(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBloc
34433434
ctx.stack_pop(1);
34443435

34453436
// ec->thread_ptr
3446-
mov(cb, REG0, member_opnd(REG_EC, rb_execution_context_t, thread_ptr));
3437+
let ec_thread_ptr = mem_opnd(64, REG_EC, RUBY_OFFSET_EC_THREAD_PTR);
3438+
mov(cb, REG0, ec_thread_ptr);
34473439

34483440
// thread->self
3449-
mov(cb, REG0, member_opnd(REG0, rb_thread_t, self));
3441+
let thread_self = mem_opnd(64, REG0, RUBY_OFFSET_THREAD_SELF);
3442+
mov(cb, REG0, thread_self);
34503443

34513444
let stack_ret = ctx.stack_push(Type::UnknownHeap);
34523445
mov(cb, stack_ret, REG0);
34533446
true
34543447
}
3455-
*/
3448+
34563449
// Check if we know how to codegen for a particular cfunc method
34573450
fn lookup_cfunc_codegen(def: *const rb_method_definition_t) -> Option<MethodGenFn>
34583451
{
@@ -5172,7 +5165,7 @@ fn get_method_gen_fn()
51725165
// All these class constants are mutable statics.
51735166
unsafe {
51745167
// Specialization for C methods. See yjit_reg_method() for details.
5175-
//yjit_reg_method(rb_cBasicObject, "!", jit_rb_obj_not);
5168+
yjit_reg_method(rb_cBasicObject, "!", jit_rb_obj_not);
51765169

51775170
yjit_reg_method(rb_cNilClass, "nil?", jit_rb_true);
51785171
yjit_reg_method(rb_mKernel, "nil?", jit_rb_false);
@@ -5183,15 +5176,14 @@ fn get_method_gen_fn()
51835176
yjit_reg_method(rb_cModule, "==", jit_rb_obj_equal);
51845177
yjit_reg_method(rb_cSymbol, "==", jit_rb_obj_equal);
51855178
yjit_reg_method(rb_cSymbol, "===", jit_rb_obj_equal);
5186-
/*
5179+
51875180
// rb_str_to_s() methods in string.c
51885181
yjit_reg_method(rb_cString, "to_s", jit_rb_str_to_s);
51895182
yjit_reg_method(rb_cString, "to_str", jit_rb_str_to_s);
51905183
yjit_reg_method(rb_cString, "bytesize", jit_rb_str_bytesize);
51915184

51925185
// Thread.current
51935186
yjit_reg_method(rb_singleton_class(rb_cThread), "current", jit_thread_s_current);
5194-
*/
51955187
}
51965188
}
51975189

yjit/src/cruby.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ extern "C" {
230230

231231
#[link_name = "rb_METHOD_ENTRY_VISI"]
232232
pub fn METHOD_ENTRY_VISI(me: * const rb_callable_method_entry_t) -> rb_method_visibility_t;
233+
234+
pub fn rb_str_bytesize(str:VALUE) -> VALUE;
233235
}
234236

235237
pub fn insn_len(opcode:usize) -> u32
@@ -579,6 +581,9 @@ pub const RUBY_OFFSET_EC_INTERRUPT_FLAG: i32 = 32; // rb_atomic_t (u32)
579581
pub const RUBY_OFFSET_EC_INTERRUPT_MASK: i32 = 36; // rb_atomic_t (u32)
580582
pub const RUBY_OFFSET_EC_THREAD_PTR: i32 = 48;
581583

584+
// Constants from rb_thread_t in vm_core.h
585+
pub const RUBY_OFFSET_THREAD_SELF: i32 = 16;
586+
582587
// TODO: need to dynamically autogenerate constants for all the YARV opcodes from insns.def
583588
pub const OP_NOP:usize = 0;
584589
pub const OP_GETLOCAL:usize = 1;

yjit/src/cruby_bindings.inc.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ pub const FALSE_REDEFINED_OP_FLAG: u32 = 2048;
1414
pub const PROC_REDEFINED_OP_FLAG: u32 = 4096;
1515
pub const VM_BLOCK_HANDLER_NONE: u32 = 0;
1616
pub type ID = ::std::os::raw::c_ulong;
17+
extern "C" {
18+
pub fn rb_singleton_class(obj: VALUE) -> VALUE;
19+
}
1720
pub type rb_alloc_func_t = ::std::option::Option<unsafe extern "C" fn(klass: VALUE) -> VALUE>;
1821
extern "C" {
1922
pub fn rb_get_alloc_func(klass: VALUE) -> rb_alloc_func_t;
@@ -81,6 +84,9 @@ extern "C" {
8184
extern "C" {
8285
pub static mut rb_cSymbol: VALUE;
8386
}
87+
extern "C" {
88+
pub static mut rb_cThread: VALUE;
89+
}
8490
extern "C" {
8591
pub static mut rb_cTrueClass: VALUE;
8692
}

0 commit comments

Comments
 (0)
0