[Stackless-checkins] CVS: slpdev/src/2.3/dev/Stackless/core slp_transfer.c, 1.23, 1.24 stackless_impl.h, 1.92, 1.93 stacklesseval.c, 1.152, 1.153

Christian Tismer tismer at centera.de
Thu Jun 3 19:18:08 CEST 2004


Update of /home/cvs/slpdev/src/2.3/dev/Stackless/core
In directory centera.de:/tmp/cvs-serv14794/Stackless/core

Modified Files:
	slp_transfer.c stackless_impl.h stacklesseval.c 
Log Message:
moved more things into slp_transfer.c, to prevend inlining
and optimization (gcc 3.3.2 problem)

Index: slp_transfer.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.3/dev/Stackless/core/slp_transfer.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -d -r1.23 -r1.24
*** slp_transfer.c	3 Jun 2004 17:07:34 -0000	1.23
--- slp_transfer.c	3 Jun 2004 17:18:06 -0000	1.24
***************
*** 48,53 ****
  /* this function must be here, too, to prevend inlining */
  
! int
! slp_make_initial_stub(void)
  {
  	PyThreadState *ts = PyThreadState_GET();
--- 48,53 ----
  /* this function must be here, too, to prevend inlining */
  
! static int
! make_initial_stub(void)
  {
  	PyThreadState *ts = PyThreadState_GET();
***************
*** 72,75 ****
--- 72,134 ----
  }
  
+ static PyObject *
+ climb_stack_and_eval_frame(PyFrameObject *f)
+ {
+ 	/* 
+ 	 * a similar case to climb_stack_and_transfer,
+ 	 * but here we need to incorporate a gap in the
+ 	 * stack into main and keep this gap on the stack.
+ 	 * This way, initial_stub is always valid to be
+ 	 * used to return to the main c stack.
+ 	 */
+ 	PyThreadState *ts = PyThreadState_GET();
+ 	int probe;
+ 	int needed = &probe - ts->st.cstack_base;
+ 	/* in rare cases, the need might have vanished due to the recursion */
+ 	int * goobledigoobs;
+ 
+ 	if (needed > 0) {
+ 		goobledigoobs = alloca(needed * sizeof(int));
+ 		if (goobledigoobs == NULL)
+ 			return NULL;
+ 	}
+ 	return slp_eval_frame(f);
+ }
+ 
+ PyObject *
+ slp_eval_frame(PyFrameObject *f)
+ {
+ 	PyThreadState *ts = PyThreadState_GET();
+ 	PyFrameObject *fprev = f->f_back;
+ 	int * stackref;
+ 
+ 	if (fprev == NULL && ts->st.main == NULL) {
+ 		/* this is the initial frame, so mark the stack base */
+ 
+ 		/* 
+ 		 * careful, this caused me a major headache.
+ 		 * it is *not* sufficient to just check for fprev == NULL.
+ 		 * Reason: (observed with wxPython):
+ 		 * A toplevel frame is run as a tasklet. When its frame
+ 		 * is deallocated (in tasklet_end), a Python object
+ 		 * with a __del__ method is destroyed. This __del__
+ 		 * will run as a toplevel frame, with f_back == NULL!
+ 		 */
+ 
+ 		stackref = STACK_REFPLUS + (int*) &f;
+ 		if (ts->st.cstack_base == NULL)
+ 			ts->st.cstack_base = stackref-CSTACK_GOODGAP;
+ 		if (stackref > ts->st.cstack_base)
+ 			return climb_stack_and_eval_frame(f);
+ 
+ 		ts->frame = f;
+ 		if (make_initial_stub())
+ 			return NULL;
+ 		return slp_run_tasklet();
+ 	}
+ 	Py_INCREF(Py_None);
+ 	return slp_frame_dispatch(f, fprev, Py_None);
+ }
+ 
  static int
  climb_stack_and_transfer(PyCStackObject **cstprev, PyCStackObject *cst,

Index: stackless_impl.h
===================================================================
RCS file: /home/cvs/slpdev/src/2.3/dev/Stackless/core/stackless_impl.h,v
retrieving revision 1.92
retrieving revision 1.93
diff -C2 -d -r1.92 -r1.93
*** stackless_impl.h	3 Jun 2004 17:07:34 -0000	1.92
--- stackless_impl.h	3 Jun 2004 17:18:06 -0000	1.93
***************
*** 44,49 ****
  PyAPI_FUNC(void) slp_cstack_restore(PyCStackObject *cst);
  
- PyAPI_FUNC(int) slp_make_initial_stub(void);
- 
  PyAPI_FUNC(int) slp_transfer(PyCStackObject **cstprev, PyCStackObject *cst,
  			     PyTaskletObject *prev);
--- 44,47 ----

Index: stacklesseval.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.3/dev/Stackless/core/stacklesseval.c,v
retrieving revision 1.152
retrieving revision 1.153
diff -C2 -d -r1.152 -r1.153
*** stacklesseval.c	3 Jun 2004 17:07:34 -0000	1.152
--- stacklesseval.c	3 Jun 2004 17:18:06 -0000	1.153
***************
*** 212,275 ****
  };
  
! 
! static PyObject *
! climb_stack_and_eval_frame(PyFrameObject *f)
! {
! 	/* 
! 	 * a similar case to climb_stack_and_transfer,
! 	 * but here we need to incorporate a gap in the
! 	 * stack into main and keep this gap on the stack.
! 	 * This way, initial_stub is always valid to be
! 	 * used to return to the main c stack.
! 	 */
! 	PyThreadState *ts = PyThreadState_GET();
! 	int probe;
! 	int needed = &probe - ts->st.cstack_base;
! 	/* in rare cases, the need might have vanished due to the recursion */
! 	int * goobledigoobs;
! 
! 	if (needed > 0) {
! 		goobledigoobs = alloca(needed * sizeof(int));
! 		if (goobledigoobs == NULL)
! 			return NULL;
! 	}
! 	return slp_eval_frame(f);
! }
! 
! 
! PyObject *
! slp_eval_frame(PyFrameObject *f)
! {
! 	PyThreadState *ts = PyThreadState_GET();
! 	PyFrameObject *fprev = f->f_back;
! 	int * stackref;
! 
! 	if (fprev == NULL && ts->st.main == NULL) {
! 		/* this is the initial frame, so mark the stack base */
! 
! 		/* 
! 		 * careful, this caused me a major headache.
! 		 * it is *not* sufficient to just check for fprev == NULL.
! 		 * Reason: (observed with wxPython):
! 		 * A toplevel frame is run as a tasklet. When its frame
! 		 * is deallocated (in tasklet_end), a Python object
! 		 * with a __del__ method is destroyed. This __del__
! 		 * will run as a toplevel frame, with f_back == NULL!
! 		 */
! 
! 		stackref = STACK_REFPLUS + (int*) &f;
! 		if (ts->st.cstack_base == NULL)
! 			ts->st.cstack_base = stackref-CSTACK_GOODGAP;
! 		if (stackref > ts->st.cstack_base)
! 			return climb_stack_and_eval_frame(f);
! 
! 		ts->frame = f;
! 		if (slp_make_initial_stub())
! 			return NULL;
! 		return slp_run_tasklet();
! 	}
! 	Py_INCREF(Py_None);
! 	return slp_frame_dispatch(f, fprev, Py_None);
! }
  
  void slp_kill_tasks_with_stacks(PyThreadState *ts)
--- 212,219 ----
  };
  
! /* 
!  * slp_eval_frame moved to slp_transfer.c
!  * to avoid optimization in gcc 3.3.2
!  */
  
  void slp_kill_tasks_with_stacks(PyThreadState *ts)


_______________________________________________
Stackless-checkins mailing list
Stackless-checkins at stackless.com
http://www.stackless.com/mailman/listinfo/stackless-checkins



More information about the Stackless-checkins mailing list