mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Issue #27809: map_next() uses fast call
Use a small stack allocated in the C stack for up to 5 iterator functions, otherwise allocates a stack on the heap memory.
This commit is contained in:
		
							parent
							
								
									f428521481
								
							
						
					
					
						commit
						a9ba1ab21b
					
				
					 1 changed files with 33 additions and 17 deletions
				
			
		|  | @ -1156,27 +1156,43 @@ map_traverse(mapobject *lz, visitproc visit, void *arg) | |||
| static PyObject * | ||||
| map_next(mapobject *lz) | ||||
| { | ||||
|     PyObject *val; | ||||
|     PyObject *argtuple; | ||||
|     PyObject *result; | ||||
|     Py_ssize_t numargs, i; | ||||
|     PyObject *small_stack[5]; | ||||
|     PyObject **stack; | ||||
|     Py_ssize_t niters, nargs, i; | ||||
|     PyObject *result = NULL; | ||||
| 
 | ||||
|     numargs = PyTuple_GET_SIZE(lz->iters); | ||||
|     argtuple = PyTuple_New(numargs); | ||||
|     if (argtuple == NULL) | ||||
|     niters = PyTuple_GET_SIZE(lz->iters); | ||||
|     if (niters <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { | ||||
|         stack = small_stack; | ||||
|     } | ||||
|     else { | ||||
|         stack = PyMem_Malloc(niters * sizeof(PyObject*)); | ||||
|         if (stack == NULL) { | ||||
|             PyErr_NoMemory(); | ||||
|             return NULL; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     for (i=0 ; i<numargs ; i++) { | ||||
|     nargs = 0; | ||||
|     for (i=0; i < niters; i++) { | ||||
|         PyObject *it = PyTuple_GET_ITEM(lz->iters, i); | ||||
|         val = Py_TYPE(it)->tp_iternext(it); | ||||
|         PyObject *val = Py_TYPE(it)->tp_iternext(it); | ||||
|         if (val == NULL) { | ||||
|             Py_DECREF(argtuple); | ||||
|             return NULL; | ||||
|             goto exit; | ||||
|         } | ||||
|         PyTuple_SET_ITEM(argtuple, i, val); | ||||
|         stack[i] = val; | ||||
|         nargs++; | ||||
|     } | ||||
| 
 | ||||
|     result = _PyObject_FastCall(lz->func, stack, nargs); | ||||
| 
 | ||||
| exit: | ||||
|     for (i=0; i < nargs; i++) { | ||||
|         Py_DECREF(stack[i]); | ||||
|     } | ||||
|     if (stack != small_stack) { | ||||
|         PyMem_Free(stack); | ||||
|     } | ||||
|     result = PyObject_Call(lz->func, argtuple, NULL); | ||||
|     Py_DECREF(argtuple); | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner