extern void _Py_Specialize_Send(_PyStackRef receiver, _Py_CODEUNIT *instr);
extern void _Py_Specialize_ToBool(_PyStackRef value, _Py_CODEUNIT *instr);
extern void _Py_Specialize_ContainsOp(_PyStackRef value, _Py_CODEUNIT *instr);
+extern void _Py_GatherStats_GetIter(_PyStackRef iterable);
// Utility functions for reading/writing 32/64-bit values in the inline caches.
// Great care should be taken to ensure that these functions remain correct and
_PyStackRef iterable;
_PyStackRef iter;
iterable = stack_pointer[-1];
+ #ifdef Py_STATS
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ _Py_GatherStats_GetIter(iterable);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ #endif
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable));
stack_pointer = _PyFrame_GetStackPointer(frame);
_PyStackRef iterable;
_PyStackRef iter;
iterable = stack_pointer[-1];
+ #ifdef Py_STATS
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ _Py_GatherStats_GetIter(iterable);
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ #endif
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable));
stack_pointer = _PyFrame_GetStackPointer(frame);
* even though we don't specialize them yet. */
fprintf(out, "opcode[BINARY_SLICE].specializable : 1\n");
fprintf(out, "opcode[STORE_SLICE].specializable : 1\n");
+ fprintf(out, "opcode[GET_ITER].specializable : 1\n");
for (int i = 0; i < 256; i++) {
if (_PyOpcode_Caches[i]) {
/* Ignore jumps as they cannot be specialized */
#define SPEC_FAIL_ITER_CALLABLE 28
#define SPEC_FAIL_ITER_ASCII_STRING 29
#define SPEC_FAIL_ITER_ASYNC_GENERATOR_SEND 30
+#define SPEC_FAIL_ITER_SELF 31
// UNPACK_SEQUENCE
return;
}
+#ifdef Py_STATS
+void
+_Py_GatherStats_GetIter(_PyStackRef iterable)
+{
+ PyTypeObject *tp = PyStackRef_TYPE(iterable);
+ int kind = SPEC_FAIL_OTHER;
+ if (tp == &PyTuple_Type) {
+ kind = SPEC_FAIL_ITER_TUPLE;
+ }
+ else if (tp == &PyList_Type) {
+ kind = SPEC_FAIL_ITER_LIST;
+ }
+ else if (tp == &PyDict_Type) {
+ kind = SPEC_FAIL_ITER_DICT_KEYS;
+ }
+ else if (tp == &PySet_Type) {
+ kind = SPEC_FAIL_ITER_SET;
+ }
+ else if (tp == &PyBytes_Type) {
+ kind = SPEC_FAIL_ITER_BYTES;
+ }
+ else if (tp == &PyEnum_Type) {
+ kind = SPEC_FAIL_ITER_ENUMERATE;
+ }
+ else if (tp == &PyUnicode_Type) {
+ kind = SPEC_FAIL_ITER_STRING;
+ }
+ else if (tp == &PyGen_Type) {
+ kind = SPEC_FAIL_ITER_GENERATOR;
+ }
+ else if (tp == &PyCoro_Type) {
+ kind = SPEC_FAIL_ITER_COROUTINE;
+ }
+ else if (tp == &PyAsyncGen_Type) {
+ kind = SPEC_FAIL_ITER_ASYNC_GENERATOR;
+ }
+ else if (tp == &_PyAsyncGenASend_Type) {
+ kind = SPEC_FAIL_ITER_ASYNC_GENERATOR_SEND;
+ }
+ else if (tp->tp_iter == PyObject_SelfIter) {
+ kind = SPEC_FAIL_ITER_SELF;
+ }
+ SPECIALIZATION_FAIL(GET_ITER, kind);
+}
+#endif
+
+
/* Code init cleanup.
* CALL_ALLOC_AND_ENTER_INIT will set up
* the frame to execute the EXIT_INIT_CHECK