Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7b21403

Browse filesBrowse files
authored
GH-112354: Initial implementation of warm up on exits and trace-stitching (GH-114142)
1 parent acda175 commit 7b21403
Copy full SHA for 7b21403
Expand file treeCollapse file tree

29 files changed

+744
-198
lines changed

‎.gitattributes

Copy file name to clipboardExpand all lines: .gitattributes
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ Include/internal/pycore_opcode.h generated
7777
Include/internal/pycore_opcode_metadata.h generated
7878
Include/internal/pycore_*_generated.h generated
7979
Include/internal/pycore_uop_ids.h generated
80+
Include/internal/pycore_uop_metadata.h generated
8081
Include/opcode.h generated
8182
Include/opcode_ids.h generated
8283
Include/token.h generated

‎Include/cpython/optimizer.h

Copy file name to clipboardExpand all lines: Include/cpython/optimizer.h
+19-6Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,28 @@ typedef struct {
3333
typedef struct {
3434
uint16_t opcode;
3535
uint16_t oparg;
36-
uint32_t target;
36+
union {
37+
uint32_t target;
38+
uint32_t exit_index;
39+
};
3740
uint64_t operand; // A cache entry
3841
} _PyUOpInstruction;
3942

43+
typedef struct _exit_data {
44+
uint32_t target;
45+
int16_t temperature;
46+
const struct _PyExecutorObject *executor;
47+
} _PyExitData;
48+
4049
typedef struct _PyExecutorObject {
4150
PyObject_VAR_HEAD
51+
const _PyUOpInstruction *trace;
4252
_PyVMData vm_data; /* Used by the VM, but opaque to the optimizer */
43-
void *jit_code;
53+
uint32_t exit_count;
54+
uint32_t code_size;
4455
size_t jit_size;
45-
_PyUOpInstruction trace[1];
56+
void *jit_code;
57+
_PyExitData exits[1];
4658
} _PyExecutorObject;
4759

4860
typedef struct _PyOptimizerObject _PyOptimizerObject;
@@ -59,6 +71,7 @@ typedef struct _PyOptimizerObject {
5971
/* These thresholds are treated as signed so do not exceed INT16_MAX
6072
* Use INT16_MAX to indicate that the optimizer should never be called */
6173
uint16_t resume_threshold;
74+
uint16_t side_threshold;
6275
uint16_t backedge_threshold;
6376
/* Data needed by the optimizer goes here, but is opaque to the VM */
6477
} _PyOptimizerObject;
@@ -73,16 +86,16 @@ PyAPI_FUNC(int) PyUnstable_Replace_Executor(PyCodeObject *code, _Py_CODEUNIT *in
7386

7487
_PyOptimizerObject *_Py_SetOptimizer(PyInterpreterState *interp, _PyOptimizerObject* optimizer);
7588

76-
PyAPI_FUNC(void) PyUnstable_SetOptimizer(_PyOptimizerObject* optimizer);
89+
PyAPI_FUNC(int) PyUnstable_SetOptimizer(_PyOptimizerObject* optimizer);
7790

7891
PyAPI_FUNC(_PyOptimizerObject *) PyUnstable_GetOptimizer(void);
7992

8093
PyAPI_FUNC(_PyExecutorObject *) PyUnstable_GetExecutor(PyCodeObject *code, int offset);
8194

8295
int
83-
_PyOptimizer_Optimize(struct _PyInterpreterFrame *frame, _Py_CODEUNIT *start, PyObject **stack_pointer);
96+
_PyOptimizer_Optimize(struct _PyInterpreterFrame *frame, _Py_CODEUNIT *start, PyObject **stack_pointer, _PyExecutorObject **exec_ptr);
8497

85-
void _Py_ExecutorInit(_PyExecutorObject *, _PyBloomFilter *);
98+
void _Py_ExecutorInit(_PyExecutorObject *, const _PyBloomFilter *);
8699
void _Py_ExecutorClear(_PyExecutorObject *);
87100
void _Py_BloomFilter_Init(_PyBloomFilter *);
88101
void _Py_BloomFilter_Add(_PyBloomFilter *bloom, void *obj);

‎Include/cpython/pystate.h

Copy file name to clipboardExpand all lines: Include/cpython/pystate.h
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ struct _ts {
212212
/* The thread's exception stack entry. (Always the last entry.) */
213213
_PyErr_StackItem exc_state;
214214

215+
PyObject *previous_executor;
216+
215217
};
216218

217219
#ifdef Py_DEBUG

‎Include/internal/pycore_interp.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_interp.h
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,13 @@ struct _is {
237237
struct callable_cache callable_cache;
238238
_PyOptimizerObject *optimizer;
239239
_PyExecutorObject *executor_list_head;
240-
/* These values are shifted and offset to speed up check in JUMP_BACKWARD */
240+
241+
/* These two values are shifted and offset to speed up check in JUMP_BACKWARD */
241242
uint32_t optimizer_resume_threshold;
242243
uint32_t optimizer_backedge_threshold;
243244

245+
uint16_t optimizer_side_threshold;
246+
244247
uint32_t next_func_version;
245248
_rare_events rare_events;
246249
PyDict_WatchCallback builtins_dict_watcher;

‎Include/internal/pycore_jit.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_jit.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extern "C" {
1313

1414
typedef _Py_CODEUNIT *(*jit_func)(_PyInterpreterFrame *frame, PyObject **stack_pointer, PyThreadState *tstate);
1515

16-
int _PyJIT_Compile(_PyExecutorObject *executor, _PyUOpInstruction *trace, size_t length);
16+
int _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction *trace, size_t length);
1717
void _PyJIT_Free(_PyExecutorObject *executor);
1818

1919
#endif // _Py_JIT

‎Include/internal/pycore_opcode_metadata.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_opcode_metadata.h
+28-26Lines changed: 28 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Include/internal/pycore_uop_ids.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_uop_ids.h
+5-3Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Include/internal/pycore_uop_metadata.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_uop_metadata.h
+21-15Lines changed: 21 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Lib/test/test_frame.py

Copy file name to clipboardExpand all lines: Lib/test/test_frame.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ def f():
331331
# on the *very next* allocation:
332332
gc.collect()
333333
gc.set_threshold(1, 0, 0)
334+
sys._clear_internal_caches()
334335
# Okay, so here's the nightmare scenario:
335336
# - We're tracing the resumption of a generator, which creates a new
336337
# frame object.

‎Lib/test/test_generated_cases.py

Copy file name to clipboardExpand all lines: Lib/test/test_generated_cases.py
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,17 @@ def test_annotated_op(self):
794794
self.run_cases_test(input, output)
795795

796796

797+
def test_deopt_and_exit(self):
798+
input = """
799+
pure op(OP, (arg1 -- out)) {
800+
DEOPT_IF(1);
801+
EXIT_IF(1);
802+
}
803+
"""
804+
output = ""
805+
with self.assertRaises(Exception):
806+
self.run_cases_test(input, output)
807+
797808
class TestGeneratedAbstractCases(unittest.TestCase):
798809
def setUp(self) -> None:
799810
super().setUp()

‎Modules/_testinternalcapi.c

Copy file name to clipboardExpand all lines: Modules/_testinternalcapi.c
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,9 @@ set_optimizer(PyObject *self, PyObject *opt)
977977
if (opt == Py_None) {
978978
opt = NULL;
979979
}
980-
PyUnstable_SetOptimizer((_PyOptimizerObject*)opt);
980+
if (PyUnstable_SetOptimizer((_PyOptimizerObject*)opt) < 0) {
981+
return NULL;
982+
}
981983
Py_RETURN_NONE;
982984
}
983985

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.