mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	Remove f_closure slot of frameobject and use f_localsplus instead.
This change eliminates an extra malloc/free when a frame with free variables is created. Any cell vars or free vars are stored in f_localsplus after the locals and before the stack. eval_code2() fills in the appropriate values after handling initialization of locals. To track the size the frame has an f_size member that tracks the total size of f_localsplus. It used to be implicitly f_nlocals + f_stacksize.
This commit is contained in:
		
							parent
							
								
									55087f0c35
								
							
						
					
					
						commit
						2b724da8d9
					
				
					 3 changed files with 33 additions and 28 deletions
				
			
		|  | @ -368,7 +368,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 	register PyObject *t; | ||||
| 	register PyObject *stream = NULL;    /* for PRINT opcodes */ | ||||
| 	register PyFrameObject *f; /* Current frame */ | ||||
| 	register PyObject **fastlocals; | ||||
| 	register PyObject **fastlocals, **freevars; | ||||
| 	PyObject *retval = NULL;	/* Return value */ | ||||
| 	PyThreadState *tstate = PyThreadState_GET(); | ||||
| 	unsigned char *first_instr; | ||||
|  | @ -439,6 +439,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 
 | ||||
| 	tstate->frame = f; | ||||
| 	fastlocals = f->f_localsplus; | ||||
| 	freevars = f->f_localsplus + f->f_nlocals; | ||||
| 
 | ||||
| 	if (co->co_argcount > 0 || | ||||
| 	    co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) { | ||||
|  | @ -572,6 +573,17 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 			goto fail; | ||||
| 		} | ||||
| 	} | ||||
| 	/* Allocate storage for cell vars and copy free vars into frame */  | ||||
| 	if (f->f_ncells) { | ||||
| 		int i; | ||||
| 		for (i = 0; i < f->f_ncells; ++i) | ||||
| 			freevars[i] = PyCell_New(NULL); | ||||
| 	} | ||||
| 	if (f->f_nfreevars) { | ||||
| 		int i; | ||||
| 		for (i = 0; i < f->f_nfreevars; ++i) | ||||
| 			freevars[f->f_ncells + i] = PyTuple_GET_ITEM(closure, i); | ||||
| 	} | ||||
| 
 | ||||
| 	if (tstate->sys_tracefunc != NULL) { | ||||
| 		/* tstate->sys_tracefunc, if defined, is a function that
 | ||||
|  | @ -1623,13 +1635,13 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 			continue; | ||||
| 
 | ||||
| 		case LOAD_CLOSURE: | ||||
| 			x = PyTuple_GET_ITEM(f->f_closure, oparg); | ||||
| 			x = freevars[oparg]; | ||||
| 			Py_INCREF(x); | ||||
| 			PUSH(x); | ||||
| 			break; | ||||
| 
 | ||||
| 		case LOAD_DEREF: | ||||
| 			x = PyTuple_GET_ITEM(f->f_closure, oparg); | ||||
| 			x = freevars[oparg]; | ||||
| 			w = PyCell_Get(x); | ||||
| 			Py_INCREF(w); | ||||
| 			PUSH(w); | ||||
|  | @ -1637,7 +1649,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | |||
| 
 | ||||
| 		case STORE_DEREF: | ||||
| 			w = POP(); | ||||
| 			x = PyTuple_GET_ITEM(f->f_closure, oparg); | ||||
| 			x = freevars[oparg]; | ||||
| 			PyCell_Set(x, w); | ||||
| 			continue; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Hylton
						Jeremy Hylton