@@ -212,27 +212,6 @@ PyUnstable_GetExecutor(PyCodeObject *code, int offset)
212
212
return NULL ;
213
213
}
214
214
215
- /** Test support **/
216
-
217
-
218
- typedef struct {
219
- _PyOptimizerObject base ;
220
- int64_t count ;
221
- } _PyCounterOptimizerObject ;
222
-
223
- typedef struct {
224
- _PyExecutorObject executor ;
225
- _PyCounterOptimizerObject * optimizer ;
226
- _Py_CODEUNIT * next_instr ;
227
- } _PyCounterExecutorObject ;
228
-
229
- static void
230
- counter_dealloc (_PyCounterExecutorObject * self ) {
231
- _Py_ExecutorClear ((_PyExecutorObject * )self );
232
- Py_DECREF (self -> optimizer );
233
- PyObject_Free (self );
234
- }
235
-
236
215
static PyObject *
237
216
is_valid (PyObject * self , PyObject * Py_UNUSED (ignored ))
238
217
{
@@ -244,84 +223,6 @@ static PyMethodDef executor_methods[] = {
244
223
{ NULL , NULL },
245
224
};
246
225
247
- PyTypeObject _PyCounterExecutor_Type = {
248
- PyVarObject_HEAD_INIT (& PyType_Type , 0 )
249
- .tp_name = "counting_executor" ,
250
- .tp_basicsize = sizeof (_PyCounterExecutorObject ),
251
- .tp_itemsize = 0 ,
252
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION ,
253
- .tp_dealloc = (destructor )counter_dealloc ,
254
- .tp_methods = executor_methods ,
255
- };
256
-
257
- static _Py_CODEUNIT *
258
- counter_execute (_PyExecutorObject * self , _PyInterpreterFrame * frame , PyObject * * stack_pointer )
259
- {
260
- ((_PyCounterExecutorObject * )self )-> optimizer -> count ++ ;
261
- _PyFrame_SetStackPointer (frame , stack_pointer );
262
- Py_DECREF (self );
263
- return ((_PyCounterExecutorObject * )self )-> next_instr ;
264
- }
265
-
266
- static int
267
- counter_optimize (
268
- _PyOptimizerObject * self ,
269
- PyCodeObject * code ,
270
- _Py_CODEUNIT * instr ,
271
- _PyExecutorObject * * exec_ptr ,
272
- int Py_UNUSED (curr_stackentries )
273
- )
274
- {
275
- _PyCounterExecutorObject * executor = (_PyCounterExecutorObject * )_PyObject_New (& _PyCounterExecutor_Type );
276
- if (executor == NULL ) {
277
- return -1 ;
278
- }
279
- executor -> executor .execute = counter_execute ;
280
- Py_INCREF (self );
281
- executor -> optimizer = (_PyCounterOptimizerObject * )self ;
282
- executor -> next_instr = instr ;
283
- * exec_ptr = (_PyExecutorObject * )executor ;
284
- _PyBloomFilter empty ;
285
- _Py_BloomFilter_Init (& empty );
286
- _Py_ExecutorInit ((_PyExecutorObject * )executor , & empty );
287
- return 1 ;
288
- }
289
-
290
- static PyObject *
291
- counter_get_counter (PyObject * self , PyObject * args )
292
- {
293
- return PyLong_FromLongLong (((_PyCounterOptimizerObject * )self )-> count );
294
- }
295
-
296
- static PyMethodDef counter_optimizer_methods [] = {
297
- { "get_count" , counter_get_counter , METH_NOARGS , NULL },
298
- { NULL , NULL },
299
- };
300
-
301
- PyTypeObject _PyCounterOptimizer_Type = {
302
- PyVarObject_HEAD_INIT (& PyType_Type , 0 )
303
- .tp_name = "Counter optimizer" ,
304
- .tp_basicsize = sizeof (_PyCounterOptimizerObject ),
305
- .tp_itemsize = 0 ,
306
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION ,
307
- .tp_methods = counter_optimizer_methods ,
308
- .tp_dealloc = (destructor )PyObject_Del ,
309
- };
310
-
311
- PyObject *
312
- PyUnstable_Optimizer_NewCounter (void )
313
- {
314
- _PyCounterOptimizerObject * opt = (_PyCounterOptimizerObject * )_PyObject_New (& _PyCounterOptimizer_Type );
315
- if (opt == NULL ) {
316
- return NULL ;
317
- }
318
- opt -> base .optimize = counter_optimize ;
319
- opt -> base .resume_threshold = INT16_MAX ;
320
- opt -> base .backedge_threshold = 0 ;
321
- opt -> count = 0 ;
322
- return (PyObject * )opt ;
323
- }
324
-
325
226
///////////////////// Experimental UOp Optimizer /////////////////////
326
227
327
228
static void
@@ -381,7 +282,7 @@ PySequenceMethods uop_as_sequence = {
381
282
PyTypeObject _PyUOpExecutor_Type = {
382
283
PyVarObject_HEAD_INIT (& PyType_Type , 0 )
383
284
.tp_name = "uop_executor" ,
384
- .tp_basicsize = sizeof (_PyUOpExecutorObject ) - sizeof ( _PyUOpInstruction ),
285
+ .tp_basicsize = offsetof (_PyUOpExecutorObject , trace ),
385
286
.tp_itemsize = sizeof (_PyUOpInstruction ),
386
287
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION ,
387
288
.tp_dealloc = (destructor )uop_dealloc ,
@@ -843,7 +744,6 @@ make_executor_from_uops(_PyUOpInstruction *buffer, _PyBloomFilter *dependencies)
843
744
dest -- ;
844
745
}
845
746
assert (dest == -1 );
846
- executor -> base .execute = _PyUOpExecute ;
847
747
_Py_ExecutorInit ((_PyExecutorObject * )executor , dependencies );
848
748
#ifdef Py_DEBUG
849
749
char * python_lltrace = Py_GETENV ("PYTHON_LLTRACE" );
@@ -899,15 +799,6 @@ uop_optimize(
899
799
return 1 ;
900
800
}
901
801
902
- /* Dummy execute() function for UOp Executor.
903
- * The actual implementation is inlined in ceval.c,
904
- * in _PyEval_EvalFrameDefault(). */
905
- _Py_CODEUNIT *
906
- _PyUOpExecute (_PyExecutorObject * executor , _PyInterpreterFrame * frame , PyObject * * stack_pointer )
907
- {
908
- Py_FatalError ("Tier 2 is now inlined into Tier 1" );
909
- }
910
-
911
802
static void
912
803
uop_opt_dealloc (PyObject * self ) {
913
804
PyObject_Free (self );
@@ -937,6 +828,84 @@ PyUnstable_Optimizer_NewUOpOptimizer(void)
937
828
return (PyObject * )opt ;
938
829
}
939
830
831
+ static void
832
+ counter_dealloc (_PyUOpExecutorObject * self ) {
833
+ PyObject * opt = (PyObject * )self -> trace [0 ].operand ;
834
+ Py_DECREF (opt );
835
+ uop_dealloc (self );
836
+ }
837
+
838
+ PyTypeObject _PyCounterExecutor_Type = {
839
+ PyVarObject_HEAD_INIT (& PyType_Type , 0 )
840
+ .tp_name = "counting_executor" ,
841
+ .tp_basicsize = offsetof(_PyUOpExecutorObject , trace ),
842
+ .tp_itemsize = sizeof (_PyUOpInstruction ),
843
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION ,
844
+ .tp_dealloc = (destructor )counter_dealloc ,
845
+ .tp_methods = executor_methods ,
846
+ };
847
+
848
+ static int
849
+ counter_optimize (
850
+ _PyOptimizerObject * self ,
851
+ PyCodeObject * code ,
852
+ _Py_CODEUNIT * instr ,
853
+ _PyExecutorObject * * exec_ptr ,
854
+ int Py_UNUSED (curr_stackentries )
855
+ )
856
+ {
857
+ _PyUOpInstruction buffer [3 ] = {
858
+ { .opcode = _LOAD_CONST_INLINE_BORROW , .operand = (uintptr_t )self },
859
+ { .opcode = _INTERNAL_INCREMENT_OPT_COUNTER },
860
+ { .opcode = _EXIT_TRACE , .target = (uint32_t )(instr - _PyCode_CODE (code )) }
861
+ };
862
+ _PyBloomFilter empty ;
863
+ _Py_BloomFilter_Init (& empty );
864
+ _PyExecutorObject * executor = make_executor_from_uops (buffer , & empty );
865
+ if (executor == NULL ) {
866
+ return -1 ;
867
+ }
868
+ Py_INCREF (self );
869
+ Py_SET_TYPE (executor , & _PyCounterExecutor_Type );
870
+ * exec_ptr = executor ;
871
+ return 1 ;
872
+ }
873
+
874
+ static PyObject *
875
+ counter_get_counter (PyObject * self , PyObject * args )
876
+ {
877
+ return PyLong_FromLongLong (((_PyCounterOptimizerObject * )self )-> count );
878
+ }
879
+
880
+ static PyMethodDef counter_optimizer_methods [] = {
881
+ { "get_count" , counter_get_counter , METH_NOARGS , NULL },
882
+ { NULL , NULL },
883
+ };
884
+
885
+ PyTypeObject _PyCounterOptimizer_Type = {
886
+ PyVarObject_HEAD_INIT (& PyType_Type , 0 )
887
+ .tp_name = "Counter optimizer" ,
888
+ .tp_basicsize = sizeof (_PyCounterOptimizerObject ),
889
+ .tp_itemsize = 0 ,
890
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION ,
891
+ .tp_methods = counter_optimizer_methods ,
892
+ .tp_dealloc = (destructor )PyObject_Del ,
893
+ };
894
+
895
+ PyObject *
896
+ PyUnstable_Optimizer_NewCounter (void )
897
+ {
898
+ _PyCounterOptimizerObject * opt = (_PyCounterOptimizerObject * )_PyObject_New (& _PyCounterOptimizer_Type );
899
+ if (opt == NULL ) {
900
+ return NULL ;
901
+ }
902
+ opt -> base .optimize = counter_optimize ;
903
+ opt -> base .resume_threshold = INT16_MAX ;
904
+ opt -> base .backedge_threshold = 0 ;
905
+ opt -> count = 0 ;
906
+ return (PyObject * )opt ;
907
+ }
908
+
940
909
941
910
/*****************************************
942
911
* Executor management
0 commit comments