From 4bdb5ced9a06532d33e6aa0dd6be49e863b31d22 Mon Sep 17 00:00:00 2001 From: ko1 Date: Mon, 25 Jun 2007 02:44:20 +0000 Subject: * gc.h: add RUBY_ prefix to debug macros. * cont.c, proc.c, yarvcore.c, * gc.c: define ruby_gc_debug_indent variable to debug mark/free. * vm.c, insnhelper.ci: rename some functions to vm_* or rb_vm_*. move some functions, definitions, declarations to suitable files. * eval.c, yarvcore.h, eval_error.ci, insnhelper.ci: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12610 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 13 +++ cont.c | 20 ++-- eval.c | 16 +-- eval_error.ci | 3 - eval_intern.h | 2 + gc.c | 2 + gc.h | 44 ++++---- insnhelper.ci | 175 ++++++++++++++++++++++++------- insns.def | 6 +- iseq.c | 42 ++++---- proc.c | 30 +++--- vm.c | 329 ++++++++++++++++++++++------------------------------------ yarvcore.c | 56 +++++----- yarvcore.h | 1 - 14 files changed, 379 insertions(+), 360 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4dacdaa33f..84a7cf7ef4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Mon Jun 25 11:36:35 2007 Koichi Sasada + + * gc.h: add RUBY_ prefix to debug macros. + + * cont.c, proc.c, yarvcore.c, + + * gc.c: define ruby_gc_debug_indent variable to debug mark/free. + + * vm.c, insnhelper.ci: rename some functions to vm_* or rb_vm_*. + move some functions, definitions, declarations to suitable files. + + * eval.c, yarvcore.h, eval_error.ci, insnhelper.ci: ditto. + Mon Jun 25 09:45:46 2007 Nobuyoshi Nakada * eval_error.ci, eval_jump.ci, eval_method.ci, eval_safe.ci: c-mode. diff --git a/cont.c b/cont.c index 407325d7b9..71bc4601b2 100644 --- a/cont.c +++ b/cont.c @@ -47,7 +47,7 @@ void rb_thread_mark(rb_thread_t *th); static void cont_mark(void *ptr) { - MARK_REPORT_ENTER("cont"); + RUBY_MARK_ENTER("cont"); if (ptr) { rb_context_t *cont = ptr; rb_gc_mark(cont->value); @@ -71,24 +71,24 @@ cont_mark(void *ptr) } #endif } - MARK_REPORT_LEAVE("cont"); + RUBY_MARK_LEAVE("cont"); } static void cont_free(void *ptr) { - FREE_REPORT_ENTER("cont"); + RUBY_FREE_ENTER("cont"); if (ptr) { rb_context_t *cont = ptr; - FREE_UNLESS_NULL(cont->saved_thread.stack); - FREE_UNLESS_NULL(cont->machine_stack); + RUBY_FREE_UNLESS_NULL(cont->saved_thread.stack); + RUBY_FREE_UNLESS_NULL(cont->machine_stack); #ifdef __ia64 - FREE_UNLESS_NULL(cont->machine_register_stack); + RUBY_FREE_UNLESS_NULL(cont->machine_register_stack); #endif - FREE_UNLESS_NULL(cont->vm_stack); + RUBY_FREE_UNLESS_NULL(cont->vm_stack); ruby_xfree(ptr); } - FREE_REPORT_LEAVE("cont"); + RUBY_FREE_LEAVE("cont"); } static void @@ -144,8 +144,8 @@ cont_new(VALUE klass) contval = Data_Make_Struct(klass, rb_context_t, cont_mark, cont_free, cont); - GC_INFO("cont alloc: %p (klass: %s)\n", cont, - klass == rb_cFiber ? "Fiber": "Continuation"); + RUBY_GC_INFO("cont alloc: %p (klass: %s)\n", cont, + klass == rb_cFiber ? "Fiber": "Continuation"); cont->self = contval; cont->alive = Qtrue; diff --git a/eval.c b/eval.c index 56a71f22a2..68c3721a08 100644 --- a/eval.c +++ b/eval.c @@ -29,6 +29,8 @@ static ID object_id, __send, __send_bang, respond_to; VALUE rb_eLocalJumpError; VALUE rb_eSysStackError; +VALUE exception_error; +VALUE sysstack_error; extern int ruby_nerrs; extern VALUE ruby_top_self; @@ -652,16 +654,8 @@ rb_mod_protected_method_defined(VALUE mod, VALUE mid) return Qfalse; } -NORETURN(void vm_iter_break _((rb_thread_t *))); - -void -rb_iter_break() -{ - vm_iter_break(GET_THREAD()); -} - -NORETURN(static void rb_longjmp _((int, VALUE))); -static VALUE make_backtrace _((void)); +NORETURN(static void rb_longjmp(int, VALUE)); +static VALUE make_backtrace(void); static void rb_longjmp(int tag, VALUE mesg) @@ -1700,7 +1694,7 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line) th->parse_in_eval++; iseqval = vm_compile(th, src, rb_str_new2(file), INT2FIX(line)); th->parse_in_eval--; - vm_set_eval_stack(th, iseqval); + rb_vm_set_eval_stack(th, iseqval); th->base_block = 0; if (0) { /* for debug */ diff --git a/eval_error.ci b/eval_error.ci index 07302bf374..f81ef8ffb5 100644 --- a/eval_error.ci +++ b/eval_error.ci @@ -204,9 +204,6 @@ print_undef(VALUE klass, ID id) rb_class2name(klass)); } -VALUE exception_error; -VALUE sysstack_error; - static int sysexit_status(VALUE err) { diff --git a/eval_intern.h b/eval_intern.h index 11e2255fac..45e2681763 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -229,6 +229,8 @@ void rb_vm_check_redefinition_opt_method(NODE *node); VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, rb_block_t *blockptr, VALUE filename); void rb_thread_terminate_all(void); +VALUE rb_vm_set_eval_stack(rb_thread_t *, VALUE iseq); + #define ruby_cbase() vm_get_cbase(GET_THREAD()) diff --git a/gc.c b/gc.c index 60124b7a02..83e04b2a50 100644 --- a/gc.c +++ b/gc.c @@ -84,6 +84,8 @@ static VALUE mark_stack[MARK_STACK_MAX]; static VALUE *mark_stack_ptr; static int mark_stack_overflow; +int ruby_gc_debug_indent = 0; + #undef GC_DEBUG #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__) diff --git a/gc.h b/gc.h index 0c3d351416..b0598131a0 100644 --- a/gc.h +++ b/gc.h @@ -7,52 +7,50 @@ NOINLINE(void rb_gc_save_machine_context(rb_thread_t *)); /* for GC debug */ -#ifndef MARK_FREE_DEBUG -#define MARK_FREE_DEBUG 0 +#ifndef RUBY_MARK_FREE_DEBUG +#define RUBY_MARK_FREE_DEBUG 0 #endif - -#if MARK_FREE_DEBUG -static int g_indent = 0; +#if RUBY_MARK_FREE_DEBUG +extern int ruby_gc_debug_indent = 0; static void rb_gc_debug_indent(void) { - int i; - for (i = 0; i < g_indent; i++) { - printf(" "); - } + printf("%*s", ruby_gc_debug_indent, ""); } static void rb_gc_debug_body(char *mode, char *msg, int st, void *ptr) { if (st == 0) { - g_indent--; + ruby_gc_debug_indent--; } rb_gc_debug_indent(); printf("%s: %s %s (%p)\n", mode, st ? "->" : "<-", msg, ptr); + if (st) { - g_indent++; + ruby_gc_debug_indent++; } + fflush(stdout); } -#define MARK_REPORT_ENTER(msg) rb_gc_debug_body("mark", msg, 1, ptr) -#define MARK_REPORT_LEAVE(msg) rb_gc_debug_body("mark", msg, 0, ptr) -#define FREE_REPORT_ENTER(msg) rb_gc_debug_body("free", msg, 1, ptr) -#define FREE_REPORT_LEAVE(msg) rb_gc_debug_body("free", msg, 0, ptr) -#define GC_INFO rb_gc_debug_indent(); printf +#define RUBY_MARK_ENTER(msg) rb_gc_debug_body("mark", msg, 1, ptr) +#define RUBY_MARK_LEAVE(msg) rb_gc_debug_body("mark", msg, 0, ptr) +#define RUBY_FREE_ENTER(msg) rb_gc_debug_body("free", msg, 1, ptr) +#define RUBY_FREE_LEAVE(msg) rb_gc_debug_body("free", msg, 0, ptr) +#define RUBY_GC_INFO rb_gc_debug_indent(); printf #else -#define MARK_REPORT_ENTER(msg) -#define MARK_REPORT_LEAVE(msg) -#define FREE_REPORT_ENTER(msg) -#define FREE_REPORT_LEAVE(msg) -#define GC_INFO if(0)printf +#define RUBY_MARK_ENTER(msg) +#define RUBY_MARK_LEAVE(msg) +#define RUBY_FREE_ENTER(msg) +#define RUBY_FREE_LEAVE(msg) +#define RUBY_GC_INFO if(0)printf #endif -#define MARK_UNLESS_NULL(ptr) if(ptr){rb_gc_mark(ptr);} -#define FREE_UNLESS_NULL(ptr) if(ptr){ruby_xfree(ptr);} +#define RUBY_MARK_UNLESS_NULL(ptr) if(RTEST(ptr)){rb_gc_mark(ptr);} +#define RUBY_FREE_UNLESS_NULL(ptr) if(ptr){ruby_xfree(ptr);} #endif /* RUBY_GC_H */ diff --git a/insnhelper.ci b/insnhelper.ci index 02489f7dc3..8cb5eb5415 100644 --- a/insnhelper.ci +++ b/insnhelper.ci @@ -561,6 +561,124 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, return val; } +/* yield */ + +static inline VALUE +vm_yield_with_cfunc(rb_thread_t *th, rb_block_t *block, + VALUE self, int argc, VALUE *argv) +{ + NODE *ifunc = (NODE *) block->iseq; + VALUE val; + VALUE arg; + + if (argc == 1) { + arg = *argv; + } + else if (argc > 1) { + arg = rb_ary_new4(argc, argv); + } + else { + arg = rb_ary_new(); + } + + vm_push_frame(th, 0, FRAME_MAGIC_IFUNC, + self, (VALUE)block->dfp, + 0, th->cfp->sp, block->lfp, 1); + + val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, Qnil); + + th->cfp++; + return val; +} + +static inline int +vm_yield_setup_args(rb_thread_t *th, rb_iseq_t *iseq, + int argc, VALUE *argv, int lambda) +{ + int i, arg_n = iseq->argc + (iseq->arg_rest == -1 ? 0 : 1); + th->mark_stack_len = argc; + + if (0) { /* for debug */ + int i; + GET_THREAD()->cfp->sp += argc; + for(i=0; iargc); + printf("iseq rest: %d\n", iseq->arg_rest); + printf("iseq blck: %d\n", iseq->arg_block); + printf(" lambda: %s\n", lambda ? "true" : "false"); + GET_THREAD()->cfp->sp -= argc; + } + + if (lambda == 0 && argc == 1 && TYPE(argv[0]) == T_ARRAY && arg_n != 1) { + VALUE ary = argv[0]; + th->mark_stack_len = argc = RARRAY_LEN(ary); + + CHECK_STACK_OVERFLOW(th->cfp, argc); + + for (i=0; iarg_rest == -1) { + + if (iseq->argc < argc) { + if (lambda) { + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", + argc, iseq->argc); + } + else { + /* simple truncate */ + th->mark_stack_len = argc = iseq->argc; + } + } + else if (iseq->argc > argc) { + if (lambda) { + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", + argc, iseq->argc); + } + } + } + else { + int r = iseq->arg_rest; + + if (argc < r) { + if (lambda) { + rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", + argc, iseq->argc); + } + else { + for (i=argc; imark_stack_len = argc = iseq->arg_rest + 1; + } + + if (iseq->arg_block != -1) { + VALUE proc = Qnil; + + if (rb_block_given_p()) { + proc = rb_block_proc(); + } + + argv[iseq->arg_block] = proc; + th->mark_stack_len = argc = iseq->arg_block + 1; + } + + th->mark_stack_len = 0; + return argc; +} + /* cref */ static NODE * @@ -575,22 +693,6 @@ lfp_get_special_cref(VALUE *lfp) } } -static void -check_svar(void) -{ - rb_thread_t *th = GET_THREAD(); - rb_control_frame_t *cfp = th->cfp; - while ((void *)(cfp + 1) < (void *)(th->stack + th->stack_size)) { - /* printf("cfp: %p\n", cfp->magic); */ - if (cfp->lfp && cfp->lfp[-1] != Qnil && - TYPE(cfp->lfp[-1]) != T_VALUES) { - /* dp(cfp->lfp[-1]); */ - rb_bug("!!!illegal svar!!!"); - } - cfp++; - } -} - static struct RValues * new_value(void) { @@ -640,28 +742,6 @@ lfp_svar(VALUE *lfp, int cnt) } } -static NODE * -lfp_set_special_cref(VALUE *lfp, NODE * cref) -{ - struct RValues *values = (void *) lfp[-1]; - VALUE *pv; - NODE *old_cref; - - if (VMDEBUG) { - check_svar(); - } - - if (cref == 0 && ((VALUE)values == Qnil || values->basic.klass == 0)) { - old_cref = 0; - } - else { - pv = lfp_svar(lfp, -1); - old_cref = (NODE *) * pv; - *pv = (VALUE)cref; - } - return old_cref; -} - static NODE * get_cref(rb_iseq_t *iseq, VALUE *lfp) { @@ -827,6 +907,25 @@ vm_method_search(VALUE id, VALUE klass, IC ic) return mn; } +static VALUE +vm_search_super_klass(VALUE klass, VALUE recv) +{ + if (BUILTIN_TYPE(klass) == T_CLASS) { + klass = RCLASS(klass)->super; + } + else if (BUILTIN_TYPE(klass) == T_MODULE) { + VALUE k = CLASS_OF(recv); + while (k) { + if (BUILTIN_TYPE(k) == T_ICLASS && RBASIC(k)->klass == klass) { + klass = RCLASS(k)->super; + break; + } + k = RCLASS(k)->super; + } + } + return klass; +} + static inline int block_proc_is_lambda(VALUE procval) { diff --git a/insns.def b/insns.def index 7487b6c2bd..2fa8f1fae3 100644 --- a/insns.def +++ b/insns.def @@ -962,7 +962,7 @@ defined ip = ip->parent_iseq; } if (ip) { - VALUE klass = search_super_klass(ip->klass, GET_SELF()); + VALUE klass = vm_search_super_klass(ip->klass, GET_SELF()); if (rb_method_boundp(klass, ip->defined_method_id, 0)) { expr_type = "super"; } @@ -1254,7 +1254,7 @@ invokesuper } id = lcfp->method_id; - klass = search_super_klass(lcfp->method_klass, recv); + klass = vm_search_super_klass(lcfp->method_klass, recv); if (TOPN(num) == Qfalse) { /* zsuper */ @@ -1262,7 +1262,7 @@ invokesuper } } else { - klass = search_super_klass(ip->klass, recv); + klass = vm_search_super_klass(ip->klass, recv); } flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT; diff --git a/iseq.c b/iseq.c index b1f7ba2204..2c4d40cd94 100644 --- a/iseq.c +++ b/iseq.c @@ -41,7 +41,7 @@ static void iseq_free(void *ptr) { rb_iseq_t *iseq; - FREE_REPORT_ENTER("iseq"); + RUBY_FREE_ENTER("iseq"); if (ptr) { iseq = ptr; @@ -50,44 +50,44 @@ iseq_free(void *ptr) * RSTRING_PTR(iseq->filename)); */ if (iseq->iseq != iseq->iseq_encoded) { - FREE_UNLESS_NULL(iseq->iseq_encoded); + RUBY_FREE_UNLESS_NULL(iseq->iseq_encoded); } - FREE_UNLESS_NULL(iseq->iseq); - FREE_UNLESS_NULL(iseq->insn_info_tbl); - FREE_UNLESS_NULL(iseq->local_table); - FREE_UNLESS_NULL(iseq->catch_table); - FREE_UNLESS_NULL(iseq->arg_opt_tbl); + RUBY_FREE_UNLESS_NULL(iseq->iseq); + RUBY_FREE_UNLESS_NULL(iseq->insn_info_tbl); + RUBY_FREE_UNLESS_NULL(iseq->local_table); + RUBY_FREE_UNLESS_NULL(iseq->catch_table); + RUBY_FREE_UNLESS_NULL(iseq->arg_opt_tbl); compile_data_free(iseq->compile_data); ruby_xfree(ptr); } - FREE_REPORT_LEAVE("iseq"); + RUBY_FREE_LEAVE("iseq"); } static void iseq_mark(void *ptr) { rb_iseq_t *iseq; - MARK_REPORT_ENTER("iseq"); + RUBY_MARK_ENTER("iseq"); if (ptr) { iseq = ptr; - GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->name), RSTRING_PTR(iseq->filename)); - MARK_UNLESS_NULL(iseq->iseq_mark_ary); - MARK_UNLESS_NULL(iseq->name); - MARK_UNLESS_NULL(iseq->filename); - MARK_UNLESS_NULL((VALUE)iseq->cref_stack); - MARK_UNLESS_NULL(iseq->klass); - MARK_UNLESS_NULL((VALUE)iseq->node); - MARK_UNLESS_NULL(iseq->cached_special_block); + RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->name), RSTRING_PTR(iseq->filename)); + RUBY_MARK_UNLESS_NULL(iseq->iseq_mark_ary); + RUBY_MARK_UNLESS_NULL(iseq->name); + RUBY_MARK_UNLESS_NULL(iseq->filename); + RUBY_MARK_UNLESS_NULL((VALUE)iseq->cref_stack); + RUBY_MARK_UNLESS_NULL(iseq->klass); + RUBY_MARK_UNLESS_NULL((VALUE)iseq->node); + RUBY_MARK_UNLESS_NULL(iseq->cached_special_block); if (iseq->compile_data != 0) { - MARK_UNLESS_NULL(iseq->compile_data->mark_ary); - MARK_UNLESS_NULL(iseq->compile_data->err_info); - MARK_UNLESS_NULL(iseq->compile_data->catch_table_ary); + RUBY_MARK_UNLESS_NULL(iseq->compile_data->mark_ary); + RUBY_MARK_UNLESS_NULL(iseq->compile_data->err_info); + RUBY_MARK_UNLESS_NULL(iseq->compile_data->catch_table_ary); } } - MARK_REPORT_LEAVE("iseq"); + RUBY_MARK_LEAVE("iseq"); } static VALUE diff --git a/proc.c b/proc.c index cb53a0f8ca..8d6ec0e8cd 100644 --- a/proc.c +++ b/proc.c @@ -34,29 +34,29 @@ static VALUE rb_obj_is_method(VALUE m); static void proc_free(void *ptr) { - FREE_REPORT_ENTER("proc"); + RUBY_FREE_ENTER("proc"); if (ptr) { ruby_xfree(ptr); } - FREE_REPORT_LEAVE("proc"); + RUBY_FREE_LEAVE("proc"); } static void proc_mark(void *ptr) { rb_proc_t *proc; - MARK_REPORT_ENTER("proc"); + RUBY_MARK_ENTER("proc"); if (ptr) { proc = ptr; - MARK_UNLESS_NULL(proc->envval); - MARK_UNLESS_NULL(proc->blockprocval); - MARK_UNLESS_NULL((VALUE)proc->special_cref_stack); - MARK_UNLESS_NULL(proc->block.proc); + RUBY_MARK_UNLESS_NULL(proc->envval); + RUBY_MARK_UNLESS_NULL(proc->blockprocval); + RUBY_MARK_UNLESS_NULL((VALUE)proc->special_cref_stack); + RUBY_MARK_UNLESS_NULL(proc->block.proc); if (proc->block.iseq && RUBY_VM_IFUNC_P(proc->block.iseq)) { - MARK_UNLESS_NULL((VALUE)(proc->block.iseq)); + RUBY_MARK_UNLESS_NULL((VALUE)(proc->block.iseq)); } } - MARK_REPORT_LEAVE("proc"); + RUBY_MARK_LEAVE("proc"); } static VALUE @@ -126,25 +126,25 @@ static void binding_free(void *ptr) { rb_binding_t *bind; - FREE_REPORT_ENTER("binding"); + RUBY_FREE_ENTER("binding"); if (ptr) { bind = ptr; ruby_xfree(ptr); } - FREE_REPORT_LEAVE("binding"); + RUBY_FREE_LEAVE("binding"); } static void binding_mark(void *ptr) { rb_binding_t *bind; - MARK_REPORT_ENTER("binding"); + RUBY_MARK_ENTER("binding"); if (ptr) { bind = ptr; - MARK_UNLESS_NULL(bind->env); - MARK_UNLESS_NULL((VALUE)bind->cref_stack); + RUBY_MARK_UNLESS_NULL(bind->env); + RUBY_MARK_UNLESS_NULL((VALUE)bind->cref_stack); } - MARK_REPORT_LEAVE("binding"); + RUBY_MARK_LEAVE("binding"); } static VALUE diff --git a/vm.c b/vm.c index 687f30e93a..59ca0ee6c6 100644 --- a/vm.c +++ b/vm.c @@ -45,8 +45,9 @@ rb_vm_change_state(void) } /* control stack frame */ -VALUE -vm_set_finish_env(rb_thread_t *th) + +static inline VALUE +rb_vm_set_finish_env(rb_thread_t *th) { vm_push_frame(th, 0, FRAME_MAGIC_FINISH, Qnil, th->cfp->lfp[0], 0, @@ -55,8 +56,8 @@ vm_set_finish_env(rb_thread_t *th) return Qtrue; } -void -vm_set_top_stack(rb_thread_t *th, VALUE iseqval) +static void +rb_vm_set_top_stack(rb_thread_t *th, VALUE iseqval) { rb_iseq_t *iseq; GetISeqPtr(iseqval, iseq); @@ -66,7 +67,7 @@ vm_set_top_stack(rb_thread_t *th, VALUE iseqval) } /* for return */ - vm_set_finish_env(th); + rb_vm_set_finish_env(th); vm_push_frame(th, iseq, FRAME_MAGIC_TOP, th->top_self, 0, iseq->iseq_encoded, @@ -74,63 +75,62 @@ vm_set_top_stack(rb_thread_t *th, VALUE iseqval) } VALUE -vm_set_eval_stack(rb_thread_t *th, VALUE iseqval) +rb_vm_set_eval_stack(rb_thread_t *th, VALUE iseqval) { rb_iseq_t *iseq; rb_block_t *block = th->base_block; GetISeqPtr(iseqval, iseq); /* for return */ - vm_set_finish_env(th); + rb_vm_set_finish_env(th); vm_push_frame(th, iseq, FRAME_MAGIC_EVAL, block->self, GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded, th->cfp->sp, block->lfp, iseq->local_size); return 0; } - /* Env */ static void env_free(void *ptr) { rb_env_t *env; - FREE_REPORT_ENTER("env"); + RUBY_FREE_ENTER("env"); if (ptr) { env = ptr; - FREE_UNLESS_NULL(env->env); + RUBY_FREE_UNLESS_NULL(env->env); ruby_xfree(ptr); } - FREE_REPORT_LEAVE("env"); + RUBY_FREE_LEAVE("env"); } static void env_mark(void *ptr) { rb_env_t *env; - MARK_REPORT_ENTER("env"); + RUBY_MARK_ENTER("env"); if (ptr) { env = ptr; if (env->env) { /* TODO: should mark more restricted range */ - GC_INFO("env->env\n"); + RUBY_GC_INFO("env->env\n"); rb_gc_mark_locations(env->env, env->env + env->env_size); } - GC_INFO("env->prev_envval\n"); - MARK_UNLESS_NULL(env->prev_envval); - MARK_UNLESS_NULL(env->block.proc); + RUBY_GC_INFO("env->prev_envval\n"); + RUBY_MARK_UNLESS_NULL(env->prev_envval); + RUBY_MARK_UNLESS_NULL(env->block.proc); if (env->block.iseq) { if (BUILTIN_TYPE(env->block.iseq) == T_NODE) { - MARK_UNLESS_NULL((VALUE)env->block.iseq); + RUBY_MARK_UNLESS_NULL((VALUE)env->block.iseq); } else { - MARK_UNLESS_NULL(env->block.iseq->self); + RUBY_MARK_UNLESS_NULL(env->block.iseq->self); } } } - MARK_REPORT_LEAVE("env"); + RUBY_MARK_LEAVE("env"); } static VALUE @@ -145,7 +145,41 @@ env_alloc(void) return obj; } -static int check_env(rb_env_t *env); +static VALUE check_env_value(VALUE envval); + +static int +check_env(rb_env_t *env) +{ + printf("---\n"); + printf("envptr: %p\n", &env->block.dfp[0]); + printf("orphan: %p\n", (void *)env->block.dfp[1]); + printf("inheap: %p\n", (void *)env->block.dfp[2]); + printf("envval: %10p ", (void *)env->block.dfp[3]); + dp(env->block.dfp[3]); + printf("penvv : %10p ", (void *)env->block.dfp[4]); + dp(env->block.dfp[4]); + printf("lfp: %10p\n", env->block.lfp); + printf("dfp: %10p\n", env->block.dfp); + if (env->block.dfp[4]) { + printf(">>\n"); + check_env_value(env->block.dfp[4]); + printf("<<\n"); + } + return 1; +} + +static VALUE +check_env_value(VALUE envval) +{ + rb_env_t *env; + GetEnvPtr(envval, env); + + if (check_env(env)) { + return envval; + } + rb_bug("invalid env\n"); + return Qnil; /* unreachable */ +} static VALUE vm_make_env_each(rb_thread_t *th, rb_control_frame_t *cfp, @@ -239,42 +273,6 @@ vm_make_env_each(rb_thread_t *th, rb_control_frame_t *cfp, return envval; } -static VALUE check_env_value(VALUE envval); - -static int -check_env(rb_env_t *env) -{ - printf("---\n"); - printf("envptr: %p\n", &env->block.dfp[0]); - printf("orphan: %p\n", (void *)env->block.dfp[1]); - printf("inheap: %p\n", (void *)env->block.dfp[2]); - printf("envval: %10p ", (void *)env->block.dfp[3]); - dp(env->block.dfp[3]); - printf("penvv : %10p ", (void *)env->block.dfp[4]); - dp(env->block.dfp[4]); - printf("lfp: %10p\n", env->block.lfp); - printf("dfp: %10p\n", env->block.dfp); - if (env->block.dfp[4]) { - printf(">>\n"); - check_env_value(env->block.dfp[4]); - printf("<<\n"); - } - return 1; -} - -static VALUE -check_env_value(VALUE envval) -{ - rb_env_t *env; - GetEnvPtr(envval, env); - - if (check_env(env)) { - return envval; - } - rb_bug("invalid env\n"); - return Qnil; /* unreachable */ -} - static int collect_local_variables_in_env(rb_env_t *env, VALUE ary) { @@ -313,11 +311,12 @@ VALUE vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp) { VALUE envval; - // SDR2(cfp); + envval = vm_make_env_each(th, cfp, cfp->dfp, cfp->lfp); if (PROCDEBUG) { check_env_value(envval); } + return envval; } @@ -331,6 +330,8 @@ vm_stack_to_heap(rb_thread_t *th) } } +/* Proc */ + static VALUE vm_make_proc_from_block(rb_thread_t *th, rb_control_frame_t *cfp, rb_block_t *block) @@ -396,6 +397,8 @@ vm_make_proc(rb_thread_t *th, return procval; } +/* C -> Ruby: method */ + VALUE vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, VALUE id, ID oid, int argc, const VALUE *argv, @@ -418,7 +421,7 @@ vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, rb_control_frame_t *reg_cfp; int i; - vm_set_finish_env(th); + rb_vm_set_finish_env(th); reg_cfp = th->cfp; CHECK_STACK_OVERFLOW(reg_cfp, argc); @@ -483,25 +486,6 @@ vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, return val; } -static VALUE -search_super_klass(VALUE klass, VALUE recv) -{ - if (BUILTIN_TYPE(klass) == T_CLASS) { - klass = RCLASS(klass)->super; - } - else if (BUILTIN_TYPE(klass) == T_MODULE) { - VALUE k = CLASS_OF(recv); - while (k) { - if (BUILTIN_TYPE(k) == T_ICLASS && RBASIC(k)->klass == klass) { - klass = RCLASS(k)->super; - break; - } - k = RCLASS(k)->super; - } - } - return klass; -} - static VALUE vm_call_super(rb_thread_t *th, int argc, const VALUE *argv) { @@ -517,7 +501,7 @@ vm_call_super(rb_thread_t *th, int argc, const VALUE *argv) klass = RCLASS(klass)->super; if (klass == 0) { - klass = search_super_klass(cfp->method_klass, recv); + klass = vm_search_super_klass(cfp->method_klass, recv); } id = cfp->method_id; @@ -547,121 +531,7 @@ rb_call_super(int argc, const VALUE *argv) return vm_call_super(GET_THREAD(), argc, argv); } -static inline VALUE -vm_yield_with_cfunc(rb_thread_t *th, rb_block_t *block, - VALUE self, int argc, VALUE *argv) -{ - NODE *ifunc = (NODE *) block->iseq; - VALUE val; - VALUE arg; - - if (argc == 1) { - arg = *argv; - } - else if (argc > 1) { - arg = rb_ary_new4(argc, argv); - } - else { - arg = rb_ary_new(); - } - - vm_push_frame(th, 0, FRAME_MAGIC_IFUNC, - self, (VALUE)block->dfp, - 0, th->cfp->sp, block->lfp, 1); - - val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, Qnil); - - th->cfp++; - return val; -} - -static inline int -vm_yield_setup_args(rb_thread_t *th, rb_iseq_t *iseq, - int argc, VALUE *argv, int lambda) -{ - int i, arg_n = iseq->argc + (iseq->arg_rest == -1 ? 0 : 1); - th->mark_stack_len = argc; - - if (0) { /* for debug */ - int i; - GET_THREAD()->cfp->sp += argc; - for(i=0; iargc); - printf("iseq rest: %d\n", iseq->arg_rest); - printf("iseq blck: %d\n", iseq->arg_block); - printf(" lambda: %s\n", lambda ? "true" : "false"); - GET_THREAD()->cfp->sp -= argc; - } - - if (lambda == 0 && argc == 1 && TYPE(argv[0]) == T_ARRAY && arg_n != 1) { - VALUE ary = argv[0]; - th->mark_stack_len = argc = RARRAY_LEN(ary); - - CHECK_STACK_OVERFLOW(th->cfp, argc); - - for (i=0; iarg_rest == -1) { - - if (iseq->argc < argc) { - if (lambda) { - rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", - argc, iseq->argc); - } - else { - /* simple truncate */ - th->mark_stack_len = argc = iseq->argc; - } - } - else if (iseq->argc > argc) { - if (lambda) { - rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", - argc, iseq->argc); - } - } - } - else { - int r = iseq->arg_rest; - - if (argc < r) { - if (lambda) { - rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", - argc, iseq->argc); - } - else { - for (i=argc; imark_stack_len = argc = iseq->arg_rest + 1; - } - - if (iseq->arg_block != -1) { - VALUE proc = Qnil; - - if (rb_block_given_p()) { - proc = rb_block_proc(); - } - - argv[iseq->arg_block] = proc; - th->mark_stack_len = argc = iseq->arg_block + 1; - } - - th->mark_stack_len = 0; - return argc; -} +/* C -> Ruby: block */ static VALUE invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self, int argc, VALUE *argv) @@ -673,7 +543,7 @@ invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self, int argc, VALUE *ar int magic = block_proc_is_lambda(block->proc) ? FRAME_MAGIC_LAMBDA : FRAME_MAGIC_BLOCK; - vm_set_finish_env(th); + rb_vm_set_finish_env(th); CHECK_STACK_OVERFLOW(th->cfp, argc); CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max); @@ -757,6 +627,8 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, return val; } +/* special variable */ + VALUE * vm_cfp_svar(rb_control_frame_t *cfp, int cnt) { @@ -813,6 +685,8 @@ rb_lastline_set(VALUE val) *var = val; } +/* backtrace */ + int vm_get_sourceline(rb_control_frame_t *cfp) { @@ -894,15 +768,45 @@ vm_backtrace(rb_thread_t *th, int lev) return ary; } -VALUE -thread_backtrace(VALUE self, int level) +/* cref */ + +static void +check_svar(void) { - rb_thread_t *th; - GetThreadPtr(self, th); - return vm_backtrace(th, level); + rb_thread_t *th = GET_THREAD(); + rb_control_frame_t *cfp = th->cfp; + while ((void *)(cfp + 1) < (void *)(th->stack + th->stack_size)) { + /* printf("cfp: %p\n", cfp->magic); */ + if (cfp->lfp && cfp->lfp[-1] != Qnil && + TYPE(cfp->lfp[-1]) != T_VALUES) { + /* dp(cfp->lfp[-1]); */ + rb_bug("!!!illegal svar!!!"); + } + cfp++; + } } -/* cref */ +static NODE * +lfp_set_special_cref(VALUE *lfp, NODE * cref) +{ + struct RValues *values = (void *) lfp[-1]; + VALUE *pv; + NODE *old_cref; + + if (VMDEBUG) { + check_svar(); + } + + if (cref == 0 && ((VALUE)values == Qnil || values->basic.klass == 0)) { + old_cref = 0; + } + else { + pv = lfp_svar(lfp, -1); + old_cref = (NODE *) * pv; + *pv = (VALUE)cref; + } + return old_cref; +} NODE * vm_set_special_cref(rb_thread_t *th, VALUE *lfp, NODE * cref_stack) @@ -956,8 +860,7 @@ vm_get_cbase(rb_thread_t *th) return klass; } -/*********************************************************/ -/*********************************************************/ +/* jump */ static VALUE make_localjump_error(const char *mesg, VALUE value, int reason) @@ -1040,7 +943,9 @@ vm_jump_tag_but_local_jump(int state, VALUE val) JUMP_TAG(state); } -void +NORETURN(static void vm_iter_break(rb_thread_t *th)); + +static void vm_iter_break(rb_thread_t *th) { rb_control_frame_t *cfp = th->cfp; @@ -1051,6 +956,14 @@ vm_iter_break(rb_thread_t *th) TH_JUMP_TAG(th, TAG_BREAK); } +void +rb_iter_break() +{ + vm_iter_break(GET_THREAD()); +} + +/* optimization: redefine management */ + VALUE ruby_vm_redefined_flag = 0; static st_table *vm_opt_method_table = 0; @@ -1080,7 +993,7 @@ add_opt_method(VALUE klass, ID mid, VALUE bop) void yarv_init_redefined_flag(void) { - VALUE register_info[] = { + const VALUE register_info[] = { idPLUS, BOP_PLUS, rb_cFixnum, rb_cFloat, rb_cString, rb_cArray, 0, idMINUS, BOP_MINUS, rb_cFixnum, 0, idMULT, BOP_MULT, rb_cFixnum, rb_cFloat, 0, @@ -1098,7 +1011,7 @@ yarv_init_redefined_flag(void) idGE, BOP_GE, rb_cFixnum, 0, 0, }; - VALUE *ptr = register_info; + const VALUE *ptr = register_info; vm_opt_method_table = st_init_numtable(); while (*ptr) { @@ -1112,7 +1025,7 @@ yarv_init_redefined_flag(void) } } - +/* evaluator body */ #include "vm_evalbody.ci" @@ -1428,13 +1341,15 @@ vm_eval_body(rb_thread_t *th) return result; } +/* misc */ + VALUE rb_thread_eval(rb_thread_t *th, VALUE iseqval) { VALUE val; volatile VALUE tmp; - vm_set_top_stack(th, iseqval); + rb_vm_set_top_stack(th, iseqval); if (!rb_const_defined(rb_cObject, rb_intern("TOPLEVEL_BINDING"))) { rb_define_global_const("TOPLEVEL_BINDING", rb_binding_new()); diff --git a/yarvcore.c b/yarvcore.c index e297f69f5d..e4e93aa0e4 100644 --- a/yarvcore.c +++ b/yarvcore.c @@ -146,7 +146,7 @@ void native_thread_cleanup(void *); static void vm_free(void *ptr) { - FREE_REPORT_ENTER("vm"); + RUBY_FREE_ENTER("vm"); if (ptr) { rb_vm_t *vmobj = ptr; @@ -156,7 +156,7 @@ vm_free(void *ptr) /* ruby_xfree(ptr); */ /* ruby_current_vm = 0; */ } - FREE_REPORT_LEAVE("vm"); + RUBY_FREE_LEAVE("vm"); } static int @@ -179,17 +179,17 @@ mark_event_hooks(rb_event_hook_t *hook) static void vm_mark(void *ptr) { - MARK_REPORT_ENTER("vm"); - GC_INFO("-------------------------------------------------\n"); + RUBY_MARK_ENTER("vm"); + RUBY_GC_INFO("-------------------------------------------------\n"); if (ptr) { rb_vm_t *vm = ptr; if (vm->living_threads) { st_foreach(vm->living_threads, vm_mark_each_thread_func, 0); } - MARK_UNLESS_NULL(vm->thgroup_default); - MARK_UNLESS_NULL(vm->mark_object_ary); - MARK_UNLESS_NULL(vm->last_status); - MARK_UNLESS_NULL(vm->loaded_features); + RUBY_MARK_UNLESS_NULL(vm->thgroup_default); + RUBY_MARK_UNLESS_NULL(vm->mark_object_ary); + RUBY_MARK_UNLESS_NULL(vm->last_status); + RUBY_MARK_UNLESS_NULL(vm->loaded_features); if (vm->loading_table) { rb_mark_tbl(vm->loading_table); @@ -198,7 +198,7 @@ vm_mark(void *ptr) mark_event_hooks(vm->event_hooks); } - MARK_REPORT_LEAVE("vm"); + RUBY_MARK_LEAVE("vm"); } void @@ -221,13 +221,13 @@ static void thread_free(void *ptr) { rb_thread_t *th; - FREE_REPORT_ENTER("thread"); + RUBY_FREE_ENTER("thread"); if (ptr) { th = ptr; if (!th->root_fiber) { - FREE_UNLESS_NULL(th->stack); + RUBY_FREE_UNLESS_NULL(th->stack); } if (th->local_storage) { @@ -247,13 +247,13 @@ thread_free(void *ptr) #endif if (th->vm->main_thread == th) { - GC_INFO("main thread\n"); + RUBY_GC_INFO("main thread\n"); } else { ruby_xfree(ptr); } } - FREE_REPORT_LEAVE("thread"); + RUBY_FREE_LEAVE("thread"); } void yarv_machine_stack_mark(rb_thread_t *th); @@ -262,7 +262,7 @@ void rb_thread_mark(void *ptr) { rb_thread_t *th = NULL; - MARK_REPORT_ENTER("thread"); + RUBY_MARK_ENTER("thread"); if (ptr) { th = ptr; if (th->stack) { @@ -282,18 +282,18 @@ rb_thread_mark(void *ptr) } /* mark ruby objects */ - MARK_UNLESS_NULL(th->first_proc); - MARK_UNLESS_NULL(th->first_args); - - MARK_UNLESS_NULL(th->thgroup); - MARK_UNLESS_NULL(th->value); - MARK_UNLESS_NULL(th->errinfo); - MARK_UNLESS_NULL(th->thrown_errinfo); - MARK_UNLESS_NULL(th->local_svar); - MARK_UNLESS_NULL(th->top_self); - MARK_UNLESS_NULL(th->top_wrapper); - MARK_UNLESS_NULL(th->fiber); - MARK_UNLESS_NULL(th->root_fiber); + RUBY_MARK_UNLESS_NULL(th->first_proc); + RUBY_MARK_UNLESS_NULL(th->first_args); + + RUBY_MARK_UNLESS_NULL(th->thgroup); + RUBY_MARK_UNLESS_NULL(th->value); + RUBY_MARK_UNLESS_NULL(th->errinfo); + RUBY_MARK_UNLESS_NULL(th->thrown_errinfo); + RUBY_MARK_UNLESS_NULL(th->local_svar); + RUBY_MARK_UNLESS_NULL(th->top_self); + RUBY_MARK_UNLESS_NULL(th->top_wrapper); + RUBY_MARK_UNLESS_NULL(th->fiber); + RUBY_MARK_UNLESS_NULL(th->root_fiber); rb_mark_tbl(th->local_storage); @@ -307,8 +307,8 @@ rb_thread_mark(void *ptr) mark_event_hooks(th->event_hooks); } - MARK_UNLESS_NULL(th->stat_insn_usage); - MARK_REPORT_LEAVE("thread"); + RUBY_MARK_UNLESS_NULL(th->stat_insn_usage); + RUBY_MARK_LEAVE("thread"); } static VALUE diff --git a/yarvcore.h b/yarvcore.h index 3a23cd81ca..85842a00a4 100644 --- a/yarvcore.h +++ b/yarvcore.h @@ -663,7 +663,6 @@ void rb_disable_interrupt(void); int rb_thread_method_id_and_klass(rb_thread_t *th, ID *idp, VALUE *klassp); VALUE vm_eval_body(rb_thread_t *th); -VALUE vm_set_eval_stack(rb_thread_t *, VALUE iseq); VALUE vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, int argc, VALUE *argv); VALUE vm_make_proc(rb_thread_t *th, rb_control_frame_t *cfp, rb_block_t *block); VALUE vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp); -- cgit v1.2.3