Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Include/opcode.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions Lib/dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
_cache_format,
_inline_cache_entries,
_nb_ops,
_opsize,
_specializations,
_specialized_instructions,
)
Expand Down Expand Up @@ -433,7 +434,8 @@ def _get_co_positions(code, show_caches=False):
ops = code.co_code[::2]
prev_op = 0
for op, positions in zip(ops, code.co_positions()):
if prev_op != 0:
assert _opsize in (1, 2)
if _opsize == 2 and prev_op != 0:
# skip oparg2, oparg3
prev_op = op
continue
Expand Down Expand Up @@ -495,7 +497,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
argrepr = "to " + repr(argval)
elif deop in hasjrel:
signed_arg = -arg if _is_backward_jump(deop) else arg
argval = offset + (signed_arg + 2) * 2
argval = offset + (signed_arg + _opsize) * 2
if deop == FOR_ITER:
argval += 2
argrepr = "to " + repr(argval)
Expand Down Expand Up @@ -627,7 +629,7 @@ def _unpack_opargs(code):
op = code[i]
deop = _deoptop(op)
caches = _inline_cache_entries[deop]
caches += 1 # also skip over arg2, arg3
caches += _opsize - 1 # also skip over oparg2, oparg3
if deop in hasarg:
arg = code[i+1] | extended_arg
extended_arg = (arg << 8) if deop == EXTENDED_ARG else 0
Expand All @@ -654,7 +656,7 @@ def findlabels(code):
if deop in hasjrel:
if _is_backward_jump(deop):
arg = -arg
label = offset + (arg + 2) * 2
label = offset + (arg + _opsize) * 2
if deop == FOR_ITER:
label += 2
elif deop in hasjabs:
Expand Down
3 changes: 3 additions & 0 deletions Lib/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@ def pseudo_op(name, op, real_ops):
"deopt",
]

# number of codewords for opcode+oparg(s)
_opsize = 2

_cache_format = {
"LOAD_GLOBAL": {
"counter": 1,
Expand Down
7 changes: 5 additions & 2 deletions Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
int entry_point = 0;
while (entry_point < Py_SIZE(co) &&
_Py_OPCODE(_PyCode_CODE(co)[entry_point]) != RESUME) {
entry_point += 2;
entry_point += OPSIZE;
}
co->_co_firsttraceable = entry_point;
_PyCode_Quicken(co);
Expand Down Expand Up @@ -1519,7 +1519,10 @@ deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)];
int caches = _PyOpcode_Caches[opcode];
instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction));
instructions[++i] = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
for (int k = 0; k < OPSIZE - 1; k++) {
/* oparg2, oparg3 */
instructions[++i] = _Py_MAKECODEUNIT(0, 0);
}
while (caches--) {
instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0);
}
Expand Down
2 changes: 1 addition & 1 deletion Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ _PyGen_yf(PyGenObject *gen)
assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND);
return NULL;
}
_Py_CODEUNIT next = frame->prev_instr[2];
_Py_CODEUNIT next = frame->prev_instr[OPSIZE];
if (_Py_OPCODE(next) != RESUME || _Py_OPARG(next) < 2)
{
/* Not in a yield from */
Expand Down
28 changes: 14 additions & 14 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ dummy_func(
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
assert(cframe.use_tracing == 0);
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_BinarySubscr(container, sub, next_instr);
DISPATCH_SAME_OPARG();
}
Expand Down Expand Up @@ -482,7 +482,7 @@ dummy_func(
_PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
assert(cframe.use_tracing == 0);
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_StoreSubscr(container, sub, next_instr);
DISPATCH_SAME_OPARG();
}
Expand Down Expand Up @@ -1047,7 +1047,7 @@ dummy_func(
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
assert(cframe.use_tracing == 0);
PyObject *seq = TOP();
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_UnpackSequence(seq, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
Expand Down Expand Up @@ -1126,7 +1126,7 @@ dummy_func(
assert(cframe.use_tracing == 0);
PyObject *owner = TOP();
PyObject *name = GETITEM(names, oparg);
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_StoreAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG();
}
Expand Down Expand Up @@ -1252,7 +1252,7 @@ dummy_func(
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
assert(cframe.use_tracing == 0);
PyObject *name = GETITEM(names, oparg>>1);
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
DISPATCH_SAME_OPARG();
}
Expand Down Expand Up @@ -1698,7 +1698,7 @@ dummy_func(
assert(cframe.use_tracing == 0);
PyObject *owner = TOP();
PyObject *name = GETITEM(names, oparg>>1);
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_LoadAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG();
}
Expand Down Expand Up @@ -2062,7 +2062,7 @@ dummy_func(
assert(cframe.use_tracing == 0);
PyObject *right = TOP();
PyObject *left = SECOND();
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_CompareOp(left, right, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
Expand Down Expand Up @@ -2560,7 +2560,7 @@ dummy_func(
_PyForIterCache *cache = (_PyForIterCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
assert(cframe.use_tracing == 0);
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_ForIter(TOP(), next_instr, oparg);
DISPATCH_SAME_OPARG();
}
Expand Down Expand Up @@ -2588,7 +2588,7 @@ dummy_func(
STACK_SHRINK(1);
Py_DECREF(iter);
/* Skip END_FOR */
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 2);
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + OPSIZE);
}
}

Expand All @@ -2611,7 +2611,7 @@ dummy_func(
}
STACK_SHRINK(1);
Py_DECREF(it);
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 2);
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + OPSIZE);
end_for_iter_list:
}

