[前][次][番号順一覧][スレッド一覧]

ruby-changes:24991

From: ko1 <ko1@a...>
Date: Fri, 28 Sep 2012 13:05:48 +0900 (JST)
Subject: [ruby-changes:24991] ko1:r37043 (trunk): * vm_core.h: remove rb_control_frame_t::bp (bp: base pointer).

ko1	2012-09-28 13:05:36 +0900 (Fri, 28 Sep 2012)

  New Revision: 37043

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37043

  Log:
    * vm_core.h: remove rb_control_frame_t::bp (bp: base pointer).
      `bp' can be calculate by `sp' (stack pointer) of previous frame.
      Now, `bp_check' field is remained for debug.  You can eliminate
      this field by setting  VM_DEBUG_BP_CHECK as 0.
    * vm_insnhelper.c (vm_base_ptr): add `vm_base_ptr(cfp).
      This function calculates base pointer from cfp.
    * vm_insnhelper.c (vm_setup_method): push `recv' value on top of
      value stack (before method parameters).
      This change is for keeping consistency with normal method dispatch.
    * insns.def: fix to use vm_base_ptr().
    * vm.c (vm_exec): ditto.
    * vm_dump.c: remove `bp' related dumps.
    * cont.c (fiber_init): fix to check VM_DEBUG_BP_CHECK.

  Modified files:
    trunk/ChangeLog
    trunk/cont.c
    trunk/insns.def
    trunk/vm.c
    trunk/vm_core.h
    trunk/vm_dump.c
    trunk/vm_insnhelper.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 37042)
+++ ChangeLog	(revision 37043)
@@ -1,3 +1,25 @@
+Fri Sep 28 12:51:54 2012  Koichi Sasada  <ko1@a...>
+
+	* vm_core.h: remove rb_control_frame_t::bp (bp: base pointer).
+	  `bp' can be calculate by `sp' (stack pointer) of previous frame.
+	  Now, `bp_check' field is remained for debug.  You can eliminate
+	  this field by setting  VM_DEBUG_BP_CHECK as 0.
+
+	* vm_insnhelper.c (vm_base_ptr): add `vm_base_ptr(cfp).
+	  This function calculates base pointer from cfp.
+
+	* vm_insnhelper.c (vm_setup_method): push `recv' value on top of
+	  value stack (before method parameters).
+	  This change is for keeping consistency with normal method dispatch.
+
+	* insns.def: fix to use vm_base_ptr().
+
+	* vm.c (vm_exec): ditto.
+
+	* vm_dump.c: remove `bp' related dumps.
+
+	* cont.c (fiber_init): fix to check VM_DEBUG_BP_CHECK.
+
 Fri Sep 28 10:40:51 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* io.c (rb_io_reopen): accept File::Constants as well as mode string.
