Skip to content

Commit cf6098d

Browse files
committed
Attempting to work out pythongh-106608
1 parent ecc05e2 commit cf6098d

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

Include/internal/pycore_uops.h

+12-1
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,26 @@ typedef struct {
1717
} _PyUOpInstruction;
1818

1919
typedef struct {
20+
PyObject_VAR_HEAD
2021
_PyExecutorObject base;
21-
_PyUOpInstruction trace[_Py_UOP_MAX_TRACE_LENGTH]; // TODO: variable length
22+
_PyUOpInstruction trace[1];
2223
} _PyUOpExecutorObject;
2324

2425
_PyInterpreterFrame *_PyUopExecute(
2526
_PyExecutorObject *executor,
2627
_PyInterpreterFrame *frame,
2728
PyObject **stack_pointer);
2829

30+
/* Cast argument to _PyUOpExecutorObject* type. */
31+
#define _PyUOpExecutor_CAST(op) \
32+
_Py_CAST(_PyUOpExecutorObject*, (op))
33+
34+
static inline Py_ssize_t PyUOpExecutor_GET_SIZE(PyObject *op) {
35+
_PyUOpExecutorObject *executor = _PyUOpExecutor_CAST(op);
36+
return Py_SIZE(executor);
37+
}
38+
#define PyUOpExecutor_GET_SIZE(op) PyUOpExecutor_GET_SIZE(_PyObject_CAST(op))
39+
2940
#ifdef __cplusplus
3041
}
3142
#endif

Python/executor.c

+33
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,39 @@
3131
#define ENABLE_SPECIALIZATION 0
3232

3333

34+
// TODO: continue editing this from tupleobject.c to fit _PyUOpExecutorObject
35+
static _PyUOpExecutorObject *
36+
tuple_alloc(Py_ssize_t size)
37+
{
38+
_PyUOpExecutorObject *op = maybe_freelist_pop(size);
39+
if (op == NULL) {
40+
/* Check for overflow */
41+
if ((size_t)size > ((size_t)PY_SSIZE_T_MAX - (sizeof(PyTupleObject) -
42+
sizeof(PyObject *))) / sizeof(PyObject *)) {
43+
return (_PyUOpExecutorObject *)PyErr_NoMemory();
44+
}
45+
op = PyObject_GC_NewVar(_PyUOpExecutorObject, &PyTuple_Type, size);
46+
if (op == NULL)
47+
return NULL;
48+
}
49+
return op;
50+
}
51+
52+
PyObject *
53+
PyUOpExecutor_New(_PyUOpInstruction trace[], Py_ssize_t size)
54+
{
55+
_PyUOpExecutorObject *op;
56+
op = tuple_alloc(size);
57+
if (op == NULL) {
58+
return NULL;
59+
}
60+
for (Py_ssize_t i = 0; i < size; i++) {
61+
op->trace[i] = trace[i];
62+
}
63+
_PyObject_GC_TRACK(op);
64+
return (PyObject *) op;
65+
}
66+
3467
_PyInterpreterFrame *
3568
_PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject **stack_pointer)
3669
{

Python/optimizer.c

+5-7
Original file line numberDiff line numberDiff line change
@@ -320,13 +320,7 @@ uop_name(int index) {
320320
static Py_ssize_t
321321
uop_len(_PyUOpExecutorObject *self)
322322
{
323-
int count = 0;
324-
for (; count < _Py_UOP_MAX_TRACE_LENGTH; count++) {
325-
if (self->trace[count].opcode == 0) {
326-
break;
327-
}
328-
}
329-
return count;
323+
return PyUOpExecutor_GET_SIZE(self);
330324
}
331325

332326
static PyObject *
@@ -703,6 +697,10 @@ uop_optimize(
703697
return -1;
704698
}
705699
executor->base.execute = _PyUopExecute;
700+
/*
701+
This should replace PyObject_New and memcpy
702+
_PyUOpExecutorObject *executor = PyUOpExecutor_New(trace, trace_length);
703+
*/
706704
memcpy(executor->trace, trace, trace_length * sizeof(_PyUOpInstruction));
707705
if (trace_length < _Py_UOP_MAX_TRACE_LENGTH) {
708706
executor->trace[trace_length].opcode = 0; // Sentinel

0 commit comments

Comments
 (0)