Normalize jumps in compiler. All forward jumps to use JUMP_FORWARD. (GH-28755)

This commit is contained in:
Mark Shannon 2021-10-06 13:05:45 +01:00 committed by GitHub
parent c379bc5ec9
commit f6eafe18c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 14 deletions

View file

@ -4051,19 +4051,18 @@ check_eval_breaker:
TARGET(JUMP_ABSOLUTE) {
PREDICTED(JUMP_ABSOLUTE);
if (oparg < INSTR_OFFSET()) {
/* Increment the warmup counter and quicken if warm enough
* _Py_Quicken is idempotent so we don't worry about overflow */
if (!PyCodeObject_IsWarmedUp(co)) {
PyCodeObject_IncrementWarmup(co);
if (PyCodeObject_IsWarmedUp(co)) {
if (_Py_Quicken(co)) {
goto error;
}
int nexti = INSTR_OFFSET();
first_instr = co->co_firstinstr;
next_instr = first_instr + nexti;
assert(oparg < INSTR_OFFSET());
/* Increment the warmup counter and quicken if warm enough
* _Py_Quicken is idempotent so we don't worry about overflow */
if (!PyCodeObject_IsWarmedUp(co)) {
PyCodeObject_IncrementWarmup(co);
if (PyCodeObject_IsWarmedUp(co)) {
if (_Py_Quicken(co)) {
goto error;
}
int nexti = INSTR_OFFSET();
first_instr = co->co_firstinstr;
next_instr = first_instr + nexti;
}
}
JUMPTO(oparg);
@ -4072,6 +4071,7 @@ check_eval_breaker:
}
TARGET(JUMP_ABSOLUTE_QUICK) {
assert(oparg < INSTR_OFFSET());
JUMPTO(oparg);
CHECK_EVAL_BREAKER();
DISPATCH();

View file

@ -7220,6 +7220,26 @@ assemble_emit(struct assembler *a, struct instr *i)
return 1;
}
static void
normalize_jumps(struct assembler *a)
{
for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) {
b->b_visited = 0;
}
for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) {
b->b_visited = 1;
if (b->b_iused == 0) {
continue;
}
struct instr *last = &b->b_instr[b->b_iused-1];
if (last->i_opcode == JUMP_ABSOLUTE &&
last->i_target->b_visited == 0
) {
last->i_opcode = JUMP_FORWARD;
}
}
}
static void
assemble_jump_offsets(struct assembler *a, struct compiler *c)
{
@ -7897,6 +7917,9 @@ assemble(struct compiler *c, int addNone)
clean_basic_block(b);
}
/* Order of basic blocks must have been determined by now */
normalize_jumps(&a);
/* Can't modify the bytecode after computing jump offsets. */
assemble_jump_offsets(&a, c);