diff options
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) |