RJIT: Optimize String#empty?

This commit is contained in:
Takashi Kokubun 2023-03-18 23:24:57 -07:00
parent ca9355e173
commit 106cca5111
3 changed files with 50 additions and 1 deletions

View file

@ -2729,6 +2729,29 @@ module RubyVM::RJIT
true true
end end
# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler]
def jit_rb_str_empty_p(jit, ctx, asm, argc, known_recv_class)
# Assume same offset to len embedded or not so we can use one code path to read the length
assert_equal(C.RString.offsetof(:as, :heap, :len), C.RString.offsetof(:as, :embed, :len))
recv_opnd = ctx.stack_pop(1)
out_opnd = ctx.stack_push
asm.comment('get string length')
asm.mov(:rax, recv_opnd)
str_len_opnd = [:rax, C.RString.offsetof(:as, :heap, :len)]
asm.cmp(str_len_opnd, 0)
asm.mov(:rax, Qfalse)
asm.mov(:rcx, Qtrue)
asm.cmove(:rax, :rcx)
asm.mov(out_opnd, :rax)
return true
end
# @param jit [RubyVM::RJIT::JITState] # @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context] # @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler] # @param asm [RubyVM::RJIT::Assembler]
@ -2826,7 +2849,7 @@ module RubyVM::RJIT
register_cfunc_method(Integer, :===, :jit_rb_int_equal) register_cfunc_method(Integer, :===, :jit_rb_int_equal)
# rb_str_to_s() methods in string.c # rb_str_to_s() methods in string.c
#register_cfunc_method(String, :empty?, :jit_rb_str_empty_p) register_cfunc_method(String, :empty?, :jit_rb_str_empty_p)
register_cfunc_method(String, :to_s, :jit_rb_str_to_s) register_cfunc_method(String, :to_s, :jit_rb_str_to_s)
register_cfunc_method(String, :to_str, :jit_rb_str_to_s) register_cfunc_method(String, :to_str, :jit_rb_str_to_s)
#register_cfunc_method(String, :bytesize, :jit_rb_str_bytesize) #register_cfunc_method(String, :bytesize, :jit_rb_str_bytesize)

View file

@ -748,6 +748,31 @@ module RubyVM::RJIT # :nodoc: all
) )
end end
def C.RString
@RString ||= CType::Struct.new(
"RString", Primitive.cexpr!("SIZEOF(struct RString)"),
basic: [self.RBasic, Primitive.cexpr!("OFFSETOF((*((struct RString *)NULL)), basic)")],
as: [CType::Union.new(
"", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as)"),
heap: CType::Struct.new(
"", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as.heap)"),
len: [CType::Immediate.parse("long"), Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.heap, len)")],
ptr: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.heap, ptr)")],
aux: [CType::Union.new(
"", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as.heap.aux)"),
capa: CType::Immediate.parse("long"),
shared: self.VALUE,
), Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.heap, aux)")],
),
embed: CType::Struct.new(
"", Primitive.cexpr!("SIZEOF(((struct RString *)NULL)->as.embed)"),
len: [CType::Immediate.parse("long"), Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.embed, len)")],
ary: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF(((struct RString *)NULL)->as.embed, ary)")],
),
), Primitive.cexpr!("OFFSETOF((*((struct RString *)NULL)), as)")],
)
end
def C.RStruct def C.RStruct
@RStruct ||= CType::Struct.new( @RStruct ||= CType::Struct.new(
"RStruct", Primitive.cexpr!("SIZEOF(struct RStruct)"), "RStruct", Primitive.cexpr!("SIZEOF(struct RStruct)"),

View file

@ -556,6 +556,7 @@ generator = BindingGenerator.new(
RBasic RBasic
RObject RObject
RStruct RStruct
RString
attr_index_t attr_index_t
iseq_inline_constant_cache iseq_inline_constant_cache
iseq_inline_constant_cache_entry iseq_inline_constant_cache_entry