MJIT: Use a String buffer in builtin compilers
instead of FILE*. Using C.fprintf is slower than String manipulation on memory. I'm going to change the way MJIT writes files, and this is a prerequisite for it.
This commit is contained in:
parent
6d26f78f68
commit
6844bcc6b4
@ -13,7 +13,7 @@ struct rb_builtin_function {
|
|||||||
const char * const name;
|
const char * const name;
|
||||||
|
|
||||||
// for jit
|
// for jit
|
||||||
void (*compiler)(FILE *, long, unsigned, bool);
|
void (*compiler)(VALUE, long, unsigned, bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RB_BUILTIN_FUNCTION(_i, _name, _fname, _arity, _compiler) {\
|
#define RB_BUILTIN_FUNCTION(_i, _name, _fname, _arity, _compiler) {\
|
||||||
|
@ -203,8 +203,8 @@ module RubyVM::MJIT
|
|||||||
return src, next_pos, finish_p, compile_insns
|
return src, next_pos, finish_p, compile_insns
|
||||||
end
|
end
|
||||||
when :invokebuiltin, :opt_invokebuiltin_delegate
|
when :invokebuiltin, :opt_invokebuiltin_delegate
|
||||||
if compile_invokebuiltin(f, insn, stack_size, sp_inc, body, operands)
|
if src = compile_invokebuiltin(insn, stack_size, sp_inc, body, operands)
|
||||||
return '', next_pos, finish_p, compile_insns
|
return src, next_pos, finish_p, compile_insns
|
||||||
end
|
end
|
||||||
when :opt_getconstant_path
|
when :opt_getconstant_path
|
||||||
if src = compile_getconstant_path(stack_size, pos, insn_len, operands, status)
|
if src = compile_getconstant_path(stack_size, pos, insn_len, operands, status)
|
||||||
@ -215,7 +215,9 @@ module RubyVM::MJIT
|
|||||||
|
|
||||||
# opt_invokebuiltin_delegate_leave also implements leave insn. We need to handle it here for inlining.
|
# opt_invokebuiltin_delegate_leave also implements leave insn. We need to handle it here for inlining.
|
||||||
if insn.name == :opt_invokebuiltin_delegate_leave
|
if insn.name == :opt_invokebuiltin_delegate_leave
|
||||||
compile_invokebuiltin(f, insn, stack_size, sp_inc, body, operands)
|
if invokebuiltin_src = compile_invokebuiltin(insn, stack_size, sp_inc, body, operands)
|
||||||
|
src << invokebuiltin_src
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if stack_size != 1
|
if stack_size != 1
|
||||||
$stderr.puts "MJIT warning: Unexpected JIT stack_size on leave: #{stack_size}" # TODO: check mjit_opts?
|
$stderr.puts "MJIT warning: Unexpected JIT stack_size on leave: #{stack_size}" # TODO: check mjit_opts?
|
||||||
@ -407,18 +409,18 @@ module RubyVM::MJIT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile_invokebuiltin(f, insn, stack_size, sp_inc, body, operands)
|
def compile_invokebuiltin(insn, stack_size, sp_inc, body, operands)
|
||||||
bf = C.RB_BUILTIN.new(operands[0])
|
bf = C.RB_BUILTIN.new(operands[0])
|
||||||
if bf.compiler > 0
|
if bf.compiler > 0
|
||||||
index = (insn.name == :invokebuiltin ? -1 : operands[1])
|
index = (insn.name == :invokebuiltin ? -1 : operands[1])
|
||||||
C.fprintf(f, "{\n")
|
src = +"{\n"
|
||||||
C.fprintf(f, " VALUE val;\n")
|
src << " VALUE val;\n"
|
||||||
C.builtin_compiler(f, bf, index, stack_size, body.builtin_inline_p)
|
C.builtin_compiler(src, bf, index, stack_size, body.builtin_inline_p)
|
||||||
C.fprintf(f, " stack[#{stack_size + sp_inc - 1}] = val;\n")
|
src << " stack[#{stack_size + sp_inc - 1}] = val;\n"
|
||||||
C.fprintf(f, "}\n")
|
src << "}\n"
|
||||||
return true
|
return src
|
||||||
else
|
else
|
||||||
return false
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -143,11 +143,11 @@ cdhash_to_hash(rb_execution_context_t *ec, VALUE self, VALUE cdhash_addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
builtin_compile(rb_execution_context_t *ec, VALUE self, VALUE f_addr, VALUE bf_addr, VALUE index, VALUE stack_size, VALUE builtin_inline_p)
|
builtin_compile(rb_execution_context_t *ec, VALUE self, VALUE buf, VALUE bf_addr, VALUE index, VALUE stack_size, VALUE builtin_inline_p)
|
||||||
{
|
{
|
||||||
FILE *f = (FILE *)NUM2PTR(f_addr);
|
// Call "mjit_compile_invokebuiltin_for_#{func}" in mk_builtin_loader.rb
|
||||||
RB_BUILTIN bf = (RB_BUILTIN)NUM2PTR(bf_addr);
|
RB_BUILTIN bf = (RB_BUILTIN)NUM2PTR(bf_addr);
|
||||||
bf->compiler(f, NIL_P(index) ? -1 : NUM2LONG(index), NUM2UINT(stack_size), RTEST(builtin_inline_p));
|
bf->compiler(buf, NIL_P(index) ? -1 : NUM2LONG(index), NUM2UINT(stack_size), RTEST(builtin_inline_p));
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,10 +325,10 @@ def mk_builtin_header file
|
|||||||
. map {|i|", argv[#{i}]"} \
|
. map {|i|", argv[#{i}]"} \
|
||||||
. join('')
|
. join('')
|
||||||
f.puts %'static void'
|
f.puts %'static void'
|
||||||
f.puts %'mjit_compile_invokebuiltin_for_#{func}(FILE *f, long index, unsigned stack_size, bool inlinable_p)'
|
f.puts %'mjit_compile_invokebuiltin_for_#{func}(VALUE buf, long index, unsigned stack_size, bool inlinable_p)'
|
||||||
f.puts %'{'
|
f.puts %'{'
|
||||||
f.puts %' fprintf(f, " VALUE self = GET_SELF();\\n");'
|
f.puts %' rb_str_catf(buf, " VALUE self = GET_SELF();\\n");'
|
||||||
f.puts %' fprintf(f, " typedef VALUE (*func)(rb_execution_context_t *, VALUE#{decl});\\n");'
|
f.puts %' rb_str_catf(buf, " typedef VALUE (*func)(rb_execution_context_t *, VALUE#{decl});\\n");'
|
||||||
if inlines.has_key? cfunc_name
|
if inlines.has_key? cfunc_name
|
||||||
body_lineno, text, locals, func_name = inlines[cfunc_name]
|
body_lineno, text, locals, func_name = inlines[cfunc_name]
|
||||||
lineno, str = generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_name)
|
lineno, str = generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_name)
|
||||||
@ -336,22 +336,22 @@ def mk_builtin_header file
|
|||||||
str.gsub(/^(?!#)/, ' ').each_line {|i|
|
str.gsub(/^(?!#)/, ' ').each_line {|i|
|
||||||
j = RubyVM::CEscape.rstring2cstr(i).dup
|
j = RubyVM::CEscape.rstring2cstr(i).dup
|
||||||
j.sub!(/^ return\b/ , ' val =')
|
j.sub!(/^ return\b/ , ' val =')
|
||||||
f.printf(%' fprintf(f, "%%s", %s);\n', j)
|
f.printf(%' rb_str_catf(buf, "%%s", %s);\n', j)
|
||||||
}
|
}
|
||||||
f.puts(%' return;')
|
f.puts(%' return;')
|
||||||
f.puts(%' }')
|
f.puts(%' }')
|
||||||
end
|
end
|
||||||
if argc > 0
|
if argc > 0
|
||||||
f.puts %' if (index == -1) {'
|
f.puts %' if (index == -1) {'
|
||||||
f.puts %' fprintf(f, " const VALUE *argv = &stack[%d];\\n", stack_size - #{argc});'
|
f.puts %' rb_str_catf(buf, " const VALUE *argv = &stack[%d];\\n", stack_size - #{argc});'
|
||||||
f.puts %' }'
|
f.puts %' }'
|
||||||
f.puts %' else {'
|
f.puts %' else {'
|
||||||
f.puts %' fprintf(f, " const unsigned int lnum = ISEQ_BODY(GET_ISEQ())->local_table_size;\\n");'
|
f.puts %' rb_str_catf(buf, " const unsigned int lnum = ISEQ_BODY(GET_ISEQ())->local_table_size;\\n");'
|
||||||
f.puts %' fprintf(f, " const VALUE *argv = GET_EP() - lnum - VM_ENV_DATA_SIZE + 1 + %ld;\\n", index);'
|
f.puts %' rb_str_catf(buf, " const VALUE *argv = GET_EP() - lnum - VM_ENV_DATA_SIZE + 1 + %ld;\\n", index);'
|
||||||
f.puts %' }'
|
f.puts %' }'
|
||||||
end
|
end
|
||||||
f.puts %' fprintf(f, " func f = (func)%"PRIuVALUE"; /* == #{cfunc_name} */\\n", (VALUE)#{cfunc_name});'
|
f.puts %' rb_str_catf(buf, " func f = (func)%"PRIuVALUE"; /* == #{cfunc_name} */\\n", (VALUE)#{cfunc_name});'
|
||||||
f.puts %' fprintf(f, " val = f(ec, self#{argv});\\n");'
|
f.puts %' rb_str_catf(buf, " val = f(ec, self#{argv});\\n");'
|
||||||
f.puts %'}'
|
f.puts %'}'
|
||||||
f.puts
|
f.puts
|
||||||
}
|
}
|
||||||
|
@ -270,13 +270,6 @@ pub struct rb_method_cfunc_t {
|
|||||||
_marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
|
_marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opaque FILE type from the C standard library
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct FILE {
|
|
||||||
_data: [u8; 0],
|
|
||||||
_marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Opaque call-cache type from vm_callinfo.h
|
/// Opaque call-cache type from vm_callinfo.h
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct rb_callcache {
|
pub struct rb_callcache {
|
||||||
|
@ -1047,7 +1047,7 @@ pub struct rb_builtin_function {
|
|||||||
pub name: *const ::std::os::raw::c_char,
|
pub name: *const ::std::os::raw::c_char,
|
||||||
pub compiler: ::std::option::Option<
|
pub compiler: ::std::option::Option<
|
||||||
unsafe extern "C" fn(
|
unsafe extern "C" fn(
|
||||||
arg1: *mut FILE,
|
arg1: VALUE,
|
||||||
arg2: ::std::os::raw::c_long,
|
arg2: ::std::os::raw::c_long,
|
||||||
arg3: ::std::os::raw::c_uint,
|
arg3: ::std::os::raw::c_uint,
|
||||||
arg4: bool,
|
arg4: bool,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user