mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	call_trace(): Add an additional parameter -- pointer to a PyObject*
that should be used to cache an interned version of the event
    string passed to the profile/trace function.  call_trace() will
    create interned strings and cache them in using the storage
    specified by this additional parameter, avoiding a lot of string
    object creation at runtime when using the profiling or tracing
    functions.
All call sites are modified to pass the additional parameter, and four
static PyObject* variables are allocated to cache the interned string
objects.
This closes SF patch #431257.
			
			
This commit is contained in:
		
							parent
							
								
									edb5ffb2c1
								
							
						
					
					
						commit
						904aa7bb00
					
				
					 1 changed files with 36 additions and 13 deletions
				
			
		|  | @ -62,7 +62,7 @@ static int prtrace(PyObject *, char *); | |||
| #endif | ||||
| static void call_exc_trace(PyObject **, PyObject**, PyFrameObject *); | ||||
| static int call_trace(PyObject **, PyObject **, | ||||
| 		      PyFrameObject *, char *, PyObject *); | ||||
| 		      PyFrameObject *, char *, PyObject **, PyObject *); | ||||
| static PyObject *loop_subscript(PyObject *, PyObject *); | ||||
| static PyObject *apply_slice(PyObject *, PyObject *, PyObject *); | ||||
| static int assign_slice(PyObject *, PyObject *, | ||||
|  | @ -97,6 +97,15 @@ static long dxp[256]; | |||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| /* Cached interned string objects used for calling the profile and
 | ||||
|  * trace functions. | ||||
|  */ | ||||
| static PyObject *str_call = NULL; | ||||
| static PyObject *str_exception = NULL; | ||||
| static PyObject *str_line = NULL; | ||||
| static PyObject *str_return = NULL; | ||||
| 
 | ||||
| 
 | ||||
| #ifdef WITH_THREAD | ||||
| 
 | ||||
| #ifndef DONT_HAVE_ERRNO_H | ||||
|  | @ -645,7 +654,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 		   (sys.trace) is also called whenever an exception | ||||
| 		   is detected. */ | ||||
| 		if (call_trace(&tstate->sys_tracefunc, | ||||
| 			       &f->f_trace, f, "call", | ||||
| 			       &f->f_trace, f, "call", &str_call, | ||||
| 			       Py_None/*XXX how to compute arguments now?*/)) { | ||||
| 			/* Trace function raised an error */ | ||||
| 			goto fail; | ||||
|  | @ -656,7 +665,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 		/* Similar for sys_profilefunc, except it needn't return
 | ||||
| 		   itself and isn't called for "line" events */ | ||||
| 		if (call_trace(&tstate->sys_profilefunc, | ||||
| 			       (PyObject**)0, f, "call", | ||||
| 			       (PyObject**)0, f, "call", &str_call, | ||||
| 			       Py_None/*XXX*/)) { | ||||
| 			goto fail; | ||||
| 		} | ||||
|  | @ -1952,7 +1961,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 			/* Trace each line of code reached */ | ||||
| 			f->f_lasti = INSTR_OFFSET(); | ||||
| 			err = call_trace(&f->f_trace, &f->f_trace, | ||||
| 					 f, "line", Py_None); | ||||
| 					 f, "line", &str_line, Py_None); | ||||
| 			break; | ||||
| 
 | ||||
| 		case CALL_FUNCTION: | ||||
|  | @ -2297,7 +2306,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 	if (f->f_trace) { | ||||
| 		if (why == WHY_RETURN) { | ||||
| 			if (call_trace(&f->f_trace, &f->f_trace, f, | ||||
| 				       "return", retval)) { | ||||
| 				       "return", &str_return, retval)) { | ||||
| 				Py_XDECREF(retval); | ||||
| 				retval = NULL; | ||||
| 				why = WHY_EXCEPTION; | ||||
|  | @ -2307,7 +2316,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 
 | ||||
| 	if (tstate->sys_profilefunc && why == WHY_RETURN) { | ||||
| 		if (call_trace(&tstate->sys_profilefunc, (PyObject**)0, | ||||
| 			       f, "return", retval)) { | ||||
| 			       f, "return", &str_return, retval)) { | ||||
| 			Py_XDECREF(retval); | ||||
| 			retval = NULL; | ||||
| 			why = WHY_EXCEPTION; | ||||
|  | @ -2575,7 +2584,8 @@ call_exc_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f) | |||
| 		PyErr_Restore(type, value, traceback); | ||||
| 		return; | ||||
| 	} | ||||
| 	err = call_trace(p_trace, p_newtrace, f, "exception", arg); | ||||
| 	err = call_trace(p_trace, p_newtrace, f, | ||||
| 			 "exception", &str_exception, arg); | ||||
| 	Py_DECREF(arg); | ||||
| 	if (err == 0) | ||||
| 		PyErr_Restore(type, value, traceback); | ||||
|  | @ -2590,11 +2600,16 @@ call_exc_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f) | |||
|  				may not point to NULL variable initially | ||||
|    PyObject **p_newtrace: in/out; may be NULL; | ||||
|   				may point to NULL variable; | ||||
|  				may be same variable as p_newtrace */ | ||||
|  				may be same variable as p_newtrace | ||||
|    PyObject **p_omsg: in/out; may not be NULL; | ||||
| 				if non-null & *p_omsg == NULL, will be | ||||
| 				initialized with an interned string | ||||
| 				corresponding to msg. | ||||
| */ | ||||
| 
 | ||||
| static int | ||||
| call_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f, | ||||
| 	   char *msg, PyObject *arg) | ||||
| 	   char *msg, PyObject **p_omsg, PyObject *arg) | ||||
| { | ||||
| 	PyThreadState *tstate = f->f_tstate; | ||||
| 	PyObject *args, *what; | ||||
|  | @ -2612,9 +2627,17 @@ call_trace(PyObject **p_trace, PyObject **p_newtrace, PyFrameObject *f, | |||
| 	args = PyTuple_New(3); | ||||
| 	if (args == NULL) | ||||
| 		goto cleanup; | ||||
| 	what = PyString_FromString(msg); | ||||
| 	if (*p_omsg != NULL) { | ||||
| 		what = *p_omsg; | ||||
| 		Py_INCREF(what); | ||||
| 	} | ||||
| 	else { | ||||
| 		what = PyString_InternFromString(msg); | ||||
| 		if (what == NULL) | ||||
| 			goto cleanup; | ||||
| 		*p_omsg = what; | ||||
| 		Py_INCREF(what); | ||||
| 	} | ||||
| 	Py_INCREF(f); | ||||
| 	PyTuple_SET_ITEM(args, 0, (PyObject *)f); | ||||
| 	PyTuple_SET_ITEM(args, 1, what); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Fred Drake
						Fred Drake