Expand All @@ -2626,7 +2626,7 @@ dummy_func(
if (r->len <= 0) {
STACK_SHRINK(1);
Py_DECREF(r);
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 2);
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + OPSIZE);
}
else {
long value = r->start;
Expand All @@ -2636,7 +2636,7 @@ dummy_func(
goto error;
}
// The STORE_FAST is already done.
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + 2);
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + OPSIZE);
}
}

Expand Down Expand Up @@ -2891,7 +2891,7 @@ dummy_func(
int is_meth = is_method(stack_pointer, oparg);
int nargs = oparg + is_meth;
PyObject *callable = PEEK(nargs + 1);
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_Call(callable, next_instr, nargs, kwnames);
DISPATCH_SAME_OPARG();
}
Expand Down Expand Up @@ -3637,7 +3637,7 @@ dummy_func(
_PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
assert(cframe.use_tracing == 0);
next_instr -= 2;
next_instr -= OPSIZE;
_Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, &GETLOCAL(0));
DISPATCH_SAME_OPARG();
}
Expand Down
13 changes: 6 additions & 7 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#define INSTRUCTION_START(op) \
do { \
frame->prev_instr = next_instr; \
next_instr += 2; \
next_instr += OPSIZE; \
OPCODE_EXE_INC(op); \
if (_py_stats) _py_stats->opcode_stats[lastopcode].pair_count[op]++; \
lastopcode = op; \
Expand All @@ -679,7 +679,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
do { \
frame->prev_instr = next_instr; \
if (VERBOSE) fprintf(stderr, ">>: _Py_OPCODE(*next_instr) = %d\n", _Py_OPCODE(*next_instr)); \
next_instr += 2; \
next_instr += OPSIZE; \
} while (0)
#endif

Expand Down Expand Up @@ -721,7 +721,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#define DISPATCH_INLINED(NEW_FRAME) \
do { \
_PyFrame_SetStackPointer(frame, stack_pointer); \
frame->prev_instr = next_instr - 2; \
frame->prev_instr = next_instr - OPSIZE; \
(NEW_FRAME)->previous = frame; \
frame = cframe.current_frame = (NEW_FRAME); \
CALL_STAT_INC(inlined_py_calls); \
Expand Down Expand Up @@ -1173,8 +1173,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
if(!_PyErr_Occurred(tstate)) PyObject_Print(frame->f_code->co_name, stderr, 0); \
fprintf(stderr, "\n"); \
} \
next_instr = frame->prev_instr + (_PyInterpreterFrame_LASTI(frame) == -1 ? 1 : 2); /* TODO: init frame to -2? */ \
if (_Py_OPCODE(*next_instr) == 0) next_instr++; \
next_instr = frame->prev_instr + (_PyInterpreterFrame_LASTI(frame) == -1 ? 1 : OPSIZE); /* TODO: init frame to -OPSIZE? */ \
stack_pointer = _PyFrame_GetStackPointer(frame); \
/* Set stackdepth to -1. \
Update when returning or calling trace function. \
Expand Down Expand Up @@ -1289,7 +1288,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
// next_instr wasn't incremented at the start of this
// instruction. Increment it before handling the error,
// so that it looks the same as a "normal" instruction:
next_instr += 2;
next_instr += OPSIZE;
goto error;
}
// Reload next_instr. Don't increment it, though, since
Expand All @@ -1314,7 +1313,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
}
opcode = _PyOpcode_Deopt[opcode];
if (_PyOpcode_Caches[opcode]) {
_Py_CODEUNIT *counter = &next_instr[2];
_Py_CODEUNIT *counter = &next_instr[OPSIZE];
// The instruction is going to decrement the counter, so we need to
// increment it here to make sure it doesn't try to specialize:
if (!ADAPTIVE_COUNTER_IS_MAX(*counter)) {
Expand Down
20 changes: 14 additions & 6 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ instr_size(struct instr *instruction)
assert(HAS_ARG(opcode) || oparg == 0);
int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg);
int caches = _PyOpcode_Caches[opcode];
return 2 * (extended_args + 1) + caches;
return OPSIZE * (extended_args + 1) + caches;
}

static void
Expand All @@ -251,22 +251,30 @@ write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen)
int oparg = instruction->i_oparg;
assert(HAS_ARG(opcode) || oparg == 0);
int caches = _PyOpcode_Caches[opcode];
switch ((ilen - caches)/2) {
switch ((ilen - caches)/OPSIZE) {
case 4:
*codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 24) & 0xFF);
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
for(int k = 0; k < OPSIZE - 1; k++) {
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
}
/* fall through */
case 3:
*codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 16) & 0xFF);
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
for(int k = 0; k < OPSIZE - 1; k++) {
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
}
/* fall through */
case 2:
*codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 8) & 0xFF);
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
for(int k = 0; k < OPSIZE - 1; k++) {
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
}
/* fall through */
case 1:
*codestr++ = _Py_MAKECODEUNIT(opcode, oparg & 0xFF);
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
for(int k = 0; k < OPSIZE - 1; k++) {
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
}
break;
default:
Py_UNREACHABLE();
Expand Down
Loading