summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rw-r--r--iseq.c23
-rwxr-xr-xtool/instruction.rb4
-rw-r--r--vm.c222
-rw-r--r--vm_dump.c139
-rw-r--r--vm_exec.h10
-rw-r--r--vm_insnhelper.h37
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 <ko1@atdot.net>
+
+ * 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 <ko1@atdot.net>
* 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 */