]> granicus.if.org Git - python/commitdiff
Assorted patches from Armin Rigo:
authorMichael W. Hudson <mwh@python.net>
Fri, 8 Nov 2002 12:53:11 +0000 (12:53 +0000)
committerMichael W. Hudson <mwh@python.net>
Fri, 8 Nov 2002 12:53:11 +0000 (12:53 +0000)
[ 617309 ] getframe hook (Psyco #1)
[ 617311 ] Tiny profiling info (Psyco #2)
[ 617312 ] debugger-controlled jumps (Psyco #3)

These are forward ports from 2.2.2.

Include/pystate.h
Modules/pyexpat.c
Python/ceval.c
Python/pystate.c

index 9b61ad7d39e0d6792c31d1110cd2db1dca3aab51..d4233bfeedab2a1dfd6b8b81d08724d99482cd46 100644 (file)
@@ -67,6 +67,8 @@ typedef struct _ts {
 
     PyObject *dict;
 
+    int tick_counter;
+
     /* XXX signal handlers should also be here */
 
 } PyThreadState;
@@ -105,6 +107,9 @@ PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *);
 PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *);
 PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *);
 
+/* hook for PyEval_GetFrame(), requested for Psyco */
+PyAPI_DATA(unaryfunc) _PyThreadState_GetFrame;
+
 #ifdef __cplusplus
 }
 #endif
index 2009b225bcbd29b6e68baadd8ee124638e9038ab..f74751ba616a1cb91f0be0ed27e2859039762107 100644 (file)
@@ -304,7 +304,7 @@ call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args)
     f = PyFrame_New(
                     tstate,                    /*back*/
                     c,                         /*code*/
-                    tstate->frame->f_globals,  /*globals*/
+                    PyEval_GetGlobals(),       /*globals*/
                     NULL                       /*locals*/
                     );
     if (f == NULL)
index 09b88a6ca7806197241e636e95bdb806e3d70811..1c95cb9cfbae04123bd1a4280ce09bd31187cb09 100644 (file)
@@ -51,7 +51,7 @@ static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
 static void call_trace_protected(Py_tracefunc, PyObject *,
                                 PyFrameObject *, int);
 static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
-static void maybe_call_line_trace(int, Py_tracefunc, PyObject *, 
+static void maybe_call_line_trace(Py_tracefunc, PyObject *, 
                                  PyFrameObject *, int *, int *);
 
 static PyObject *apply_slice(PyObject *, PyObject *, PyObject *);
@@ -599,24 +599,6 @@ eval_frame(PyFrameObject *f)
        }
 
        tstate->frame = f;
-       co = f->f_code;
-       names = co->co_names;
-       consts = co->co_consts;
-       fastlocals = f->f_localsplus;
-       freevars = f->f_localsplus + f->f_nlocals;
-       _PyCode_GETCODEPTR(co, &first_instr);
-       /* An explanation is in order for the next line.
-
-          f->f_lasti now refers to the index of the last instruction
-          executed.  You might think this was obvious from the name, but
-          this wasn't always true before 2.3!  PyFrame_New now sets
-          f->f_lasti to -1 (i.e. the index *before* the first instruction)
-          and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this
-          does work.  Promise. */
-       next_instr = first_instr + f->f_lasti + 1;
-       stack_pointer = f->f_stacktop;
-       assert(stack_pointer != NULL);
-       f->f_stacktop = NULL;   /* remains NULL unless yield suspends frame */
 
        if (tstate->use_tracing) {
                if (tstate->c_tracefunc != NULL) {
@@ -655,6 +637,25 @@ eval_frame(PyFrameObject *f)
                }
        }
 
+       co = f->f_code;
+       names = co->co_names;
+       consts = co->co_consts;
+       fastlocals = f->f_localsplus;
+       freevars = f->f_localsplus + f->f_nlocals;
+       _PyCode_GETCODEPTR(co, &first_instr);
+       /* An explanation is in order for the next line.
+
+          f->f_lasti now refers to the index of the last instruction
+          executed.  You might think this was obvious from the name, but
+          this wasn't always true before 2.3!  PyFrame_New now sets
+          f->f_lasti to -1 (i.e. the index *before* the first instruction)
+          and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this
+          does work.  Promise. */
+       next_instr = first_instr + f->f_lasti + 1;
+       stack_pointer = f->f_stacktop;
+       assert(stack_pointer != NULL);
+       f->f_stacktop = NULL;   /* remains NULL unless yield suspends frame */
+
 #ifdef LLTRACE
        lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL;
 #endif