Index: insns.def
===================================================================
--- insns.def	(revision 37042)
+++ insns.def	(revision 37043)
@@ -1092,9 +1092,9 @@
 (VALUE val)
 {
     if (OPT_CHECKED_RUN) {
-	if (reg_cfp->sp != reg_cfp->bp) {
+	if (reg_cfp->sp != vm_base_ptr(reg_cfp)) {
 	    rb_bug("Stack consistency error (sp: %"PRIdPTRDIFF", bp: %"PRIdPTRDIFF")",
-		   VM_SP_CNT(th, reg_cfp->sp), VM_SP_CNT(th, reg_cfp->bp));
+		   VM_SP_CNT(th, reg_cfp->sp), VM_SP_CNT(th, vm_base_ptr(reg_cfp)));
 	}
     }
 
@@ -1316,8 +1316,8 @@
 ()
 ()
 {
-    if (GET_CFP()->bp != GET_EP() + 1) {
-	VALUE *ep = GET_CFP()->bp - 1;
+    if (vm_base_ptr(reg_cfp) != GET_EP() + 1) {
+	VALUE *ep = vm_base_ptr(reg_cfp) - 1;
 	/* TODO: copy env and clean stack at creating env? */
 	*ep = *GET_EP();
 	SET_EP(ep);
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 37042)
+++ vm_core.h	(revision 37043)
@@ -353,18 +353,25 @@
     VALUE *defined_strings;
 } rb_vm_t;
 
+#ifndef VM_DEBUG_BP_CHECK
+#define VM_DEBUG_BP_CHECK 0
+#endif
+
 typedef struct {
     VALUE *pc;			/* cfp[0] */
     VALUE *sp;			/* cfp[1] */
-    VALUE *bp;			/* cfp[2] */
-    rb_iseq_t *iseq;		/* cfp[3] */
-    VALUE flag;			/* cfp[4] */
-    VALUE self;			/* cfp[5] / block[0] */
-    VALUE klass;		/* cfp[6] / block[1] */
-    VALUE *ep;			/* cfp[7] / block[2] */
-    rb_iseq_t *block_iseq;	/* cfp[8] / block[3] */
-    VALUE proc;			/* cfp[9] / block[4] */
-    const rb_method_entry_t *me;/* cfp[10] */
+    rb_iseq_t *iseq;		/* cfp[2] */
+    VALUE flag;			/* cfp[3] */
+    VALUE self;			/* cfp[4] / block[0] */
+    VALUE klass;		/* cfp[5] / block[1] */
+    VALUE *ep;			/* cfp[6] / block[2] */
+    rb_iseq_t *block_iseq;	/* cfp[7] / block[3] */
+    VALUE proc;			/* cfp[8] / block[4] */
+    const rb_method_entry_t *me;/* cfp[9] */
+
+#if VM_DEBUG_BP_CHECK
+    VALUE *bp_check;		/* cfp[10] */
+#endif
 } rb_control_frame_t;
 
 typedef struct rb_block_struct {
@@ -707,7 +714,8 @@
 
 #define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp) ((rb_block_t *)(&(cfp)->self))
 #define RUBY_VM_GET_CFP_FROM_BLOCK_PTR(b) \
-  ((rb_control_frame_t *)((VALUE *)(b) - 5))
+  ((rb_control_frame_t *)((VALUE *)(b) - 4))
+/* magic number `4' is depend on rb_control_frame_t layout. */
 
 /* VM related object allocate functions */
 VALUE rb_thread_alloc(VALUE klass);
Index: cont.c
===================================================================
--- cont.c	(revision 37042)
+++ cont.c	(revision 37043)
@@ -1061,7 +1061,9 @@
     th->cfp--;
     th->cfp->pc = 0;
     th->cfp->sp = th->stack + 1;
-    th->cfp->bp = 0;
+#if VM_DEBUG_BP_CHECK
+    th->cfp->bp_check = 0;
+#endif
     th->cfp->ep = th->stack;
     *th->cfp->ep = VM_ENVVAL_BLOCK_PTR(0);
     th->cfp->self = Qnil;
Index: vm.c
===================================================================
--- vm.c	(revision 37042)
+++ vm.c	(revision 37043)
@@ -1272,7 +1272,7 @@
 		    }
 		    else if (entry->type == type) {
 			cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
-			cfp->sp = cfp->bp + entry->sp;
+			cfp->sp = vm_base_ptr(cfp) + entry->sp;
 
 			if (state != TAG_REDO) {
 #if OPT_STACK_CACHING
@@ -1317,7 +1317,7 @@
 
 	    /* enter catch scope */
 	    GetISeqPtr(catch_iseqval, catch_iseq);
-	    cfp->sp = cfp->bp + cont_sp;
+	    cfp->sp = vm_base_ptr(cfp) + cont_sp;
 	    cfp->pc = cfp->iseq->iseq_encoded + cont_pc;
 
 	    /* push block frame */
Index: vm_dump.c
===================================================================
--- vm_dump.c	(revision 37042)
+++ vm_dump.c	(revision 37043)
@@ -27,7 +27,7 @@
 static void
 control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
 {
-    ptrdiff_t pc = -1, bp = -1;
+    ptrdiff_t pc = -1;
     ptrdiff_t ep = cfp->ep - th->stack;
     char ep_in_heap = ' ';
     char posbuf[MAX_POSBUF+1];
@@ -44,9 +44,6 @@
 	ep = (ptrdiff_t)cfp->ep;
 	ep_in_heap = 'p';
     }
-    if (cfp->bp) {
-	bp = cfp->bp - th->stack;
-    }
 
     switch (VM_FRAME_TYPE(cfp)) {
       case VM_FRAME_MAGIC_TOP:
@@ -119,7 +116,7 @@
     else {
 	fprintf(stderr, "p:%04"PRIdPTRDIFF" ", pc);
     }
-    fprintf(stderr, "s:%04"PRIdPTRDIFF" b:%04"PRIdPTRDIFF" ", (cfp->sp - th->stack), bp);
+    fprintf(stderr, "s:%04"PRIdPTRDIFF" ", cfp->sp - th->stack);
     fprintf(stderr, ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "e:%06"PRIxPTRDIFF" ", ep % 10000);
     fprintf(stderr, "%-6s", magic);
     if (line) {
@@ -141,7 +138,7 @@
 rb_vmdebug_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp)
 {
 #if 0
-    VALUE *sp = cfp->sp, *bp = cfp->bp, *ep = cfp->ep;
+    VALUE *sp = cfp->sp, *ep = cfp->ep;
     VALUE *p, *st, *t;
 
     fprintf(stderr, "-- stack frame ------------\n");
@@ -155,8 +152,6 @@
 
 	if (p == ep)
 	    fprintf(stderr, " <- ep");
-	if (p == bp)
-	    fprintf(stderr, " <- bp");	/* should not be */
 
 	fprintf(stderr, "\n");
     }
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 37042)
+++ vm_insnhelper.c	(revision 37043)
@@ -57,7 +57,9 @@
 
     cfp->pc = (VALUE *)pc;
     cfp->sp = sp + 1;
-    cfp->bp = sp + 1;
+#if VM_DEBUG_BP_CHECK
+    cfp->bp_check = sp + 1;
+#endif
     cfp->ep = sp;
     cfp->iseq = (rb_iseq_t *) iseq;
     cfp->flag = type;
@@ -494,19 +496,16 @@
 		const rb_method_entry_t *me, VALUE defined_class)
 {
     int opt_pc, i;
-    VALUE *sp, *rsp = cfp->sp - argc;
+    VALUE *sp, *argv = cfp->sp - argc;
     rb_iseq_t *iseq = me->def->body.iseq;
 
-    VM_CALLEE_SETUP_ARG(opt_pc, th, iseq, argc, rsp, &blockptr);
+    VM_CALLEE_SETUP_ARG(opt_pc, th, iseq, argc, argv, &blockptr);
 
     /* stack overflow check */
     CHECK_STACK_OVERFLOW(cfp, iseq->stack_max);
+    sp = argv + iseq->arg_size;
 
-    sp = rsp + iseq->arg_size;
-
     if (LIKELY(!(flag & VM_CALL_TAILCALL_BIT))) {
-	if (0) printf("local_size: %d, arg_size: %d\n",
-		      iseq->local_size, iseq->arg_size);
 
 	/* clear local variables */
 	for (i = 0; i < iseq->local_size - iseq->arg_size; i++) {
@@ -517,30 +516,36 @@
 		      VM_ENVVAL_BLOCK_PTR(blockptr),
 		      iseq->iseq_encoded + opt_pc, sp, 0, me);
 
-	cfp->sp = rsp - 1 /* recv */;
+	cfp->sp = argv - 1 /* recv */;
     }
     else {
-	VALUE *p_rsp;
-	int is_finish_frame = VM_FRAME_TYPE_FINISH_P(cfp);
+	VALUE *src_argv = argv;
+	VALUE *sp_orig;
+	int src_argc = sp - src_argv;
+	VALUE finish_flag = VM_FRAME_TYPE_FINISH_P(cfp) ? VM_FRAME_FLAG_FINISH : 0;
+	cfp = th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); /* pop cf */
 
-	th->cfp++; /* pop cf */
-	p_rsp = th->cfp->sp;
+	sp = sp_orig = cfp->sp;
 
+	/* push self */
+	sp[0] = recv;
+	sp++;
+
 	/* copy arguments */
-	for (i=0; i < (sp - rsp); i++) {
-	    p_rsp[i] = rsp[i];
+	for (i=0; i < src_argc; i++) {
+	    *sp++ = src_argv[i];
 	}
 
-	sp -= rsp - p_rsp;
-
 	/* clear local variables */
 	for (i = 0; i < iseq->local_size - iseq->arg_size; i++) {
 	    *sp++ = Qnil;
 	}
 
-	vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD | (is_finish_frame ? VM_FRAME_FLAG_FINISH : 0),
+	vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD | finish_flag,
 		      recv, defined_class, VM_ENVVAL_BLOCK_PTR(blockptr),
 		      iseq->iseq_encoded + opt_pc, sp, 0, me);
+
+	cfp->sp = sp_orig;
     }
 }
 
@@ -1902,3 +1907,27 @@
     CHECK_CMP_NAN(a, b);
     return a >= b ? Qtrue : Qfalse;
 }
+
+static VALUE *
+vm_base_ptr(rb_control_frame_t *cfp)
+{
+    rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+    VALUE *bp = prev_cfp->sp + cfp->iseq->local_size + 1;
+
+    if (cfp->iseq->type == ISEQ_TYPE_METHOD) {
+	/* adjust `self' */
+	bp += 1;
+    }
+
+#if VM_DEBUG_BP_CHECK
+    if (bp != cfp->bp_check) {
+	fprintf(stderr, "bp_check: %d, bp: %d\n",
+		cfp->bp_check - GET_THREAD()->stack,
+		bp - GET_THREAD()->stack);
+	rb_bug("vm_base_ptr: unreachable");
+    }
+#endif
+
+    return bp;
+}
+

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]