yarv-diff:325
From: ko1 atdot.net
Date: 25 Apr 2006 13:34:51 -0000
Subject: [yarv-diff:325] r492 - trunk
Author: ko1
Date: 2006-04-25 22:34:50 +0900 (Tue, 25 Apr 2006)
New Revision: 492
Modified:
trunk/ChangeLog
trunk/eval.c
trunk/insnhelper.h
trunk/insns.def
trunk/vm.c
trunk/vm_dump.c
trunk/vm_macro.def
trunk/yarvcore.c
trunk/yarvcore.h
Log:
* yarvcore.h : remove struct yarv_cmethod_info, add
data structure for profiling and extend yarv_control_frame_t
* vm.c : make pop_frame() and apply above change
* eval.c : ditto
* vm_dump.c : ditto
* vm_macro.def : ditto
* insns.def (leave): use pop_frame() instead of
POP_CONTROL_STACK_FRAME() macro
* insnhelper.h : remove some macros
* yarvcore.c : change th_set_top_stack() prototype
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-04-18 09:38:38 UTC (rev 491)
+++ trunk/ChangeLog 2006-04-25 13:34:50 UTC (rev 492)
@@ -4,6 +4,27 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-04-25(Tue) 22:30:14 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * yarvcore.h : remove struct yarv_cmethod_info, add
+ data structure for profiling and extend yarv_control_frame_t
+
+ * vm.c : make pop_frame() and apply above change
+
+ * eval.c : ditto
+
+ * vm_dump.c : ditto
+
+ * vm_macro.def : ditto
+
+ * insns.def (leave): use pop_frame() instead of
+ POP_CONTROL_STACK_FRAME() macro
+
+ * insnhelper.h : remove some macros
+
+ * yarvcore.c : change th_set_top_stack() prototype
+
+
2006-04-18(Tue) 18:37:08 +0900 Koichi Sasada <ko1 atdot.net>
* compile.c, disasm.c : support export/import exception
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2006-04-18 09:38:38 UTC (rev 491)
+++ trunk/eval.c 2006-04-25 13:34:50 UTC (rev 492)
@@ -1267,6 +1267,7 @@
state = 0;
th->state = 0;
th->errinfo = Qnil;
+ th->cfp = cfp;
}
else{
// SDR(); printf("%p, %p\n", cdfp, escape_dfp);
@@ -1275,11 +1276,12 @@
else if (state == TAG_RETRY) {
VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
VALUE *cdfp = cfp->dfp;
-
+
if (cdfp == escape_dfp) {
state = 0;
th->state = 0;
th->errinfo = Qnil;
+ th->cfp = cfp;
goto iter_retry;
}
}
@@ -1287,9 +1289,9 @@
TH_POP_TAG();
switch (state) {
- case 0:
+ case 0:
break;
- default:
+ default:
TH_JUMP_TAG(th, state);
}
return retval;
@@ -1822,12 +1824,8 @@
{
yarv_iseq_t *iseq = cfp->iseq;
if (!iseq) {
- return 0;
+ return cfp->method_id;
}
- if (YARV_CMETHOD_INFO_P(iseq)) {
- struct yarv_cmethod_info *cmi = (void *)iseq;
- return cmi->id;
- }
else if (YARV_IFUNC_P(iseq)) {
return rb_intern("<ifunc>");
}
Modified: trunk/insnhelper.h
===================================================================
--- trunk/insnhelper.h 2006-04-18 09:38:38 UTC (rev 491)
+++ trunk/insnhelper.h 2006-04-25 13:34:50 UTC (rev 492)
@@ -18,8 +18,6 @@
* deal with control frame pointer
*/
-#define POP_CONTROL_STACK_FRAME(th) INC_CFP()
-
/**********************************************************/
/* deal with stack */
/**********************************************************/
@@ -72,9 +70,6 @@
/* FP */
#define GET_CFP() (USAGE_ANALYSIS_REGISTER_HELPER(2, 0, REG_CFP))
-#define SET_CFP(x) (th->cfp = REG_CFP = (USAGE_ANALYSIS_REGISTER_HELPER(2, 1, (x))))
-#define INC_CFP() (SET_CFP(GET_CFP() + 1))
-#define DEC_CFP() (SET_CFP(GET_CFP() - 1))
#define GET_LFP() (USAGE_ANALYSIS_REGISTER_HELPER(3, 0, REG_LFP))
#define SET_LFP(x) (REG_LFP = (USAGE_ANALYSIS_REGISTER_HELPER(3, 1, (x))))
Modified: trunk/insns.def
===================================================================
--- trunk/insns.def 2006-04-18 09:38:38 UTC (rev 491)
+++ trunk/insns.def 2006-04-25 13:34:50 UTC (rev 492)
@@ -1309,7 +1309,7 @@
}
#endif
YARV_CHECK_INTS();
- POP_CONTROL_STACK_FRAME(th);
+ pop_frame(th);
RESTORE_REGS();
}
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2006-04-18 09:38:38 UTC (rev 491)
+++ trunk/vm.c 2006-04-25 13:34:50 UTC (rev 492)
@@ -75,7 +75,7 @@
/*
* prepare stack frame
*/
-static inline VALUE
+static inline yarv_control_frame_t *
push_frame(yarv_thread_t *th, yarv_iseq_t *iseq, VALUE magic,
VALUE self, VALUE specval, VALUE *pc,
VALUE *sp, VALUE *lfp, int local_size)
@@ -108,22 +108,53 @@
cfp->lfp = lfp;
cfp->dfp = dfp;
cfp->proc = 0;
+ cfp->method_id = 0;
- return Qtrue;
+#define COLLECT_PROFILE 0
+#if COLLECT_PROFILE
+ cfp->prof_time_self = clock();
+ cfp->prof_time_chld = 0;
+#endif
+
+ return cfp;
}
+static inline void
+pop_frame(yarv_thread_t *th)
+{
+#if COLLECT_PROFILE
+ yarv_control_frame_t *cfp = th->cfp;
+
+ if (YARV_NORMAL_ISEQ_P(cfp->iseq)) {
+ VALUE current_time = clock();
+ yarv_control_frame_t *cfp = th->cfp;
+ cfp->prof_time_self = current_time - cfp->prof_time_self;
+ (cfp+1)->prof_time_chld += cfp->prof_time_self;
+
+ cfp->iseq->profile.count++;
+ cfp->iseq->profile.time_cumu = cfp->prof_time_self;
+ cfp->iseq->profile.time_self = cfp->prof_time_self - cfp->prof_time_chld;
+ }
+ else if (0 /* c method? */) {
+
+ }
+#endif
+ th->cfp = YARV_PREVIOUS_CONTROL_FRAME(th->cfp);
+}
+
EXTERN VALUE ruby_top_self;
VALUE
th_set_finish_env(yarv_thread_t *th)
{
push_frame(th, 0, FRAME_MAGIC_FINISH,
- Qnil, th->cfp->lfp[0], 0, th->cfp->sp, 0, 1);
+ Qnil, th->cfp->lfp[0], 0,
+ th->cfp->sp, 0, 1);
th->cfp->pc = &yarv_finish_insn_seq[0];
return Qtrue;
}
-VALUE
+void
th_set_top_stack(yarv_thread_t *th, VALUE iseqval)
{
yarv_iseq_t *iseq;
@@ -132,9 +163,9 @@
/* for return */
th_set_finish_env(th);
- return push_frame(th, iseq, FRAME_MAGIC_TOP,
- ruby_top_self, 0, iseq->iseq_encoded, th->cfp->sp, 0,
- iseq->local_size);
+ push_frame(th, iseq, FRAME_MAGIC_TOP,
+ ruby_top_self, 0, iseq->iseq_encoded,
+ th->cfp->sp, 0, iseq->local_size);
}
VALUE
@@ -422,7 +453,8 @@
yarv_block_t *blockptr = 0;
if (0) printf("id: %s (%p), nd: %s, argc: %d, passed: %p\n",
- rb_id2name(id), id, node_name(nd_type(body)), argc, th->passed_block);
+ rb_id2name(id), id, node_name(nd_type(body)),
+ argc, th->passed_block);
//SDR2(th->cfp);
if (th->passed_block) {
@@ -445,16 +477,26 @@
val = th_eval_body(th);
break;
}
- case NODE_CFUNC:{
+ case NODE_CFUNC: {
yarv_control_frame_t *reg_cfp = th->cfp;
- struct yarv_cmethod_info cmi = { 0, id, klass };
+ yarv_control_frame_t *cfp =
+ push_frame(th, 0, FRAME_MAGIC_CFUNC,
+ recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
- push_frame(th, (yarv_iseq_t *)&cmi, FRAME_MAGIC_CFUNC,
- recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
+ cfp->callee_id = oid;
+ cfp->method_id = id;
+ cfp->method_klass = klass;
val = call_cfunc(body->nd_cfnc, recv, body->nd_argc, argc, argv);
- th->cfp = reg_cfp; /* pop control stack frame */
+ if (reg_cfp != th->cfp + 1) {
+ SDR2(reg_cfp);
+ SDR2(th->cfp-5);
+ rb_bug("cfp consistency error - call0");
+ th->cfp = reg_cfp;
+ }
+ pop_frame(th);
+
break;
}
case NODE_ATTRSET:{
@@ -502,22 +544,23 @@
ID id;
NODE *body;
int nosuper = 0;
- {
- struct yarv_cmethod_info *cmi = (void *)th->cfp->iseq;
- if (cmi->sig == 0) {
- klass = RCLASS(cmi->klass)->super;
- id = cmi->id;
- }
- else {
- rb_bug("thread_call_super: should not be reached");
- }
+ yarv_control_frame_t *cfp = th->cfp;
+
+ if (!th->cfp->iseq) {
+ klass = RCLASS(cfp->method_klass)->super;
+ id = cfp->method_id;
}
+ else {
+ rb_bug("thread_call_super: should not be reached");
+ }
body = rb_method_node(klass, id); /* this returns NODE_METHOD */
if (body) {
body = body->nd_body;
}
else {
+ dp(klass);
+ dpi(id);
rb_bug("th_call_super: not found");
}
return th_call0(th, klass, recv, id, id, argc, argv, body, nosuper);
@@ -680,6 +723,7 @@
int state;
volatile int stored_safe = th->safe_level;
volatile NODE *stored_special_cref_stack = 0;
+ yarv_control_frame_t * volatile cfp = th->cfp;
TH_PUSH_TAG(th);
if ((state = EXEC_TAG()) == 0) {
@@ -700,7 +744,7 @@
for (i=0; i<argc; i++) {
th->cfp->sp[i] = argv[i];
}
- argc = th_yield_setup_args(iseq, argc, th->cfp->sp);
+ argc = th_yield_setup_args(iseq, argc, cfp->sp);
th->cfp->sp += argc;
push_frame(th, iseq,
@@ -721,6 +765,7 @@
if (escape_dfp == cdfp) {
state = 0;
th->errinfo = Qnil;
+ th->cfp = cfp;
val = GET_THROWOBJ_VAL(err);
}
}
@@ -850,13 +895,14 @@
file, line_no, RSTRING(iseq->name)->ptr);
rb_ary_push(ary, str);
}
- else {
- struct yarv_cmethod_info *cmi = (void *)cfp->iseq;
- str = rb_sprintf("%s:%d:in `%s'",
- file, line_no, rb_id2name(cmi->id));
- rb_ary_push(ary, str);
- }
}
+ else if (cfp->callee_id) {
+ str = rb_sprintf("%s:%d:in `%s'",
+ file, line_no,
+ /* TODO: method_id? callee_id? */
+ rb_id2name(cfp->callee_id));
+ rb_ary_push(ary, str);
+ }
cfp = YARV_NEXT_CONTROL_FRAME(cfp);
}
return rb_ary_reverse(ary);
@@ -1536,6 +1582,7 @@
else {
result = GET_THROWOBJ_VAL(err);
th->errinfo = Qnil;
+ th->cfp += 2;
goto finish_vme;
}
/* through */
@@ -1663,7 +1710,7 @@
push_frame(th, catch_iseq, FRAME_MAGIC_BLOCK,
cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded,
cfp->sp + 1, cfp->lfp, catch_iseq->local_size - 1);
-
+
state = 0;
th->errinfo = Qnil;
goto vm_loop_start;
@@ -1674,7 +1721,7 @@
goto exception_handler;
}
else {
- th->cfp++;
+ pop_frame(th);
th->errinfo = err;
TH_POP_TAG2();
JUMP_TAG(state);
Modified: trunk/vm_dump.c
===================================================================
--- trunk/vm_dump.c 2006-04-18 09:38:38 UTC (rev 491)
+++ trunk/vm_dump.c 2006-04-25 13:34:50 UTC (rev 492)
@@ -80,13 +80,7 @@
}
if (cfp->iseq != 0) {
- if (YARV_CMETHOD_INFO_P(cfp->iseq)) {
- struct yarv_cmethod_info *cmi = (void *)cfp->iseq;
- iseq_name = rb_id2name(cmi->id);
- snprintf(posbuf, 23, ":%s", rb_id2name(cmi->id));
- line = -1;
- }
- else if (YARV_IFUNC_P(cfp->iseq)) {
+ if (YARV_IFUNC_P(cfp->iseq)) {
iseq_name = "<ifunc>";
}
else {
@@ -100,6 +94,11 @@
}
}
}
+ else if (cfp->method_id) {
+ iseq_name = rb_id2name(cfp->method_id);
+ snprintf(posbuf, 23, ":%s", rb_id2name(cfp->method_id));
+ line = -1;
+ }
fprintf(stderr, "c:%04ld ",
(yarv_control_frame_t *)(th->stack + th->stack_size) - cfp);
@@ -225,15 +224,16 @@
yarv_iseq_t *iseq = cfp->iseq;
if (iseq == 0) {
- name = "?";
- local_size = 0;
+ if (cfp->method_id) {
+ argc = 0;
+ local_size = 0;
+ name = rb_id2name(cfp->method_id);
+ }
+ else {
+ name = "?";
+ local_size = 0;
+ }
}
- else if (YARV_CMETHOD_INFO_P(iseq)) {
- struct yarv_cmethod_info *cmi = (void *)iseq;
- argc = 0;
- local_size = 0;
- name = rb_id2name(cmi->id);
- }
else if (YARV_IFUNC_P(iseq)) {
argc = 0;
local_size = 0;
@@ -575,6 +575,7 @@
SDR();
bt = th_backtrace(th, 0);
+ if (TYPE(bt) == T_ARRAY)
for (i = 0; i < RARRAY(bt)->len; i++) {
dp(RARRAY(bt)->ptr[i]);
}
Modified: trunk/vm_macro.def
===================================================================
--- trunk/vm_macro.def 2006-04-18 09:38:38 UTC (rev 491)
+++ trunk/vm_macro.def 2006-04-25 13:34:50 UTC (rev 492)
@@ -52,16 +52,23 @@
MACRO macro_eval_invoke_cfunc(num, id, recv, klass, mn, blockptr)
{
- struct yarv_cmethod_info cmi = { 0, id, klass };
-
- push_frame(th, (yarv_iseq_t *) & cmi, FRAME_MAGIC_CFUNC,
- recv, (VALUE) blockptr, 0, GET_SP(), 0, 1);
-
+ yarv_control_frame_t *cfp =
+ push_frame(th, 0, FRAME_MAGIC_CFUNC,
+ recv, (VALUE) blockptr, 0, GET_SP(), 0, 1);
+ cfp->callee_id = id; /* TODO */
+ cfp->method_id = id;
+ cfp->method_klass = klass;
+
reg_cfp->sp -= num + 1;
val = call_cfunc(mn->nd_cfnc, recv, mn->nd_argc, num, reg_cfp->sp + 1);
-
- th->cfp = reg_cfp; /* pop control stack frame */
+ if (reg_cfp != th->cfp + 1) {
+ SDR2(reg_cfp);
+ SDR2(th->cfp-5);
+ rb_bug("cfp consistency error - send");
+ th->cfp = reg_cfp;
+ }
+ pop_frame(th);
}
MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2006-04-18 09:38:38 UTC (rev 491)
+++ trunk/yarvcore.c 2006-04-25 13:34:50 UTC (rev 492)
@@ -785,7 +785,7 @@
}
VALUE th_eval_body(yarv_thread_t *th);
-VALUE th_set_top_stack(yarv_thread_t *, VALUE iseq);
+void th_set_top_stack(yarv_thread_t *, VALUE iseq);
VALUE rb_f_binding(VALUE);
static VALUE
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2006-04-18 09:38:38 UTC (rev 491)
+++ trunk/yarvcore.h 2006-04-25 13:34:50 UTC (rev 492)
@@ -190,6 +190,12 @@
#define GetISeqVal(obj, tobj) \
Data_Get_Struct(obj, yarv_iseq_t, tobj)
+typedef struct yarv_iseq_profile_struct {
+ VALUE count;
+ VALUE time_self;
+ VALUE time_cumu; /* cumulative */
+} yarv_iseq_profile_t;
+
struct yarv_iseq_struct;
struct yarv_iseq_struct {
@@ -267,7 +273,8 @@
/* misc */
ID defined_method_id; /* for define_method */
-
+ yarv_iseq_profile_t profile;
+
struct iseq_compile_data *compile_data;
};
@@ -311,6 +318,12 @@
VALUE *dfp; // cfp[7] // block[2]
yarv_iseq_t *block_iseq; // cfp[8] // block[3]
VALUE proc; // cfp[9] // block[4]
+ ID callee_id; // cfp[10]
+ ID method_id; // cfp[11] saved in special case
+ VALUE method_klass; // cfp[12] saved in special case
+ VALUE prof_time_self; // cfp[13]
+ VALUE prof_time_chld; // cfp[14]
+ VALUE dummy; // cfp[15]
} yarv_control_frame_t;
typedef struct {
@@ -510,18 +523,12 @@
#define YARV_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp) \
(!YARV_VALID_CONTROL_FRAME_P((cfp), YARV_END_CONTROL_FRAME(th)))
-#define YARV_CMETHOD_INFO_P(ptr) (*((VALUE*)(ptr)) == 0)
#define YARV_IFUNC_P(ptr) (BUILTIN_TYPE(ptr) == T_NODE)
#define YARV_NORMAL_ISEQ_P(ptr) \
- (ptr && !YARV_CMETHOD_INFO_P(ptr) && !YARV_IFUNC_P(ptr))
+ (ptr && !YARV_IFUNC_P(ptr))
#define YARV_CLASS_SPECIAL_P(ptr) (((VALUE)(ptr)) & 0x02)
#define YARV_BLOCK_PTR_P(ptr) (!YARV_CLASS_SPECIAL_P(ptr) && GC_GUARDED_PTR_REF(ptr))
-struct yarv_cmethod_info {
- VALUE sig; /* must be null */
- ID id;
- VALUE klass;
-};
#define GET_BLOCK_PTR_IN_CFP(cfp) ((yarv_block_t *)(&(cfp)->self))
#define GET_CFP_FROM_BLOCK_PTR(b) \
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml