Skip to content

Commit 414665b

Browse files
committed
add OPSIZE to make the code a bit more self-documenting
1 parent f9e5993 commit 414665b

12 files changed

+102
-80
lines changed

Include/opcode.h

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/dis.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
_cache_format,
1212
_inline_cache_entries,
1313
_nb_ops,
14+
_opsize,
1415
_specializations,
1516
_specialized_instructions,
1617
)
@@ -433,7 +434,8 @@ def _get_co_positions(code, show_caches=False):
433434
ops = code.co_code[::2]
434435
prev_op = 0
435436
for op, positions in zip(ops, code.co_positions()):
436-
if prev_op != 0:
437+
assert _opsize in (1, 2)
438+
if _opsize == 2 and prev_op != 0:
437439
# skip oparg2, oparg3
438440
prev_op = op
439441
continue
@@ -495,7 +497,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
495497
argrepr = "to " + repr(argval)
496498
elif deop in hasjrel:
497499
signed_arg = -arg if _is_backward_jump(deop) else arg
498-
argval = offset + (signed_arg + 2) * 2
500+
argval = offset + (signed_arg + _opsize) * 2
499501
if deop == FOR_ITER:
500502
argval += 2
501503
argrepr = "to " + repr(argval)
@@ -627,7 +629,7 @@ def _unpack_opargs(code):
627629
op = code[i]
628630
deop = _deoptop(op)
629631
caches = _inline_cache_entries[deop]
630-
caches += 1 # also skip over arg2, arg3
632+
caches += _opsize - 1 # also skip over oparg2, oparg3
631633
if deop in hasarg:
632634
arg = code[i+1] | extended_arg
633635
extended_arg = (arg << 8) if deop == EXTENDED_ARG else 0
@@ -654,7 +656,7 @@ def findlabels(code):
654656
if deop in hasjrel:
655657
if _is_backward_jump(deop):
656658
arg = -arg
657-
label = offset + (arg + 2) * 2
659+
label = offset + (arg + _opsize) * 2
658660
if deop == FOR_ITER:
659661
label += 2
660662
elif deop in hasjabs:

Lib/opcode.py

+3
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,9 @@ def pseudo_op(name, op, real_ops):
380380
"deopt",
381381
]
382382

383+
# number of codewords for opcode+oparg(s)
384+
_opsize = 2
385+
383386
_cache_format = {
384387
"LOAD_GLOBAL": {
385388
"counter": 1,

Objects/codeobject.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
411411
int entry_point = 0;
412412
while (entry_point < Py_SIZE(co) &&
413413
_Py_OPCODE(_PyCode_CODE(co)[entry_point]) != RESUME) {
414-
entry_point += 2;
414+
entry_point += OPSIZE;
415415
}
416416
co->_co_firsttraceable = entry_point;
417417
_PyCode_Quicken(co);
@@ -1519,7 +1519,10 @@ deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
15191519
int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)];
15201520
int caches = _PyOpcode_Caches[opcode];
15211521
instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction));
1522-
instructions[++i] = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
1522+
for (int k = 0; k < OPSIZE - 1; k++) {
1523+
/* oparg2, oparg3 */
1524+
instructions[++i] = _Py_MAKECODEUNIT(0, 0);
1525+
}
15231526
while (caches--) {
15241527
instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0);
15251528
}

Objects/genobject.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ _PyGen_yf(PyGenObject *gen)
335335
assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND);
336336
return NULL;
337337
}
338-
_Py_CODEUNIT next = frame->prev_instr[2];
338+
_Py_CODEUNIT next = frame->prev_instr[OPSIZE];
339339
if (_Py_OPCODE(next) != RESUME || _Py_OPARG(next) < 2)
340340
{
341341
/* Not in a yield from */

Python/bytecodes.c

+14-14
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ dummy_func(
335335
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
336336
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
337337
assert(cframe.use_tracing == 0);
338-
next_instr -= 2;
338+
next_instr -= OPSIZE;
339339
_Py_Specialize_BinarySubscr(container, sub, next_instr);
340340
DISPATCH_SAME_OPARG();
341341
}
@@ -482,7 +482,7 @@ dummy_func(
482482
_PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr;
483483
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
484484
assert(cframe.use_tracing == 0);
485-
next_instr -= 2;
485+
next_instr -= OPSIZE;
486486
_Py_Specialize_StoreSubscr(container, sub, next_instr);
487487
DISPATCH_SAME_OPARG();
488488
}
@@ -1047,7 +1047,7 @@ dummy_func(
10471047
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
10481048
assert(cframe.use_tracing == 0);
10491049
PyObject *seq = TOP();
1050-
next_instr -= 2;
1050+
next_instr -= OPSIZE;
10511051
_Py_Specialize_UnpackSequence(seq, next_instr, oparg);
10521052
DISPATCH_SAME_OPARG();
10531053
}
@@ -1126,7 +1126,7 @@ dummy_func(
11261126
assert(cframe.use_tracing == 0);
11271127
PyObject *owner = TOP();
11281128
PyObject *name = GETITEM(names, oparg);
1129-
next_instr -= 2;
1129+
next_instr -= OPSIZE;
11301130
_Py_Specialize_StoreAttr(owner, next_instr, name);
11311131
DISPATCH_SAME_OPARG();
11321132
}
@@ -1252,7 +1252,7 @@ dummy_func(
12521252
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
12531253
assert(cframe.use_tracing == 0);
12541254
PyObject *name = GETITEM(names, oparg>>1);
1255-
next_instr -= 2;
1255+
next_instr -= OPSIZE;
12561256
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
12571257
DISPATCH_SAME_OPARG();
12581258
}
@@ -1698,7 +1698,7 @@ dummy_func(
16981698
assert(cframe.use_tracing == 0);
16991699
PyObject *owner = TOP();
17001700
PyObject *name = GETITEM(names, oparg>>1);
1701-
next_instr -= 2;
1701+
next_instr -= OPSIZE;
17021702
_Py_Specialize_LoadAttr(owner, next_instr, name);
17031703
DISPATCH_SAME_OPARG();
17041704
}
@@ -2062,7 +2062,7 @@ dummy_func(
20622062
assert(cframe.use_tracing == 0);
20632063
PyObject *right = TOP();
20642064
PyObject *left = SECOND();
2065-
next_instr -= 2;
2065+
next_instr -= OPSIZE;
20662066
_Py_Specialize_CompareOp(left, right, next_instr, oparg);
20672067
DISPATCH_SAME_OPARG();
20682068
}
@@ -2560,7 +2560,7 @@ dummy_func(
25602560
_PyForIterCache *cache = (_PyForIterCache *)next_instr;
25612561
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
25622562
assert(cframe.use_tracing == 0);
2563-
next_instr -= 2;
2563+
next_instr -= OPSIZE;
25642564
_Py_Specialize_ForIter(TOP(), next_instr, oparg);
25652565
DISPATCH_SAME_OPARG();
25662566
}
@@ -2588,7 +2588,7 @@ dummy_func(
25882588
STACK_SHRINK(1);
25892589
Py_DECREF(iter);
25902590
/* Skip END_FOR */
2591-
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 2);
2591+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + OPSIZE);
25922592
}
25932593
}
25942594

@@ -2611,7 +2611,7 @@ dummy_func(
26112611
}
26122612
STACK_SHRINK(1);
26132613
Py_DECREF(it);
2614-
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 2);
2614+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + OPSIZE);
26152615
end_for_iter_list:
26162616
}
26172617

@@ -2626,7 +2626,7 @@ dummy_func(
26262626
if (r->len <= 0) {
26272627
STACK_SHRINK(1);
26282628
Py_DECREF(r);
2629-
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 2);
2629+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + OPSIZE);
26302630
}
26312631
else {
26322632
long value = r->start;
@@ -2636,7 +2636,7 @@ dummy_func(
26362636
goto error;
26372637
}
26382638
// The STORE_FAST is already done.
2639-
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + 2);
2639+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + OPSIZE);
26402640
}
26412641
}
26422642

@@ -2891,7 +2891,7 @@ dummy_func(
28912891
int is_meth = is_method(stack_pointer, oparg);
28922892
int nargs = oparg + is_meth;
28932893
PyObject *callable = PEEK(nargs + 1);
2894-
next_instr -= 2;
2894+
next_instr -= OPSIZE;
28952895
_Py_Specialize_Call(callable, next_instr, nargs, kwnames);
28962896
DISPATCH_SAME_OPARG();
28972897
}
@@ -3637,7 +3637,7 @@ dummy_func(
36373637
_PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
36383638
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
36393639
assert(cframe.use_tracing == 0);
3640-
next_instr -= 2;
3640+
next_instr -= OPSIZE;
36413641
_Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, &GETLOCAL(0));
36423642
DISPATCH_SAME_OPARG();
36433643
}

Python/ceval.c

+6-7
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
669669
#define INSTRUCTION_START(op) \
670670
do { \
671671
frame->prev_instr = next_instr; \
672-
next_instr += 2; \
672+
next_instr += OPSIZE; \
673673
OPCODE_EXE_INC(op); \
674674
if (_py_stats) _py_stats->opcode_stats[lastopcode].pair_count[op]++; \
675675
lastopcode = op; \
@@ -679,7 +679,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
679679
do { \
680680
frame->prev_instr = next_instr; \
681681
if (VERBOSE) fprintf(stderr, ">>: _Py_OPCODE(*next_instr) = %d\n", _Py_OPCODE(*next_instr)); \
682-
next_instr += 2; \
682+
next_instr += OPSIZE; \
683683
} while (0)
684684
#endif
685685

@@ -721,7 +721,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
721721
#define DISPATCH_INLINED(NEW_FRAME) \
722722
do { \
723723
_PyFrame_SetStackPointer(frame, stack_pointer); \
724-
frame->prev_instr = next_instr - 2; \
724+
frame->prev_instr = next_instr - OPSIZE; \
725725
(NEW_FRAME)->previous = frame; \
726726
frame = cframe.current_frame = (NEW_FRAME); \
727727
CALL_STAT_INC(inlined_py_calls); \
@@ -1173,8 +1173,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11731173
if(!_PyErr_Occurred(tstate)) PyObject_Print(frame->f_code->co_name, stderr, 0); \
11741174
fprintf(stderr, "\n"); \
11751175
} \
1176-
next_instr = frame->prev_instr + (_PyInterpreterFrame_LASTI(frame) == -1 ? 1 : 2); /* TODO: init frame to -2? */ \
1177-
if (_Py_OPCODE(*next_instr) == 0) next_instr++; \
1176+
next_instr = frame->prev_instr + (_PyInterpreterFrame_LASTI(frame) == -1 ? 1 : OPSIZE); /* TODO: init frame to -OPSIZE? */ \
11781177
stack_pointer = _PyFrame_GetStackPointer(frame); \
11791178
/* Set stackdepth to -1. \
11801179
Update when returning or calling trace function. \
@@ -1289,7 +1288,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
12891288
// next_instr wasn't incremented at the start of this
12901289
// instruction. Increment it before handling the error,
12911290
// so that it looks the same as a "normal" instruction:
1292-
next_instr += 2;
1291+
next_instr += OPSIZE;
12931292
goto error;
12941293
}
12951294
// Reload next_instr. Don't increment it, though, since
@@ -1314,7 +1313,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
13141313
}
13151314
opcode = _PyOpcode_Deopt[opcode];
13161315
if (_PyOpcode_Caches[opcode]) {
1317-
_Py_CODEUNIT *counter = &next_instr[2];
1316+
_Py_CODEUNIT *counter = &next_instr[OPSIZE];
13181317
// The instruction is going to decrement the counter, so we need to
13191318
// increment it here to make sure it doesn't try to specialize:
13201319
if (!ADAPTIVE_COUNTER_IS_MAX(*counter)) {

Python/compile.c

+14-6
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ instr_size(struct instr *instruction)
240240
assert(HAS_ARG(opcode) || oparg == 0);
241241
int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg);
242242
int caches = _PyOpcode_Caches[opcode];
243-
return 2 * (extended_args + 1) + caches;
243+
return OPSIZE * (extended_args + 1) + caches;
244244
}
245245

246246
static void
@@ -251,22 +251,30 @@ write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen)
251251
int oparg = instruction->i_oparg;
252252
assert(HAS_ARG(opcode) || oparg == 0);
253253
int caches = _PyOpcode_Caches[opcode];
254-
switch ((ilen - caches)/2) {
254+
switch ((ilen - caches)/OPSIZE) {
255255
case 4:
256256
*codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 24) & 0xFF);
257-
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
257+
for(int k = 0; k < OPSIZE - 1; k++) {
258+
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
259+
}
258260
/* fall through */
259261
case 3:
260262
*codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 16) & 0xFF);
261-
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
263+
for(int k = 0; k < OPSIZE - 1; k++) {
264+
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
265+
}
262266
/* fall through */
263267
case 2:
264268
*codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 8) & 0xFF);
265-
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
269+
for(int k = 0; k < OPSIZE - 1; k++) {
270+
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
271+
}
266272
/* fall through */
267273
case 1:
268274
*codestr++ = _Py_MAKECODEUNIT(opcode, oparg & 0xFF);
269-
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
275+
for(int k = 0; k < OPSIZE - 1; k++) {
276+
*codestr++ = _Py_MAKECODEUNIT(0, 0); /* oparg2, oparg3 */
277+
}
270278
break;
271279
default:
272280
Py_UNREACHABLE();

0 commit comments

Comments
 (0)