summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-06-30 21:03:37 (GMT)
committerGitHub <noreply@github.com>2022-06-30 21:03:37 (GMT)
commit113b309f18103343a195f7c53c41763acf295167 (patch)
tree4c4792ad8d608f454e0895fda41539b546d347b7 /Python/ceval.c
parent6c405381918a358a62ce72798dd37c2a3d2a9be2 (diff)
downloadcpython-113b309f18103343a195f7c53c41763acf295167.zip
cpython-113b309f18103343a195f7c53c41763acf295167.tar.gz
cpython-113b309f18103343a195f7c53c41763acf295167.tar.bz2
[3.11] GH-93354: Use exponential backoff to avoid excessive specialization attempts (GH-93355) (GH-93379)
Co-authored-by: Mark Shannon <mark@hotpy.org> Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index b868161..a2c1d0b 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1559,7 +1559,11 @@ eval_frame_handle_pending(PyThreadState *tstate)
dtrace_function_entry(frame); \
}
+#define ADAPTIVE_COUNTER_IS_ZERO(cache) \
+ (cache)->counter < (1<<ADAPTIVE_BACKOFF_BITS)
+#define DECREMENT_ADAPTIVE_COUNTER(cache) \
+ (cache)->counter -= (1<<ADAPTIVE_BACKOFF_BITS)
static int
trace_function_entry(PyThreadState *tstate, _PyInterpreterFrame *frame)
@@ -2154,7 +2158,7 @@ handle_eval_breaker:
TARGET(BINARY_SUBSCR_ADAPTIVE) {
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
PyObject *sub = TOP();
PyObject *container = SECOND();
next_instr--;
@@ -2165,7 +2169,7 @@ handle_eval_breaker:
}
else {
STAT_INC(BINARY_SUBSCR, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
JUMP_TO_INSTRUCTION(BINARY_SUBSCR);
}
}
@@ -2319,7 +2323,7 @@ handle_eval_breaker:
TARGET(STORE_SUBSCR_ADAPTIVE) {
_PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
PyObject *sub = TOP();
PyObject *container = SECOND();
next_instr--;
@@ -2330,7 +2334,7 @@ handle_eval_breaker:
}
else {
STAT_INC(STORE_SUBSCR, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
JUMP_TO_INSTRUCTION(STORE_SUBSCR);
}
}
@@ -2812,7 +2816,7 @@ handle_eval_breaker:
TARGET(UNPACK_SEQUENCE_ADAPTIVE) {
assert(cframe.use_tracing == 0);
_PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
PyObject *seq = TOP();
next_instr--;
_Py_Specialize_UnpackSequence(seq, next_instr, oparg);
@@ -2820,7 +2824,7 @@ handle_eval_breaker:
}
else {
STAT_INC(UNPACK_SEQUENCE, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
JUMP_TO_INSTRUCTION(UNPACK_SEQUENCE);
}
}
@@ -3053,7 +3057,7 @@ handle_eval_breaker:
TARGET(LOAD_GLOBAL_ADAPTIVE) {
assert(cframe.use_tracing == 0);
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
PyObject *name = GETITEM(names, oparg>>1);
next_instr--;
if (_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name) < 0) {
@@ -3063,7 +3067,7 @@ handle_eval_breaker:
}
else {
STAT_INC(LOAD_GLOBAL, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
JUMP_TO_INSTRUCTION(LOAD_GLOBAL);
}
}
@@ -3477,7 +3481,7 @@ handle_eval_breaker:
TARGET(LOAD_ATTR_ADAPTIVE) {
assert(cframe.use_tracing == 0);
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
PyObject *owner = TOP();
PyObject *name = GETITEM(names, oparg);
next_instr--;
@@ -3488,7 +3492,7 @@ handle_eval_breaker:
}
else {
STAT_INC(LOAD_ATTR, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
JUMP_TO_INSTRUCTION(LOAD_ATTR);
}
}
@@ -3586,7 +3590,7 @@ handle_eval_breaker:
TARGET(STORE_ATTR_ADAPTIVE) {
assert(cframe.use_tracing == 0);
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
PyObject *owner = TOP();
PyObject *name = GETITEM(names, oparg);
next_instr--;
@@ -3597,7 +3601,7 @@ handle_eval_breaker:
}
else {
STAT_INC(STORE_ATTR, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
JUMP_TO_INSTRUCTION(STORE_ATTR);
}
}
@@ -3716,7 +3720,7 @@ handle_eval_breaker:
TARGET(COMPARE_OP_ADAPTIVE) {
assert(cframe.use_tracing == 0);
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
PyObject *right = TOP();
PyObject *left = SECOND();
next_instr--;
@@ -3725,7 +3729,7 @@ handle_eval_breaker:
}
else {
STAT_INC(COMPARE_OP, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
JUMP_TO_INSTRUCTION(COMPARE_OP);
}
}
@@ -4523,7 +4527,7 @@ handle_eval_breaker:
TARGET(LOAD_METHOD_ADAPTIVE) {
assert(cframe.use_tracing == 0);
_PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
PyObject *owner = TOP();
PyObject *name = GETITEM(names, oparg);
next_instr--;
@@ -4534,7 +4538,7 @@ handle_eval_breaker:
}
else {
STAT_INC(LOAD_METHOD, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
JUMP_TO_INSTRUCTION(LOAD_METHOD);
}
}
@@ -4815,7 +4819,7 @@ handle_eval_breaker:
TARGET(CALL_ADAPTIVE) {
_PyCallCache *cache = (_PyCallCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
next_instr--;
int is_meth = is_method(stack_pointer, oparg);
int nargs = oparg + is_meth;
@@ -4829,7 +4833,7 @@ handle_eval_breaker:
}
else {
STAT_INC(CALL, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
goto call_function;
}
}
@@ -5560,7 +5564,7 @@ handle_eval_breaker:
TARGET(BINARY_OP_ADAPTIVE) {
assert(cframe.use_tracing == 0);
_PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
- if (cache->counter == 0) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {
PyObject *lhs = SECOND();
PyObject *rhs = TOP();
next_instr--;
@@ -5569,7 +5573,7 @@ handle_eval_breaker:
}
else {
STAT_INC(BINARY_OP, deferred);
- cache->counter--;
+ DECREMENT_ADAPTIVE_COUNTER(cache);
JUMP_TO_INSTRUCTION(BINARY_OP);
}
}
@@ -5690,7 +5694,7 @@ miss:
assert(adaptive_opcode);
_Py_SET_OPCODE(next_instr[-1], adaptive_opcode);
STAT_INC(opcode, deopt);
- *counter = ADAPTIVE_CACHE_BACKOFF;
+ *counter = adaptive_counter_start();
}
next_instr--;
DISPATCH_GOTO();