From 23dc0dbc4ad3354a9df899c0105c57bf42e2d243 Mon Sep 17 00:00:00 2001 From: ko1 Date: Thu, 4 Oct 2012 12:31:05 +0000 Subject: * vm.c (VM_COLLECT_USAGE_DETAILS): make new VM usage analysis hooks (old macro name is COLLECT_USAGE_ANALYSIS). This feature is only for VM developers. (I'm not sure I can use `VM developers' (the plural form) in this sentence). If VM_COLLECT_USAGE_DETAILS is not 0, VM enables the following usage collection features: (1) insntruction: collect intruction usages. (2) operand: collect operand usages. (3) register: collect register usages. The results are stored in RubyVM::USAGE_ANALYSIS_INSN for (1, 2), RubyVM::USAGE_ANALYSIS_INSN_BIGRAM for (1) and RubyVM::USAGE_ANALYSIS_REGS for (3). You can stop collecting usages with RubyVM::USAGE_ANALYSIS_INSN_STOP(), RubyVM::USAGE_ANALYSIS_OPERAND_STOP(), RubyVM::USAGE_ANALYSIS_REGISTER_STOP() for (1), (2), (3) respectively. You can also change the hook functions by setting C level global variables `ruby_vm_collect_usage_func_(insn|operand|register)' for (1), (2), (3) respectively. See codes for more details. * tool/instruction.rb: fix macro names. * iseq.c (insn_operand_intern): make it export (used in vm.c). fix to skip several processes if not needed (pointer is 0). * vm_dump.c: move codes for collection features to vm.c. * vm_exec.h: rename macro and function names. * vm_insnhelper.h: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37085 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 37 +++++++++ iseq.c | 23 ++++-- tool/instruction.rb | 4 +- vm.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++- vm_dump.c | 139 -------------------------------- vm_exec.h | 10 --- vm_insnhelper.h | 37 +++++---- 7 files changed, 295 insertions(+), 177 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74351a99e5..39da3e16e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +Thu Oct 4 21:15:26 2012 Koichi Sasada + + * vm.c (VM_COLLECT_USAGE_DETAILS): make new VM usage analysis + hooks (old macro name is COLLECT_USAGE_ANALYSIS). + This feature is only for VM developers. (I'm not sure I can use + `VM developers' (the plural form) in this sentence). + If VM_COLLECT_USAGE_DETAILS is not 0, VM enables the following + usage collection features: + (1) insntruction: collect intruction usages. + (2) operand: collect operand usages. + (3) register: collect register usages. + The results are stored in + RubyVM::USAGE_ANALYSIS_INSN for (1, 2), + RubyVM::USAGE_ANALYSIS_INSN_BIGRAM for (1) and + RubyVM::USAGE_ANALYSIS_REGS for (3). + You can stop collecting usages with + RubyVM::USAGE_ANALYSIS_INSN_STOP(), + RubyVM::USAGE_ANALYSIS_OPERAND_STOP(), + RubyVM::USAGE_ANALYSIS_REGISTER_STOP() + for (1), (2), (3) respectively. + You can also change the hook functions by setting + C level global variables + `ruby_vm_collect_usage_func_(insn|operand|register)' + for (1), (2), (3) respectively. + See codes for more details. + + * tool/instruction.rb: fix macro names. + + * iseq.c (insn_operand_intern): make it export (used in vm.c). + fix to skip several processes if not needed (pointer is 0). + + * vm_dump.c: move codes for collection features to vm.c. + + * vm_exec.h: rename macro and function names. + + * vm_insnhelper.h: ditto. + Thu Oct 4 18:59:14 2012 Koichi Sasada * test/ruby/test_settracefunc.rb (test_tracepoint): diff --git a/iseq.c b/iseq.c index e34537e871..a6f39bc1f7 100644 --- a/iseq.c +++ b/iseq.c @@ -963,7 +963,7 @@ id_to_name(ID id, VALUE default_value) return str; } -static VALUE +VALUE insn_operand_intern(rb_iseq_t *iseq, VALUE insn, int op_no, VALUE op, int len, size_t pos, VALUE *pnop, VALUE child) @@ -991,13 +991,18 @@ insn_operand_intern(rb_iseq_t *iseq, } case TS_DINDEX:{ if (insn == BIN(getdynamic) || insn == BIN(setdynamic)) { - rb_iseq_t *diseq = iseq; - VALUE level = *pnop, i; + if (pnop) { + rb_iseq_t *diseq = iseq; + VALUE level = *pnop, i; - for (i = 0; i < level; i++) { - diseq = diseq->parent_iseq; + for (i = 0; i < level; i++) { + diseq = diseq->parent_iseq; + } + ret = id_to_name(diseq->local_table[diseq->local_size - op], INT2FIX('*')); + } + else { + ret = rb_sprintf("%"PRIuVALUE, op); } - ret = id_to_name(diseq->local_table[diseq->local_size - op], INT2FIX('*')); } else { ret = rb_inspect(INT2FIX(op)); @@ -1011,7 +1016,9 @@ insn_operand_intern(rb_iseq_t *iseq, op = obj_resurrect(op); ret = rb_inspect(op); if (CLASS_OF(op) == rb_cISeq) { - rb_ary_push(child, op); + if (child) { + rb_ary_push(child, op); + } } break; @@ -1049,7 +1056,7 @@ insn_operand_intern(rb_iseq_t *iseq, break; default: - rb_bug("rb_iseq_disasm: unknown operand type: %c", type); + rb_bug("insn_operand_intern: unknown operand type: %c", type); } return ret; } diff --git a/tool/instruction.rb b/tool/instruction.rb index 9dc7604170..43b26b5c97 100755 --- a/tool/instruction.rb +++ b/tool/instruction.rb @@ -791,9 +791,9 @@ class RubyVM end def make_header_analysis insn - commit " USAGE_ANALYSIS_INSN(BIN(#{insn.name}));" + commit " COLLECT_USAGE_INSN(BIN(#{insn.name}));" insn.opes.each_with_index{|op, i| - commit " USAGE_ANALYSIS_OPERAND(BIN(#{insn.name}), #{i}, #{op[1]});" + commit " COLLECT_USAGE_OPERAND(BIN(#{insn.name}), #{i}, #{op[1]});" } end diff --git a/vm.c b/vm.c index 348d1349fa..61881a6220 100644 --- a/vm.c +++ b/vm.c @@ -61,6 +61,16 @@ rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp) return VM_CF_BLOCK_PTR(cfp); } +#ifndef VM_COLLECT_USAGE_DETAILS +#define VM_COLLECT_USAGE_DETAILS 0 +#endif + +#if VM_COLLECT_USAGE_DETAILS +static void vm_collect_usage_operand(int insn, int n, VALUE op); +static void vm_collect_usage_register(int reg, int isset); +static void vm_collect_usage_insn(int insn); +#endif + static VALUE vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class, int argc, const VALUE *argv, const rb_block_t *blockptr); @@ -91,10 +101,6 @@ rb_event_flag_t ruby_vm_event_flags; static void thread_free(void *ptr); -void vm_analysis_operand(int insn, int n, VALUE op); -void vm_analysis_register(int reg, int isset); -void vm_analysis_insn(int insn); - void rb_vm_change_state(void) { @@ -2070,6 +2076,12 @@ nsdr(void) return ary; } +#if VM_COLLECT_USAGE_DETAILS +static VALUE usage_analysis_insn_stop(VALUE self); +static VALUE usage_analysis_operand_stop(VALUE self); +static VALUE usage_analysis_register_stop(VALUE self); +#endif + void Init_VM(void) { @@ -2109,10 +2121,18 @@ Init_VM(void) rb_cThread = rb_define_class("Thread", rb_cObject); rb_undef_alloc_func(rb_cThread); +#if VM_COLLECT_USAGE_DETAILS /* ::RubyVM::USAGE_ANALYSIS_* */ rb_define_const(rb_cRubyVM, "USAGE_ANALYSIS_INSN", rb_hash_new()); rb_define_const(rb_cRubyVM, "USAGE_ANALYSIS_REGS", rb_hash_new()); rb_define_const(rb_cRubyVM, "USAGE_ANALYSIS_INSN_BIGRAM", rb_hash_new()); + + rb_define_singleton_method(rb_cRubyVM, "USAGE_ANALYSIS_INSN_STOP", usage_analysis_insn_stop, 0); + rb_define_singleton_method(rb_cRubyVM, "USAGE_ANALYSIS_OPERAND_STOP", usage_analysis_operand_stop, 0); + rb_define_singleton_method(rb_cRubyVM, "USAGE_ANALYSIS_REGISTER_STOP", usage_analysis_register_stop, 0); +#endif + + /* ::RubyVM::OPTS, which shows vm build options */ rb_define_const(rb_cRubyVM, "OPTS", opts = rb_ary_new()); #if OPT_DIRECT_THREADED_CODE @@ -2281,3 +2301,197 @@ rb_ruby_debug_ptr(void) { return ruby_vm_debug_ptr(GET_VM()); } + +#if VM_COLLECT_USAGE_DETAILS + +/* uh = { + * insn(Fixnum) => ihash(Hash) + * } + * ihash = { + * -1(Fixnum) => count, # insn usage + * 0(Fixnum) => ophash, # operand usage + * } + * ophash = { + * val(interned string) => count(Fixnum) + * } + */ +static void +vm_analysis_insn(int insn) +{ + ID usage_hash; + ID bigram_hash; + static int prev_insn = -1; + + VALUE uh; + VALUE ihash; + VALUE cv; + + CONST_ID(usage_hash, "USAGE_ANALYSIS_INSN"); + CONST_ID(bigram_hash, "USAGE_ANALYSIS_INSN_BIGRAM"); + uh = rb_const_get(rb_cRubyVM, usage_hash); + if ((ihash = rb_hash_aref(uh, INT2FIX(insn))) == Qnil) { + ihash = rb_hash_new(); + rb_hash_aset(uh, INT2FIX(insn), ihash); + } + if ((cv = rb_hash_aref(ihash, INT2FIX(-1))) == Qnil) { + cv = INT2FIX(0); + } + rb_hash_aset(ihash, INT2FIX(-1), INT2FIX(FIX2INT(cv) + 1)); + + /* calc bigram */ + if (prev_insn != -1) { + VALUE bi; + VALUE ary[2]; + VALUE cv; + + ary[0] = INT2FIX(prev_insn); + ary[1] = INT2FIX(insn); + bi = rb_ary_new4(2, &ary[0]); + + uh = rb_const_get(rb_cRubyVM, bigram_hash); + if ((cv = rb_hash_aref(uh, bi)) == Qnil) { + cv = INT2FIX(0); + } + rb_hash_aset(uh, bi, INT2FIX(FIX2INT(cv) + 1)); + } + prev_insn = insn; +} + +/* iseq.c */ +VALUE insn_operand_intern(rb_iseq_t *iseq, + VALUE insn, int op_no, VALUE op, + int len, size_t pos, VALUE *pnop, VALUE child); + +static void +vm_analysis_operand(int insn, int n, VALUE op) +{ + ID usage_hash; + + VALUE uh; + VALUE ihash; + VALUE ophash; + VALUE valstr; + VALUE cv; + + CONST_ID(usage_hash, "USAGE_ANALYSIS_INSN"); + + uh = rb_const_get(rb_cRubyVM, usage_hash); + if ((ihash = rb_hash_aref(uh, INT2FIX(insn))) == Qnil) { + ihash = rb_hash_new(); + rb_hash_aset(uh, INT2FIX(insn), ihash); + } + if ((ophash = rb_hash_aref(ihash, INT2FIX(n))) == Qnil) { + ophash = rb_hash_new(); + rb_hash_aset(ihash, INT2FIX(n), ophash); + } + /* intern */ + valstr = insn_operand_intern(GET_THREAD()->cfp->iseq, insn, n, op, 0, 0, 0, 0); + + /* set count */ + if ((cv = rb_hash_aref(ophash, valstr)) == Qnil) { + cv = INT2FIX(0); + } + rb_hash_aset(ophash, valstr, INT2FIX(FIX2INT(cv) + 1)); +} + +static void +vm_analysis_register(int reg, int isset) +{ + ID usage_hash; + VALUE uh; + VALUE valstr; + static const char regstrs[][5] = { + "pc", /* 0 */ + "sp", /* 1 */ + "ep", /* 2 */ + "cfp", /* 3 */ + "self", /* 4 */ + "iseq", /* 5 */ + }; + static const char getsetstr[][4] = { + "get", + "set", + }; + static VALUE syms[sizeof(regstrs) / sizeof(regstrs[0])][2]; + + VALUE cv; + + CONST_ID(usage_hash, "USAGE_ANALYSIS_REGS"); + if (syms[0] == 0) { + char buff[0x10]; + int i; + + for (i = 0; i < (int)(sizeof(regstrs) / sizeof(regstrs[0])); i++) { + int j; + for (j = 0; j < 2; j++) { + snprintf(buff, 0x10, "%d %s %-4s", i, getsetstr[j], regstrs[i]); + syms[i][j] = ID2SYM(rb_intern(buff)); + } + } + } + valstr = syms[reg][isset]; + + uh = rb_const_get(rb_cRubyVM, usage_hash); + if ((cv = rb_hash_aref(uh, valstr)) == Qnil) { + cv = INT2FIX(0); + } + rb_hash_aset(uh, valstr, INT2FIX(FIX2INT(cv) + 1)); +} + +void (*ruby_vm_collect_usage_func_insn)(int insn) = vm_analysis_insn; +void (*ruby_vm_collect_usage_func_operand)(int insn, int n, VALUE op) = vm_analysis_operand; +void (*ruby_vm_collect_usage_func_register)(int reg, int isset) = vm_analysis_register; + +/* :nodoc: */ +static VALUE +usage_analysis_insn_stop(VALUE self) +{ + ruby_vm_collect_usage_func_insn = 0; + return Qnil; +} + +/* :nodoc: */ +static VALUE +usage_analysis_operand_stop(VALUE self) +{ + ruby_vm_collect_usage_func_operand = 0; + return Qnil; +} + +/* :nodoc: */ +static VALUE +usage_analysis_register_stop(VALUE self) +{ + ruby_vm_collect_usage_func_register = 0; + return Qnil; +} + +/* @param insn instruction number */ +static void +vm_collect_usage_insn(int insn) +{ + if (ruby_vm_collect_usage_func_insn) + (*ruby_vm_collect_usage_func_insn)(insn); +} + +/* @param insn instruction number + * @param n n-th operand + * @param op operand value + */ +static void +vm_collect_usage_operand(int insn, int n, VALUE op) +{ + if (ruby_vm_collect_usage_func_operand) + (*ruby_vm_collect_usage_func_operand)(insn, n, op); +} + +/* @param reg register id. see code of vm_analysis_register() */ +/* @param iseset 0: read, 1: write */ +static void +vm_collect_usage_register(int reg, int isset) +{ + if (ruby_vm_collect_usage_func_register) + (*ruby_vm_collect_usage_func_register)(reg, isset); +} + +#endif diff --git a/vm_dump.c b/vm_dump.c index 10061020ce..8e005bd14e 100644 --- a/vm_dump.c +++ b/vm_dump.c @@ -395,145 +395,6 @@ rb_vmdebug_debug_print_post(rb_thread_t *th, rb_control_frame_t *cfp #endif } -#ifdef COLLECT_USAGE_ANALYSIS -/* uh = { - * insn(Fixnum) => ihash(Hash) - * } - * ihash = { - * -1(Fixnum) => count, # insn usage - * 0(Fixnum) => ophash, # operand usage - * } - * ophash = { - * val(interned string) => count(Fixnum) - * } - */ -void -vm_analysis_insn(int insn) -{ - ID usage_hash; - ID bigram_hash; - static int prev_insn = -1; - - VALUE uh; - VALUE ihash; - VALUE cv; - - CONST_ID(usage_hash, "USAGE_ANALYSIS_INSN"); - CONST_ID(bigram_hash, "USAGE_ANALYSIS_INSN_BIGRAM"); - uh = rb_const_get(rb_cRubyVM, usage_hash); - if ((ihash = rb_hash_aref(uh, INT2FIX(insn))) == Qnil) { - ihash = rb_hash_new(); - rb_hash_aset(uh, INT2FIX(insn), ihash); - } - if ((cv = rb_hash_aref(ihash, INT2FIX(-1))) == Qnil) { - cv = INT2FIX(0); - } - rb_hash_aset(ihash, INT2FIX(-1), INT2FIX(FIX2INT(cv) + 1)); - - /* calc bigram */ - if (prev_insn != -1) { - VALUE bi; - VALUE ary[2]; - VALUE cv; - - ary[0] = INT2FIX(prev_insn); - ary[1] = INT2FIX(insn); - bi = rb_ary_new4(2, &ary[0]); - - uh = rb_const_get(rb_cRubyVM, bigram_hash); - if ((cv = rb_hash_aref(uh, bi)) == Qnil) { - cv = INT2FIX(0); - } - rb_hash_aset(uh, bi, INT2FIX(FIX2INT(cv) + 1)); - } - prev_insn = insn; -} - -/* from disasm.c */ -extern VALUE insn_operand_intern(int insn, int op_no, VALUE op, - int len, int pos, VALUE child); - -void -vm_analysis_operand(int insn, int n, VALUE op) -{ - ID usage_hash; - - VALUE uh; - VALUE ihash; - VALUE ophash; - VALUE valstr; - VALUE cv; - - CONST_ID(usage_hash, "USAGE_ANALYSIS_INSN"); - - uh = rb_const_get(rb_cRubyVM, usage_hash); - if ((ihash = rb_hash_aref(uh, INT2FIX(insn))) == Qnil) { - ihash = rb_hash_new(); - rb_hash_aset(uh, INT2FIX(insn), ihash); - } - if ((ophash = rb_hash_aref(ihash, INT2FIX(n))) == Qnil) { - ophash = rb_hash_new(); - rb_hash_aset(ihash, INT2FIX(n), ophash); - } - /* intern */ - valstr = insn_operand_intern(insn, n, op, 0, 0, 0); - - /* set count */ - if ((cv = rb_hash_aref(ophash, valstr)) == Qnil) { - cv = INT2FIX(0); - } - rb_hash_aset(ophash, valstr, INT2FIX(FIX2INT(cv) + 1)); -} - -void -vm_analysis_register(int reg, int isset) -{ - ID usage_hash; - VALUE uh; - VALUE rhash; - VALUE valstr; - static const char regstrs[][5] = { - "pc", /* 0 */ - "sp", /* 1 */ - "ep", /* 2 */ - "cfp", /* 3 */ - "self", /* 4 */ - "iseq", /* 5 */ - }; - static const char getsetstr[][4] = { - "get", - "set", - }; - static VALUE syms[sizeof(regstrs) / sizeof(regstrs[0])][2]; - - VALUE cv; - - CONST_ID(usage_hash, "USAGE_ANALYSIS_REGS"); - if (syms[0] == 0) { - char buff[0x10]; - int i; - - for (i = 0; i < sizeof(regstrs) / sizeof(regstrs[0]); i++) { - int j; - for (j = 0; j < 2; j++) { - snfprintf(stderr, buff, 0x10, "%d %s %-4s", i, getsetstr[j], - regstrs[i]); - syms[i][j] = ID2SYM(rb_intern(buff)); - } - } - } - valstr = syms[reg][isset]; - - uh = rb_const_get(rb_cRubyVM, usage_hash); - if ((cv = rb_hash_aref(uh, valstr)) == Qnil) { - cv = INT2FIX(0); - } - rb_hash_aset(uh, valstr, INT2FIX(FIX2INT(cv) + 1)); -} - - -#endif - VALUE rb_vmdebug_thread_dump_state(VALUE self) { diff --git a/vm_exec.h b/vm_exec.h index 2c1e2d5527..863f7c055c 100644 --- a/vm_exec.h +++ b/vm_exec.h @@ -18,16 +18,6 @@ typedef unsigned long dindex_t; typedef rb_num_t GENTRY; typedef rb_iseq_t *ISEQ; -#ifdef COLLECT_USAGE_ANALYSIS -#define USAGE_ANALYSIS_INSN(insn) vm_analysis_insn(insn) -#define USAGE_ANALYSIS_OPERAND(insn, n, op) vm_analysis_operand((insn), (n), (VALUE)(op)) -#define USAGE_ANALYSIS_REGISTER(reg, s) vm_analysis_register((reg), (s)) -#else -#define USAGE_ANALYSIS_INSN(insn) /* none */ -#define USAGE_ANALYSIS_OPERAND(insn, n, op) /* none */ -#define USAGE_ANALYSIS_REGISTER(reg, s) /* none */ -#endif - #ifdef __GCC__ /* TODO: machine dependent prefetch instruction */ #define PREFETCH(pc) diff --git a/vm_insnhelper.h b/vm_insnhelper.h index 7c7745ae60..25459f157a 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -62,6 +62,15 @@ enum { extern char ruby_vm_redefined_flag[BOP_LAST_]; extern VALUE ruby_vm_const_missing_count; +#if VM_COLLECT_USAGE_DETAILS +#define COLLECT_USAGE_INSN(insn) vm_collect_usage_insn(insn) +#define COLLECT_USAGE_OPERAND(insn, n, op) vm_collect_usage_operand((insn), (n), ((VALUE)(op))) +#define COLLECT_USAGE_REGISTER(reg, s) vm_collect_usage_register((reg), (s)) +#else +#define COLLECT_USAGE_INSN(insn) /* none */ +#define COLLECT_USAGE_OPERAND(insn, n, op) /* none */ +#define COLLECT_USAGE_REGISTER(reg, s) /* none */ +#endif /**********************************************************/ /* deal with stack */ @@ -104,16 +113,16 @@ enum vm_regan_acttype { VM_REGAN_ACT_SET = 1, }; -#ifdef COLLECT_USAGE_ANALYSIS -#define USAGE_ANALYSIS_REGISTER_HELPER(a, b, v) \ - (USAGE_ANALYSIS_REGISTER((VM_REGAN_#a), (VM_REGAN_ACT_#b)), (v)) +#if VM_COLLECT_USAGE_DETAILS +#define COLLECT_USAGE_REGISTER_HELPER(a, b, v) \ + (COLLECT_USAGE_REGISTER((VM_REGAN_##a), (VM_REGAN_ACT_##b)), (v)) #else -#define USAGE_ANALYSIS_REGISTER_HELPER(a, b, v) (v) +#define COLLECT_USAGE_REGISTER_HELPER(a, b, v) (v) #endif /* PC */ -#define GET_PC() (USAGE_ANALYSIS_REGISTER_HELPER(PC, GET, REG_PC)) -#define SET_PC(x) (REG_PC = (USAGE_ANALYSIS_REGISTER_HELPER(PC, SET, (x)))) +#define GET_PC() (COLLECT_USAGE_REGISTER_HELPER(PC, GET, REG_PC)) +#define SET_PC(x) (REG_PC = (COLLECT_USAGE_REGISTER_HELPER(PC, SET, (x)))) #define GET_CURRENT_INSN() (*GET_PC()) #define GET_OPERAND(n) (GET_PC()[(n)]) #define ADD_PC(n) (SET_PC(REG_PC + (n))) @@ -122,16 +131,16 @@ enum vm_regan_acttype { #define JUMP(dst) (REG_PC += (dst)) /* frame pointer, environment pointer */ -#define GET_CFP() (USAGE_ANALYSIS_REGISTER_HELPER(CFP, GET, REG_CFP)) -#define GET_EP() (USAGE_ANALYSIS_REGISTER_HELPER(EP, GET, REG_EP)) -#define SET_EP(x) (REG_EP = (USAGE_ANALYSIS_REGISTER_HELPER(EP, SET, (x)))) +#define GET_CFP() (COLLECT_USAGE_REGISTER_HELPER(CFP, GET, REG_CFP)) +#define GET_EP() (COLLECT_USAGE_REGISTER_HELPER(EP, GET, REG_EP)) +#define SET_EP(x) (REG_EP = (COLLECT_USAGE_REGISTER_HELPER(EP, SET, (x)))) #define GET_LEP() (VM_EP_LEP(GET_EP())) /* SP */ -#define GET_SP() (USAGE_ANALYSIS_REGISTER_HELPER(SP, GET, REG_SP)) -#define SET_SP(x) (REG_SP = (USAGE_ANALYSIS_REGISTER_HELPER(SP, SET, (x)))) -#define INC_SP(x) (REG_SP += (USAGE_ANALYSIS_REGISTER_HELPER(SP, SET, (x)))) -#define DEC_SP(x) (REG_SP -= (USAGE_ANALYSIS_REGISTER_HELPER(SP, SET, (x)))) +#define GET_SP() (COLLECT_USAGE_REGISTER_HELPER(SP, GET, REG_SP)) +#define SET_SP(x) (REG_SP = (COLLECT_USAGE_REGISTER_HELPER(SP, SET, (x)))) +#define INC_SP(x) (REG_SP += (COLLECT_USAGE_REGISTER_HELPER(SP, SET, (x)))) +#define DEC_SP(x) (REG_SP -= (COLLECT_USAGE_REGISTER_HELPER(SP, SET, (x)))) #define SET_SV(x) (*GET_SP() = (x)) /* set current stack value as x */ @@ -155,7 +164,7 @@ enum vm_regan_acttype { /* deal with values */ /**********************************************************/ -#define GET_SELF() (USAGE_ANALYSIS_REGISTER_HELPER(5, 0, GET_CFP()->self)) +#define GET_SELF() (COLLECT_USAGE_REGISTER_HELPER(SELF, GET, GET_CFP()->self)) /**********************************************************/ /* deal with control flow 2: method/iterator */ -- cgit v1.2.1