summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in2
-rw-r--r--array.c6
-rw-r--r--bignum.c2
-rw-r--r--class.c4
-rw-r--r--common.mk5
-rw-r--r--compile.c2
-rw-r--r--error.c2
-rw-r--r--gc.c5
-rw-r--r--hash.c10
-rw-r--r--include/ruby/defines.h4
-rw-r--r--insns.def15
-rw-r--r--internal.h1
-rw-r--r--iseq.c2
-rw-r--r--mjit.c62
-rw-r--r--mjit.h3
-rw-r--r--mjit_compile.c158
-rw-r--r--numeric.c6
-rw-r--r--object.c10
-rw-r--r--proc.c4
-rw-r--r--re.c2
-rw-r--r--st.c2
-rw-r--r--string.c10
-rw-r--r--test/-ext-/thread_fd_close/test_thread_fd_close.rb2
-rw-r--r--test/lib/minitest/unit.rb4
-rw-r--r--test/ruby/test_io.rb8
-rw-r--r--test/ruby/test_settracefunc.rb3
-rw-r--r--test/ruby/test_thread.rb1
-rw-r--r--test/rubygems/test_gem_util.rb1
-rw-r--r--test/thread/test_cv.rb2
-rw-r--r--test/thread/test_sync.rb1
-rw-r--r--test/webrick/test_httpserver.rb1
-rw-r--r--test/webrick/test_server.rb1
-rw-r--r--thread.c2
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn.erb133
-rw-r--r--tool/ruby_vm/views/_mjit_compile_send.erb74
-rw-r--r--tool/ruby_vm/views/mjit_compile.inc.erb66
-rw-r--r--tool/transform_mjit_header.rb1
-rwxr-xr-xtool/update-deps1
-rw-r--r--variable.c20
-rw-r--r--vm.c36
-rw-r--r--vm_backtrace.c4
-rw-r--r--vm_core.h3
-rw-r--r--vm_eval.c18
-rw-r--r--vm_exec.h19
-rw-r--r--vm_insnhelper.c33
-rw-r--r--vm_insnhelper.h5
-rw-r--r--vm_method.c19
-rw-r--r--vm_trace.c2
-rw-r--r--win32/Makefile.sub2
-rwxr-xr-xwin32/mkexports.rb2
50 files changed, 680 insertions, 101 deletions
@@ -516,7 +516,7 @@ update-simplecov:
update-coverage: update-simplecov update-simplecov-html update-doclie
INSNS = opt_sc.inc optinsn.inc optunifs.inc insns.inc insns_info.inc \
- vmtc.inc vm.inc
$(INSNS): $(srcdir)/insns.def vm_opts.h \
$(srcdir)/defs/opt_operand.def $(srcdir)/defs/opt_insn_unif.def \
@@ -506,7 +506,7 @@ VALUE
return ary;
}
-VALUE
rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts)
{
VALUE ary;
@@ -640,7 +640,7 @@ rb_check_array_type(VALUE ary)
return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary);
}
-VALUE
rb_check_to_array(VALUE ary)
{
return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_a);
@@ -1297,7 +1297,7 @@ rb_ary_aref2(VALUE ary, VALUE b, VALUE e)
return rb_ary_subseq(ary, beg, len);
}
-VALUE
rb_ary_aref1(VALUE ary, VALUE arg)
{
long beg, len;
@@ -4490,7 +4490,7 @@ rb_uint128t2big(uint128_t n)
return big;
}
-VALUE
rb_int128t2big(int128_t n)
{
int neg = 0;
@@ -616,7 +616,7 @@ rb_define_class_id(ID id, VALUE super)
* \return the value \c Class#inherited's returns
* \pre Each of \a super and \a klass must be a \c Class object.
*/
-VALUE
rb_class_inherited(VALUE super, VALUE klass)
{
ID inherited;
@@ -1773,7 +1773,7 @@ rb_define_attr(VALUE klass, const char *name, int read, int write)
rb_attr(klass, rb_intern(name), read, write, FALSE);
}
-VALUE
rb_keyword_error_new(const char *error, VALUE keys)
{
const VALUE *ptr = RARRAY_CONST_PTR(keys);
@@ -890,6 +890,7 @@ $(srcs_vpath)insns.inc: $(srcdir)/tool/ruby_vm/views/insns.inc.erb
$(srcs_vpath)insns_info.inc: $(srcdir)/tool/ruby_vm/views/insns_info.inc.erb
$(srcs_vpath)vmtc.inc: $(srcdir)/tool/ruby_vm/views/vmtc.inc.erb
$(srcs_vpath)vm.inc: $(srcdir)/tool/ruby_vm/views/vm.inc.erb
common-srcs: $(srcs_vpath)parse.c $(srcs_vpath)lex.c $(srcs_vpath)enc/trans/newline.c $(srcs_vpath)id.c \
srcs-lib srcs-ext incs
@@ -2003,8 +2004,12 @@ mjit.$(OBJEXT): {$(VPATH)}mjit.h
mjit.$(OBJEXT): {$(VPATH)}ruby_assert.h
mjit.$(OBJEXT): {$(VPATH)}version.h
mjit.$(OBJEXT): {$(VPATH)}vm_core.h
mjit_compile.$(OBJEXT): {$(VPATH)}internal.h
mjit_compile.$(OBJEXT): {$(VPATH)}mjit_compile.c
mjit_compile.$(OBJEXT): {$(VPATH)}vm_core.h
load.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
load.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
@@ -754,7 +754,7 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
}
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
-static int
rb_vm_insn_addr2insn(const void *addr) /* cold path */
{
int insn;
@@ -1161,7 +1161,7 @@ exc_set_backtrace(VALUE exc, VALUE bt)
return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
}
-VALUE
rb_exc_set_backtrace(VALUE exc, VALUE bt)
{
return exc_set_backtrace(exc, bt);
@@ -2216,6 +2216,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
break;
case T_MODULE:
case T_CLASS:
rb_id_table_free(RCLASS_M_TBL(obj));
if (RCLASS_IV_TBL(obj)) {
st_free_table(RCLASS_IV_TBL(obj));
@@ -4054,7 +4055,7 @@ stack_check(rb_execution_context_t *ec, int water_mark)
#define STACKFRAME_FOR_CALL_CFUNC 838
-int
rb_ec_stack_check(rb_execution_context_t *ec)
{
return stack_check(ec, STACKFRAME_FOR_CALL_CFUNC);
@@ -6053,7 +6054,7 @@ rb_gc_writebarrier_unprotect(VALUE obj)
/*
* remember `obj' if needed.
*/
-void
rb_gc_writebarrier_remember(VALUE obj)
{
rb_objspace_t *objspace = &rb_objspace;
@@ -443,7 +443,7 @@ rb_hash_new_compare_by_id(void)
return hash;
}
-VALUE
rb_hash_new_with_size(st_index_t size)
{
VALUE ret = rb_hash_new();
@@ -495,7 +495,7 @@ rb_hash_tbl(VALUE hash)
return hash_tbl(hash);
}
-struct st_table *
rb_hash_tbl_raw(VALUE hash)
{
return hash_tbl(hash);
@@ -2155,7 +2155,7 @@ keys_i(VALUE key, VALUE value, VALUE ary)
*
*/
-VALUE
rb_hash_keys(VALUE hash)
{
VALUE keys;
@@ -2243,7 +2243,7 @@ rb_hash_values(VALUE hash)
* See also Enumerable#include?
*/
-VALUE
rb_hash_has_key(VALUE hash, VALUE key)
{
if (!RHASH(hash)->ntbl)
@@ -2949,7 +2949,7 @@ rb_hash_compare_by_id(VALUE hash)
*
*/
-VALUE
rb_hash_compare_by_id_p(VALUE hash)
{
if (!RHASH(hash)->ntbl)
@@ -270,6 +270,10 @@ void xfree(void*);
#define RUBY_FUNC_EXPORTED
#endif
#ifndef RUBY_EXTERN
#define RUBY_EXTERN extern
#endif
@@ -695,8 +695,7 @@ defineclass
class_iseq->body->iseq_encoded, GET_SP(),
class_iseq->body->local_table_size,
class_iseq->body->stack_max);
- RESTORE_REGS();
- NEXT_INSN();
}
/**********************************************************/
@@ -823,8 +822,7 @@ invokeblock
val = vm_invoke_block(ec, GET_CFP(), &calling, ci, block_handler);
if (val == Qundef) {
- RESTORE_REGS();
- NEXT_INSN();
}
}
@@ -1090,7 +1088,9 @@ opt_neq
val = vm_opt_neq(ci, cc, ci_eq, cc_eq, recv, obj);
if (val == Qundef) {
ADD_PC(2); /* !!! */
DIS_ORIGINAL_INSN(opt_send_without_block);
}
}
@@ -1206,9 +1206,11 @@ opt_aset_with
val = tmp;
}
else {
TOPN(0) = rb_str_resurrect(key);
PUSH(val);
ADD_PC(1); /* !!! */
DIS_ORIGINAL_INSN(opt_send_without_block);
}
}
@@ -1223,8 +1225,10 @@ opt_aref_with
val = vm_opt_aref_with(recv, key);
if (val == Qundef) {
PUSH(rb_str_resurrect(key));
ADD_PC(1); /* !!! */
DIS_ORIGINAL_INSN(opt_send_without_block);
}
}
@@ -1339,8 +1343,7 @@ opt_call_c_function
THROW_EXCEPTION(err);
}
- RESTORE_REGS();
- NEXT_INSN();
}
/* BLT */
@@ -1124,6 +1124,7 @@ int rb_dvar_defined(ID, const struct rb_block *);
int rb_local_defined(ID, const struct rb_block *);
const char * rb_insns_name(int i);
VALUE rb_insns_name_array(void);
/* complex.c */
VALUE rb_complex_plus(VALUE, VALUE);
@@ -1480,7 +1480,7 @@ rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos)
}
}
-rb_event_flag_t
rb_iseq_event_flags(const rb_iseq_t *iseq, size_t pos)
{
const struct iseq_insn_info_entry *entry = get_insn_info(iseq, pos);
@@ -83,6 +83,8 @@
#include "mjit.h"
#include "version.h"
#include "gc.h"
#include "ruby_assert.h"
extern void rb_native_mutex_lock(rb_nativethread_lock_t *lock);
@@ -194,6 +196,9 @@ static char *header_file;
static char *pch_file;
/* Path of "/tmp", which can be changed to $TMP in MinGW. */
static char *tmp_dir;
/* Ruby level interface module. */
VALUE rb_mMJIT;
@@ -1081,6 +1086,19 @@ child_after_fork(void)
/* TODO: Should we initiate MJIT in the forked Ruby. */
}
/* Default permitted number of units with a JIT code kept in
memory. */
#define DEFAULT_CACHE_SIZE 1000
@@ -1149,6 +1167,14 @@ mjit_init(struct mjit_options *opts)
rb_native_cond_initialize(&mjit_worker_wakeup, RB_CONDATTR_CLOCK_MONOTONIC);
rb_native_cond_initialize(&mjit_gc_wakeup, RB_CONDATTR_CLOCK_MONOTONIC);
/* Initialize worker thread */
finish_worker_p = FALSE;
worker_finished = FALSE;
@@ -1233,3 +1259,39 @@ mjit_mark(void)
CRITICAL_SECTION_FINISH(4, "mjit_mark");
RUBY_MARK_LEAVE("mjit");
}
@@ -80,6 +80,9 @@ extern void mjit_free_iseq(const rb_iseq_t *iseq);
extern void mjit_mark(void);
extern struct mjit_cont *mjit_cont_new(rb_execution_context_t *ec);
extern void mjit_cont_free(struct mjit_cont *cont);
/* A threshold used to reject long iseqs from JITting as such iseqs
takes too much time to be compiled. */
@@ -8,11 +8,163 @@
#include "internal.h"
#include "vm_core.h"
-/* Compile ISeq to C code in F. Return TRUE if it succeeds to compile. */
int
mjit_compile(FILE *f, const struct rb_iseq_constant_body *body, const char *funcname)
{
- /* TODO: Write your own JIT compiler here. */
- return FALSE;
}
@@ -1157,7 +1157,7 @@ flodivmod(double x, double y, double *divp, double *modp)
* An error will be raised if y == 0.
*/
-double
ruby_float_mod(double x, double y)
{
double mod;
@@ -1333,7 +1333,7 @@ num_equal(VALUE x, VALUE y)
* so an implementation-dependent value is returned.
*/
-VALUE
rb_float_equal(VALUE x, VALUE y)
{
volatile double a, b;
@@ -1436,7 +1436,7 @@ flo_cmp(VALUE x, VALUE y)
return rb_dbl_cmp(a, b);
}
-int
rb_float_cmp(VALUE x, VALUE y)
{
return NUM2INT(flo_cmp(x, y));
@@ -198,7 +198,7 @@ rb_eql(VALUE obj1, VALUE obj2)
* \private
*++
*/
-VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
if (obj1 == obj2) return Qtrue;
@@ -217,7 +217,7 @@ VALUE rb_obj_hash(VALUE obj);
*++
*/
-VALUE
rb_obj_not(VALUE obj)
{
return RTEST(obj) ? Qfalse : Qtrue;
@@ -233,7 +233,7 @@ rb_obj_not(VALUE obj)
*++
*/
-VALUE
rb_obj_not_equal(VALUE obj1, VALUE obj2)
{
VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
@@ -304,7 +304,7 @@ rb_obj_singleton_class(VALUE obj)
}
/*! \private */
-void
rb_obj_copy_ivar(VALUE dest, VALUE obj)
{
if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
@@ -3019,7 +3019,7 @@ rb_check_convert_type(VALUE val, int type, const char *tname, const char *method
}
/*! \private */
-VALUE
rb_check_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
{
VALUE v;
@@ -677,7 +677,7 @@ rb_vm_ifunc_new(VALUE (*func)(ANYARGS), const void *data, int min_argc, int max_
return IFUNC_NEW(func, data, arity.packed);
}
-VALUE
rb_func_proc_new(rb_block_call_func_t func, VALUE val)
{
struct vm_ifunc *ifunc = rb_vm_ifunc_proc_new(func, (void *)val);
@@ -1206,7 +1206,7 @@ rb_hash_proc(st_index_t hash, VALUE prc)
return rb_hash_uint(hash, (st_index_t)proc->block.as.captured.ep >> 16);
}
-VALUE
rb_sym_to_proc(VALUE sym)
{
static VALUE sym_proc_cache = Qfalse;
@@ -2891,7 +2891,7 @@ rb_reg_init_str_enc(VALUE re, VALUE s, rb_encoding *enc, int options)
return re;
}
-VALUE
rb_reg_new_ary(VALUE ary, int opt)
{
return rb_reg_new_str(rb_reg_preprocess_dregexp(ary, opt), opt);
@@ -2171,7 +2171,7 @@ st_insert_generic(st_table *tab, long argc, const VALUE *argv, VALUE hash)
/* Mimics ruby's { foo => bar } syntax. This function is placed here
because it touches table internals and write barriers at once. */
-void
rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
{
st_index_t n;
@@ -373,7 +373,7 @@ rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encod
return setup_fake_str(fake_str, name, len, rb_enc_to_index(enc));
}
-VALUE
rb_fstring_new(const char *ptr, long len)
{
struct RString fake_str;
@@ -1445,7 +1445,7 @@ rb_obj_as_string(VALUE obj)
return rb_obj_as_string_result(str, obj);
}
-VALUE
rb_obj_as_string_result(VALUE str, VALUE obj)
{
if (!RB_TYPE_P(str, T_STRING))
@@ -2933,7 +2933,7 @@ rb_str_append(VALUE str, VALUE str2)
#define MIN_PRE_ALLOC_SIZE 48
-VALUE
rb_str_concat_literals(size_t num, const VALUE *strary)
{
VALUE str;
@@ -10391,7 +10391,7 @@ rb_str_quote_unprintable(VALUE str)
return str;
}
-VALUE
rb_id_quote_unprintable(ID id)
{
return rb_str_quote_unprintable(rb_id2str(id));
@@ -10468,7 +10468,7 @@ sym_to_sym(VALUE sym)
return sym;
}
-VALUE
rb_sym_proc_call(ID mid, int argc, const VALUE *argv, VALUE passed_proc)
{
VALUE obj;
@@ -6,6 +6,8 @@ require 'io/wait'
class TestThreadFdClose < Test::Unit::TestCase
def test_thread_fd_close
IO.pipe do |r, w|
th = Thread.new do
begin
@@ -956,7 +956,9 @@ module MiniTest
puts if @verbose
$stdout.flush
- checker.check("#{inst.class}\##{inst.__name__}")
inst._assertions
}
@@ -2135,6 +2135,12 @@ class TestIO < Test::Unit::TestCase
end
def test_autoclose_true_closed_by_finalizer
feature2250 = '[ruby-core:26222]'
pre = 'ft2250'
t = Tempfile.new(pre)
@@ -2150,7 +2156,7 @@ class TestIO < Test::Unit::TestCase
assert_raise(Errno::EBADF, feature2250) {t.close}
end
ensure
- t.close!
end
def test_autoclose_false_closed_by_finalizer
@@ -1819,6 +1819,9 @@ class TestSetTraceFunc < Test::Unit::TestCase
}
# it is dirty hack. usually we shouldn't use such technique
Thread.pass until t.status == 'sleep'
t.add_trace_func proc{|ev, file, line, *args|
if file == __FILE__
@@ -280,6 +280,7 @@ class TestThread < Test::Unit::TestCase
s += 1
end
Thread.pass until t.stop?
assert_equal(1, s)
t.wakeup
Thread.pass while t.alive?
@@ -5,6 +5,7 @@ require 'rubygems/util'
class TestGemUtil < Gem::TestCase
def test_class_popen
assert_equal "0\n", Gem::Util.popen(Gem.ruby, '-e', 'p 0')
assert_raises Errno::ECHILD do
@@ -33,6 +33,8 @@ class TestConditionVariable < Test::Unit::TestCase
end
def test_condvar_wait_exception_handling
# Calling wait in the only thread running should raise a ThreadError of
# 'stopping only thread'
mutex = Mutex.new
@@ -59,6 +59,7 @@ class SyncTest < Test::Unit::TestCase
}
sleep 0.1 until t.stop?
t.raise
t.join
@@ -253,6 +253,7 @@ class TestWEBrickHTTPServer < Test::Unit::TestCase
server.virtual_host(WEBrick::HTTPServer.new(vhost_config))
Thread.pass while server.status != :Running
assert_equal(1, started, log.call)
assert_equal(0, stopped, log.call)
assert_equal(0, accepted, log.call)
@@ -65,6 +65,7 @@ class TestWEBrickServer < Test::Unit::TestCase
}
TestWEBrick.start_server(Echo, config){|server, addr, port, log|
true while server.status != :Running
assert_equal(1, started, log.call)
assert_equal(0, stopped, log.call)
assert_equal(0, accepted, log.call)
@@ -2089,7 +2089,7 @@ threadptr_get_interrupts(rb_thread_t *th)
return interrupt & (rb_atomic_t)~ec->interrupt_mask;
}
-void
rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing)
{
rb_atomic_t interrupt;
@@ -0,0 +1,133 @@
@@ -0,0 +1,74 @@
@@ -0,0 +1,66 @@
@@ -17,6 +17,7 @@ module MJITHeader
]
IGNORED_FUNCTIONS = [
'rb_equal_opt', # Not used from VM and not compilable
]
@@ -120,6 +120,7 @@ FILES_NEED_VPATH = %w[
known_errors.inc
lex.c
miniprelude.c
newline.c
node_name.inc
opt_sc.inc
@@ -480,7 +480,7 @@ struct rb_global_variable {
struct trace_var *trace;
};
-struct rb_global_entry*
rb_global_entry(ID id)
{
struct rb_global_entry *entry;
@@ -790,7 +790,7 @@ rb_f_untrace_var(int argc, const VALUE *argv)
return Qnil;
}
-VALUE
rb_gvar_get(struct rb_global_entry *entry)
{
struct rb_global_variable *var = entry->var;
@@ -823,7 +823,7 @@ trace_en(struct rb_global_variable *var)
return Qnil; /* not reached */
}
-VALUE
rb_gvar_set(struct rb_global_entry *entry, VALUE val)
{
struct trace_data trace;
@@ -858,7 +858,7 @@ rb_gv_get(const char *name)
return rb_gvar_get(entry);
}
-VALUE
rb_gvar_defined(struct rb_global_entry *entry)
{
if (entry->var->getter == rb_gvar_undef_getter) return Qfalse;
@@ -2010,7 +2010,7 @@ check_autoload_required(VALUE mod, ID id, const char **loadingpath)
return 0;
}
-int
rb_autoloading_value(VALUE mod, ID id, VALUE* value)
{
VALUE load;
@@ -2211,7 +2211,7 @@ rb_autoload_p(VALUE mod, ID id)
return (ele = check_autoload_data(load)) ? ele->feature : Qnil;
}
-void
rb_const_warn_if_deprecated(const rb_const_entry_t *ce, VALUE klass, ID id)
{
if (RB_CONST_DEPRECATED_P(ce)) {
@@ -2294,7 +2294,7 @@ rb_const_get_at(VALUE klass, ID id)
return rb_const_get_0(klass, id, TRUE, FALSE, FALSE);
}
-VALUE
rb_public_const_get_from(VALUE klass, ID id)
{
return rb_const_get_0(klass, id, TRUE, TRUE, TRUE);
@@ -2306,7 +2306,7 @@ rb_public_const_get(VALUE klass, ID id)
return rb_const_get_0(klass, id, FALSE, TRUE, TRUE);
}
-VALUE
rb_public_const_get_at(VALUE klass, ID id)
{
return rb_const_get_0(klass, id, TRUE, FALSE, TRUE);
@@ -2544,7 +2544,7 @@ rb_const_defined_at(VALUE klass, ID id)
return rb_const_defined_0(klass, id, TRUE, FALSE, FALSE);
}
-int
rb_public_const_defined_from(VALUE klass, ID id)
{
return rb_const_defined_0(klass, id, TRUE, TRUE, TRUE);
@@ -3123,7 +3123,7 @@ rb_st_copy(VALUE obj, struct st_table *orig_tbl)
return new_tbl;
}
-rb_const_entry_t *
rb_const_lookup(VALUE klass, ID id)
{
struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
@@ -293,7 +293,7 @@ static void vm_collect_usage_register(int reg, int isset);
#endif
static VALUE vm_make_env_object(const rb_execution_context_t *ec, rb_control_frame_t *cfp);
-static VALUE vm_invoke_bmethod(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, VALUE block_handler);
static VALUE vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, VALUE block_handler);
static VALUE rb_block_param_proxy;
@@ -302,17 +302,24 @@ static VALUE rb_block_param_proxy;
#include "vm_insnhelper.h"
#include "vm_exec.h"
#include "vm_insnhelper.c"
#include "vm_exec.c"
#include "vm_method.c"
#include "vm_eval.c"
#define PROCDEBUG 0
rb_serial_t
rb_next_class_serial(void)
{
- return NEXT_CLASS_SERIAL();
}
VALUE rb_cRubyVM;
@@ -339,7 +346,7 @@ rb_vm_inc_const_missing_count(void)
VALUE rb_class_path_no_cache(VALUE _klass);
-int
rb_dtrace_setup(rb_execution_context_t *ec, VALUE klass, ID id,
struct ruby_dtrace_method_hook_args *args)
{
@@ -499,7 +506,7 @@ rb_vm_get_binding_creatable_next_cfp(const rb_execution_context_t *ec, const rb_
return 0;
}
-rb_control_frame_t *
rb_vm_get_ruby_level_next_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp)
{
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, cfp)) bp();
@@ -512,6 +519,8 @@ rb_vm_get_ruby_level_next_cfp(const rb_execution_context_t *ec, const rb_control
return 0;
}
static rb_control_frame_t *
vm_get_ruby_level_caller_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp)
{
@@ -546,6 +555,8 @@ rb_vm_pop_cfunc_frame(void)
vm_pop_frame(ec, cfp, cfp->ep);
}
void
rb_vm_rewind_cfp(rb_execution_context_t *ec, rb_control_frame_t *cfp)
{
@@ -880,7 +891,7 @@ rb_proc_dup(VALUE self)
}
-VALUE
rb_vm_make_proc_lambda(const rb_execution_context_t *ec, const struct rb_captured_block *captured, VALUE klass, int8_t is_lambda)
{
VALUE procval;
@@ -1157,14 +1168,14 @@ vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self,
return invoke_block_from_c_proc(ec, proc, self, argc, argv, passed_block_handler, proc->is_lambda);
}
-static VALUE
vm_invoke_bmethod(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self,
int argc, const VALUE *argv, VALUE block_handler)
{
return invoke_block_from_c_proc(ec, proc, self, argc, argv, block_handler, TRUE);
}
-VALUE
rb_vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc,
int argc, const VALUE *argv, VALUE passed_block_handler)
{
@@ -1391,7 +1402,7 @@ make_localjump_error(const char *mesg, VALUE value, int reason)
return exc;
}
-void
rb_vm_localjump_error(const char *mesg, VALUE value, int reason)
{
VALUE exc = make_localjump_error(mesg, value, reason);
@@ -1775,7 +1786,7 @@ hook_before_rewind(rb_execution_context_t *ec, const rb_control_frame_t *cfp, in
};
*/
-static VALUE
vm_exec(rb_execution_context_t *ec)
{
enum ruby_tag_type state;
@@ -1789,8 +1800,8 @@ vm_exec(rb_execution_context_t *ec)
if ((state = EC_EXEC_TAG()) == TAG_NONE) {
result = mjit_exec(ec);
vm_loop_start:
- if (result == Qundef)
- result = vm_exec_core(ec, initial);
VM_ASSERT(ec->tag == &_tag);
if ((state = _tag.state) != TAG_NONE) {
err = (struct vm_throw_data *)result;
@@ -2000,6 +2011,7 @@ vm_exec(rb_execution_context_t *ec)
state = 0;
ec->tag->state = TAG_NONE;
ec->errinfo = Qnil;
result = Qundef;
goto vm_loop_start;
}
@@ -3424,4 +3436,6 @@ vm_collect_usage_register(int reg, int isset)
}
#endif
#include "vm_call_iseq_optimized.inc" /* required from vm_insnhelper.c */
@@ -520,7 +520,7 @@ bt_iter_cfunc(void *ptr, const rb_control_frame_t *cfp, ID mid)
loc->body.cfunc.prev_loc = arg->prev_loc;
}
-VALUE
rb_ec_backtrace_object(const rb_execution_context_t *ec)
{
struct bt_iter_arg arg;
@@ -595,7 +595,7 @@ rb_backtrace_to_str_ary(VALUE self)
return bt->strary;
}
-void
rb_backtrace_use_iseq_first_lineno_for_last_location(VALUE self)
{
const rb_backtrace_t *bt;
@@ -686,9 +686,10 @@ typedef struct rb_control_frame_struct {
VALUE self; /* cfp[3] / block[0] */
const VALUE *ep; /* cfp[4] / block[1] */
const void *block_code; /* cfp[5] / block[2] */ /* iseq or ifunc */
#if VM_DEBUG_BP_CHECK
- VALUE *bp_check; /* cfp[6] */
#endif
} rb_control_frame_t;
@@ -20,7 +20,7 @@ static inline VALUE vm_yield_with_cref(rb_execution_context_t *ec, int argc, con
static inline VALUE vm_yield(rb_execution_context_t *ec, int argc, const VALUE *argv);
static inline VALUE vm_yield_with_block(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE block_handler);
static inline VALUE vm_yield_force_blockarg(rb_execution_context_t *ec, VALUE args);
-static VALUE vm_exec(rb_execution_context_t *ec);
static void vm_set_eval_stack(rb_execution_context_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, const struct rb_block *base_block);
static int vm_collect_local_variables_in_heap(const VALUE *dfp, const struct local_var_list *vars);
@@ -38,7 +38,9 @@ typedef enum call_type {
static VALUE send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope);
static VALUE vm_call0_body(rb_execution_context_t* ec, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const VALUE *argv);
-static VALUE
vm_call0(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
{
struct rb_calling_info calling_entry, *calling;
@@ -252,6 +254,8 @@ rb_current_receiver(void)
return cfp->self;
}
static inline void
stack_check(rb_execution_context_t *ec)
{
@@ -262,6 +266,8 @@ stack_check(rb_execution_context_t *ec)
}
}
static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE recv, ID mid);
static inline enum method_missing_reason rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self);
@@ -633,7 +639,7 @@ rb_method_missing(int argc, const VALUE *argv, VALUE obj)
UNREACHABLE;
}
-static VALUE
make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
int argc, const VALUE *argv, int priv)
{
@@ -659,6 +665,8 @@ make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
return rb_class_new_instance(n, args, exc);
}
static void
raise_method_missing(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE obj,
enum method_missing_reason last_call_status)
@@ -740,6 +748,8 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, enum method_missin
return result;
}
/*!
* Calls a method
* \param recv receiver of the method
@@ -2175,3 +2185,5 @@ Init_vm_eval(void)
id_tag = rb_intern_const("tag");
id_value = rb_intern_const("value");
}
@@ -167,8 +167,26 @@ default: \
#endif
#define VM_SP_CNT(ec, sp) ((sp) - (ec)->vm_stack)
#if OPT_CALL_THREADED_CODE
#define THROW_EXCEPTION(exc) do { \
ec->errinfo = (VALUE)(exc); \
@@ -177,6 +195,7 @@ default: \
#else
#define THROW_EXCEPTION(exc) return (VALUE)(exc)
#endif
#define SCREG(r) (reg_##r)
@@ -243,7 +243,8 @@ vm_push_frame(rb_execution_context_t *ec,
*sp++ = specval /* ep[-1] / block handler or prev env ptr */;
*sp = type; /* ep[-0] / ENV_FLAGS */
- cfp->ep = sp;
cfp->sp = sp + 1;
#if VM_DEBUG_BP_CHECK
@@ -1295,6 +1296,18 @@ vm_expandarray(rb_control_frame_t *cfp, VALUE ary, rb_num_t num, int flag)
static VALUE vm_call_general(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
static void
vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE recv)
{
@@ -1312,13 +1325,7 @@ vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE
}
RB_DEBUG_COUNTER_INC(mc_inline_miss);
#endif
- cc->me = rb_callable_method_entry(klass, ci->mid);
- VM_ASSERT(callable_method_entry_p(cc->me));
- cc->call = vm_call_general;
-#if OPT_INLINE_METHOD_CACHE
- cc->method_state = GET_GLOBAL_METHOD_STATE();
- cc->class_serial = RCLASS_SERIAL(klass);
-#endif
}
static inline int
@@ -1458,7 +1465,7 @@ rb_eql_opt(VALUE obj1, VALUE obj2)
return opt_eql_func(obj1, obj2, &ci, &cc);
}
-static VALUE vm_call0(rb_execution_context_t *ec, VALUE, ID, int, const VALUE*, const rb_callable_method_entry_t *);
static VALUE
check_match(rb_execution_context_t *ec, VALUE pattern, VALUE target, enum vm_check_match_type type)
@@ -1562,9 +1569,9 @@ static inline VALUE vm_call_method(rb_execution_context_t *ec, rb_control_frame_
static vm_call_handler vm_call_iseq_setup_func(const struct rb_call_info *ci, const int param_size, const int local_size);
-static rb_method_definition_t *method_definition_create(rb_method_type_t type, ID mid);
-static void method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts);
-static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2);
static const rb_iseq_t *
def_iseq_ptr(rb_method_definition_t *def)
@@ -1590,7 +1597,7 @@ vm_call_iseq_setup_normal_0start(rb_execution_context_t *ec, rb_control_frame_t
return vm_call_iseq_setup_normal(ec, cfp, calling, ci, cc, 0, param, local);
}
-static inline int
simple_iseq_p(const rb_iseq_t *iseq)
{
return iseq->body->param.flags.has_opt == FALSE &&
@@ -130,8 +130,7 @@ enum vm_regan_acttype {
#define CALL_METHOD(calling, ci, cc) do { \
VALUE v = (*(cc)->call)(ec, GET_CFP(), (calling), (ci), (cc)); \
if (v == Qundef && (v = mjit_exec(ec)) == Qundef) { \
- RESTORE_REGS(); \
- NEXT_INSN(); \
} \
else { \
val = v; \
@@ -185,7 +184,7 @@ enum vm_regan_acttype {
#define GET_GLOBAL_CONSTANT_STATE() (ruby_vm_global_constant_state)
#define INC_GLOBAL_CONSTANT_STATE() (++ruby_vm_global_constant_state)
-static VALUE make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
int argc, const VALUE *argv, int priv);
static inline struct vm_throw_data *
@@ -62,6 +62,7 @@ static struct {
static void
rb_class_clear_method_cache(VALUE klass, VALUE arg)
{
RCLASS_SERIAL(klass) = rb_next_class_serial();
if (RB_TYPE_P(klass, T_ICLASS)) {
@@ -171,7 +172,7 @@ rb_free_method_entry(const rb_method_entry_t *me)
}
static inline rb_method_entry_t *search_method(VALUE klass, ID id, VALUE *defined_class_ptr);
-static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2);
static inline rb_method_entry_t *
lookup_method_table(VALUE klass, ID id)
@@ -222,7 +223,7 @@ setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE (*func)(), int argc)
cfunc->invoker = call_cfunc_invoker_func(argc);
}
-static void
method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts)
{
*(rb_method_definition_t **)&me->def = def;
@@ -336,7 +337,7 @@ method_definition_reset(const rb_method_entry_t *me)
}
}
-static rb_method_definition_t *
method_definition_create(rb_method_type_t type, ID mid)
{
rb_method_definition_t *def;
@@ -401,7 +402,7 @@ rb_method_entry_clone(const rb_method_entry_t *src_me)
return me;
}
-const rb_callable_method_entry_t *
rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class)
{
rb_method_definition_t *def = src_me->def;
@@ -812,7 +813,7 @@ method_entry_get(VALUE klass, ID id, VALUE *defined_class_ptr)
return method_entry_get_without_cache(klass, id, defined_class_ptr);
}
-const rb_method_entry_t *
rb_method_entry(VALUE klass, ID id)
{
return method_entry_get(klass, id, NULL);
@@ -853,7 +854,7 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
return cme;
}
-const rb_callable_method_entry_t *
rb_callable_method_entry(VALUE klass, ID id)
{
VALUE defined_class;
@@ -886,7 +887,7 @@ method_entry_resolve_refinement(VALUE klass, ID id, int with_refinement, VALUE *
return me;
}
-const rb_callable_method_entry_t *
rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
{
VALUE defined_class, *dcp = defined_class_ptr ? defined_class_ptr : &defined_class;
@@ -900,7 +901,7 @@ rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr
return method_entry_resolve_refinement(klass, id, FALSE, defined_class_ptr);
}
-const rb_callable_method_entry_t *
rb_callable_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
{
VALUE defined_class, *dcp = defined_class_ptr ? defined_class_ptr : &defined_class;
@@ -1462,7 +1463,7 @@ original_method_definition(const rb_method_definition_t *def)
return def;
}
-static int
rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2)
{
d1 = original_method_definition(d1);
@@ -325,7 +325,7 @@ exec_hooks_protected(rb_execution_context_t *ec, rb_vm_t *vm, rb_hook_list_t *li
return state;
}
-void
rb_exec_event_hooks(rb_trace_arg_t *trace_arg, int pop_p)
{
rb_execution_context_t *ec = trace_arg->ec;
@@ -1192,7 +1192,7 @@ rb_mjit_header.h: PHONY probes.h
$(Q) $(IFCHANGE) $@ vm.i
INSNS = opt_sc.inc optinsn.inc optunifs.inc insns.inc insns_info.inc \
- vmtc.inc vm.inc
!if [exit > insns_rules.mk]
!else if [for %I in ($(INSNS)) do \
@@ -7,7 +7,7 @@ module RbConfig
end
class Exports
- PrivateNames = /(?:Init_|ruby_static_id_|.*_threadptr_|rb_ec_|DllMain\b)/
@@subclass = []
def self.inherited(klass)