@@ -681,6 +682,7 @@ eval_frame(PyFrameObject *f)
 
                if (--_Py_Ticker < 0) {
                        _Py_Ticker = _Py_CheckInterval;
+                       tstate->tick_counter++;
                        if (things_to_do) {
                                if (Py_MakePendingCalls() < 0) {
                                        why = WHY_EXCEPTION;
@@ -716,10 +718,26 @@ eval_frame(PyFrameObject *f)
                }
 
        fast_next_opcode:
-               /* Extract opcode and argument */
-
                f->f_lasti = INSTR_OFFSET();
 
+               /* line-by-line tracing support */
+
+               if (tstate->c_tracefunc != NULL && !tstate->tracing) {
+                       /* see maybe_call_line_trace
+                          for expository comments */
+                       f->f_stacktop = stack_pointer;
+                       maybe_call_line_trace(tstate->c_tracefunc,
+                                             tstate->c_traceobj,
+                                             f, &instr_lb, &instr_ub);
+                       /* Reload possibly changed frame fields */
+                       JUMPTO(f->f_lasti);
+                       stack_pointer = f->f_stacktop;
+                       assert(stack_pointer != NULL);
+                       f->f_stacktop = NULL;
+               }
+
+               /* Extract opcode and argument */
+
                opcode = NEXTOP();
                if (HAS_ARG(opcode))
                        oparg = NEXTARG();
@@ -747,17 +765,6 @@ eval_frame(PyFrameObject *f)
                }
 #endif
 
-               /* line-by-line tracing support */
-
-               if (tstate->c_tracefunc != NULL && !tstate->tracing) {
-                       /* see maybe_call_line_trace
-                          for expository comments */
-                       maybe_call_line_trace(opcode, 
-                                             tstate->c_tracefunc,
-                                             tstate->c_traceobj,
-                                             f, &instr_lb, &instr_ub);
-               }
-
                /* Main switch on opcode */
 
                switch (opcode) {
@@ -2866,7 +2873,7 @@ call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
 }
 
 static void
-maybe_call_line_trace(int opcode, Py_tracefunc func, PyObject *obj, 
+maybe_call_line_trace(Py_tracefunc func, PyObject *obj, 
                      PyFrameObject *frame, int *instr_lb, int *instr_ub)
 {
        /* The theory of SET_LINENO-less tracing.
@@ -3025,10 +3032,9 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg)
 PyObject *
 PyEval_GetBuiltins(void)
 {
-       PyThreadState *tstate = PyThreadState_Get();
-       PyFrameObject *current_frame = tstate->frame;
+       PyFrameObject *current_frame = (PyFrameObject *)PyEval_GetFrame();
        if (current_frame == NULL)
-               return tstate->interp->builtins;
+               return PyThreadState_Get()->interp->builtins;
        else
                return current_frame->f_builtins;
 }
@@ -3036,7 +3042,7 @@ PyEval_GetBuiltins(void)
 PyObject *
 PyEval_GetLocals(void)
 {
-       PyFrameObject *current_frame = PyThreadState_Get()->frame;
+       PyFrameObject *current_frame = (PyFrameObject *)PyEval_GetFrame();
        if (current_frame == NULL)
                return NULL;
        PyFrame_FastToLocals(current_frame);
@@ -3046,7 +3052,7 @@ PyEval_GetLocals(void)
 PyObject *
 PyEval_GetGlobals(void)
 {
-       PyFrameObject *current_frame = PyThreadState_Get()->frame;
+       PyFrameObject *current_frame = (PyFrameObject *)PyEval_GetFrame();
        if (current_frame == NULL)
                return NULL;
        else
@@ -3056,21 +3062,21 @@ PyEval_GetGlobals(void)
 PyObject *
 PyEval_GetFrame(void)
 {
-       PyFrameObject *current_frame = PyThreadState_Get()->frame;
-       return (PyObject *)current_frame;
+       PyThreadState *tstate = PyThreadState_Get();
+       return _PyThreadState_GetFrame((PyObject *)tstate);
 }
 
 int
 PyEval_GetRestricted(void)
 {
-       PyFrameObject *current_frame = PyThreadState_Get()->frame;
+       PyFrameObject *current_frame = (PyFrameObject *)PyEval_GetFrame();
        return current_frame == NULL ? 0 : current_frame->f_restricted;
 }
 
 int
 PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
 {
-       PyFrameObject *current_frame = PyThreadState_Get()->frame;
+       PyFrameObject *current_frame = (PyFrameObject *)PyEval_GetFrame();
        int result = 0;
 
        if (current_frame != NULL) {
index ad92ddec26973b19a0865e3f0c1e097c57f35099..707e43e90d749b5c611cbdf2708d38290bf6441b 100644 (file)
@@ -35,6 +35,7 @@ static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
 static PyInterpreterState *interp_head = NULL;
 
 PyThreadState *_PyThreadState_Current = NULL;
+unaryfunc _PyThreadState_GetFrame = NULL;
 
 
 PyInterpreterState *
@@ -113,10 +114,19 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
 }
 
 
+/* Default implementation for _PyThreadState_GetFrame */
+static struct _frame *
+threadstate_getframe(PyThreadState *self)
+{
+       return self->frame;
+}
+
 PyThreadState *
 PyThreadState_New(PyInterpreterState *interp)
 {
        PyThreadState *tstate = PyMem_NEW(PyThreadState, 1);
+       if (_PyThreadState_GetFrame == NULL)
+               _PyThreadState_GetFrame = (unaryfunc)threadstate_getframe;
 
        if (tstate != NULL) {
                tstate->interp = interp;
@@ -125,6 +135,7 @@ PyThreadState_New(PyInterpreterState *interp)
                tstate->recursion_depth = 0;
                tstate->tracing = 0;
                tstate->use_tracing = 0;
+               tstate->tick_counter = 0;
 
                tstate->dict = NULL;