mirror of
https://github.com/python/cpython.git
synced 2024-11-23 18:04:37 +08:00
gh-100712: make it possible to disable specialization (for debugging) (#100713)
This commit is contained in:
parent
a1e051a237
commit
e9ccfe4a63
2
Include/opcode.h
generated
2
Include/opcode.h
generated
@ -226,6 +226,8 @@ extern "C" {
|
||||
#define NB_INPLACE_TRUE_DIVIDE 24
|
||||
#define NB_INPLACE_XOR 25
|
||||
|
||||
/* Defined in Lib/opcode.py */
|
||||
#define ENABLE_SPECIALIZATION 1
|
||||
|
||||
#define IS_PSEUDO_OPCODE(op) (((op) >= MIN_PSEUDO_OPCODE) && ((op) <= MAX_PSEUDO_OPCODE))
|
||||
|
||||
|
@ -33,6 +33,9 @@ hascompare = []
|
||||
hasfree = []
|
||||
hasexc = []
|
||||
|
||||
|
||||
ENABLE_SPECIALIZATION = True
|
||||
|
||||
def is_pseudo(op):
|
||||
return op >= MIN_PSEUDO_OPCODE and op <= MAX_PSEUDO_OPCODE
|
||||
|
||||
|
@ -6,6 +6,7 @@ if __name__ != 'test.support':
|
||||
import contextlib
|
||||
import functools
|
||||
import getpass
|
||||
import opcode
|
||||
import os
|
||||
import re
|
||||
import stat
|
||||
@ -46,7 +47,7 @@ __all__ = [
|
||||
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
|
||||
"check__all__", "skip_if_buggy_ucrt_strfptime",
|
||||
"check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer",
|
||||
"requires_limited_api",
|
||||
"requires_limited_api", "requires_specialization",
|
||||
# sys
|
||||
"is_jython", "is_android", "is_emscripten", "is_wasi",
|
||||
"check_impl_detail", "unix_shell", "setswitchinterval",
|
||||
@ -1077,6 +1078,8 @@ def requires_limited_api(test):
|
||||
return unittest.skipUnless(
|
||||
_testcapi.LIMITED_API_AVAILABLE, 'needs Limited API support')(test)
|
||||
|
||||
def requires_specialization(test):
|
||||
return unittest.skipUnless(opcode.ENABLE_SPECIALIZATION, "requires specialization")
|
||||
|
||||
def _filter_suite(suite, pred):
|
||||
"""Recursively filter test cases in a suite based on a predicate."""
|
||||
|
@ -10,7 +10,8 @@ import types
|
||||
import textwrap
|
||||
import warnings
|
||||
from test import support
|
||||
from test.support import script_helper, requires_debug_ranges
|
||||
from test.support import (script_helper, requires_debug_ranges,
|
||||
requires_specialization)
|
||||
from test.support.os_helper import FakePath
|
||||
|
||||
|
||||
@ -1251,6 +1252,7 @@ f(
|
||||
self.assertOpcodeSourcePositionIs(compiled_code, 'CALL',
|
||||
line=1, end_line=3, column=0, end_column=1)
|
||||
|
||||
@requires_specialization
|
||||
def test_multiline_boolean_expression(self):
|
||||
snippet = """\
|
||||
if (a or
|
||||
|
@ -7,7 +7,8 @@ import re
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
from test.support import captured_stdout, requires_debug_ranges, cpython_only
|
||||
from test.support import (captured_stdout, requires_debug_ranges,
|
||||
requires_specialization, cpython_only)
|
||||
from test.support.bytecode_helper import BytecodeTestCase
|
||||
|
||||
import opcode
|
||||
@ -1086,12 +1087,14 @@ class DisTests(DisTestBase):
|
||||
f()
|
||||
|
||||
@cpython_only
|
||||
@requires_specialization
|
||||
def test_super_instructions(self):
|
||||
self.code_quicken(lambda: load_test(0, 0))
|
||||
got = self.get_disassembly(load_test, adaptive=True)
|
||||
self.do_disassembly_compare(got, dis_load_test_quickened_code, True)
|
||||
|
||||
@cpython_only
|
||||
@requires_specialization
|
||||
def test_binary_specialize(self):
|
||||
binary_op_quicken = """\
|
||||
0 0 RESUME 0
|
||||
@ -1130,6 +1133,7 @@ class DisTests(DisTestBase):
|
||||
self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_DICT", True)
|
||||
|
||||
@cpython_only
|
||||
@requires_specialization
|
||||
def test_load_attr_specialize(self):
|
||||
load_attr_quicken = """\
|
||||
0 0 RESUME 0
|
||||
@ -1144,6 +1148,7 @@ class DisTests(DisTestBase):
|
||||
self.do_disassembly_compare(got, load_attr_quicken, True)
|
||||
|
||||
@cpython_only
|
||||
@requires_specialization
|
||||
def test_call_specialize(self):
|
||||
call_quicken = """\
|
||||
0 RESUME 0
|
||||
@ -1160,6 +1165,7 @@ class DisTests(DisTestBase):
|
||||
self.do_disassembly_compare(got, call_quicken)
|
||||
|
||||
@cpython_only
|
||||
@requires_specialization
|
||||
def test_loop_quicken(self):
|
||||
# Loop can trigger a quicken where the loop is located
|
||||
self.code_quicken(loop_test, 1)
|
||||
|
@ -2,6 +2,7 @@
|
||||
from test import support
|
||||
from test.support import import_helper
|
||||
from test.support import os_helper
|
||||
from test.support import requires_specialization
|
||||
import unittest
|
||||
|
||||
from collections import namedtuple
|
||||
@ -346,6 +347,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||
out, err = self.run_embedded_interpreter("test_repeated_simple_init")
|
||||
self.assertEqual(out, 'Finalized\n' * INIT_LOOPS)
|
||||
|
||||
@requires_specialization
|
||||
def test_specialized_static_code_gets_unspecialized_at_Py_FINALIZE(self):
|
||||
# https://github.com/python/cpython/issues/92031
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
Added option to build cpython with specialization disabled, by setting ``ENABLE_SPECIALIZATION=False`` in :mod:`opcode`, followed by ``make regen-all``.
|
@ -304,6 +304,7 @@ dummy_func(
|
||||
};
|
||||
|
||||
inst(BINARY_SUBSCR, (unused/4, container, sub -- res)) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -313,6 +314,7 @@ dummy_func(
|
||||
}
|
||||
STAT_INC(BINARY_SUBSCR, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
res = PyObject_GetItem(container, sub);
|
||||
DECREF_INPUTS();
|
||||
ERROR_IF(res == NULL, error);
|
||||
@ -441,6 +443,7 @@ dummy_func(
|
||||
};
|
||||
|
||||
inst(STORE_SUBSCR, (counter/1, v, container, sub -- )) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
next_instr--;
|
||||
@ -450,6 +453,9 @@ dummy_func(
|
||||
STAT_INC(STORE_SUBSCR, deferred);
|
||||
_PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr;
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#else
|
||||
(void)counter; // Unused.
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
/* container[sub] = v */
|
||||
int err = PyObject_SetItem(container, sub, v);
|
||||
DECREF_INPUTS();
|
||||
@ -872,6 +878,7 @@ dummy_func(
|
||||
|
||||
// stack effect: (__0 -- __array[oparg])
|
||||
inst(UNPACK_SEQUENCE) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -882,6 +889,7 @@ dummy_func(
|
||||
}
|
||||
STAT_INC(UNPACK_SEQUENCE, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
PyObject *seq = POP();
|
||||
PyObject **top = stack_pointer + oparg;
|
||||
if (!unpack_iterable(tstate, seq, oparg, -1, top)) {
|
||||
@ -956,6 +964,7 @@ dummy_func(
|
||||
};
|
||||
|
||||
inst(STORE_ATTR, (counter/1, unused/3, v, owner --)) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *name = GETITEM(names, oparg);
|
||||
@ -966,6 +975,9 @@ dummy_func(
|
||||
STAT_INC(STORE_ATTR, deferred);
|
||||
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#else
|
||||
(void)counter; // Unused.
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
PyObject *name = GETITEM(names, oparg);
|
||||
int err = PyObject_SetAttr(owner, name, v);
|
||||
Py_DECREF(v);
|
||||
@ -1064,6 +1076,7 @@ dummy_func(
|
||||
|
||||
// error: LOAD_GLOBAL has irregular stack effect
|
||||
inst(LOAD_GLOBAL) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -1074,6 +1087,7 @@ dummy_func(
|
||||
}
|
||||
STAT_INC(LOAD_GLOBAL, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
int push_null = oparg & 1;
|
||||
PEEK(0) = NULL;
|
||||
PyObject *name = GETITEM(names, oparg>>1);
|
||||
@ -1430,6 +1444,7 @@ dummy_func(
|
||||
|
||||
// error: LOAD_ATTR has irregular stack effect
|
||||
inst(LOAD_ATTR) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -1441,6 +1456,7 @@ dummy_func(
|
||||
}
|
||||
STAT_INC(LOAD_ATTR, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
PyObject *name = GETITEM(names, oparg >> 1);
|
||||
PyObject *owner = TOP();
|
||||
if (oparg & 1) {
|
||||
@ -1778,6 +1794,7 @@ dummy_func(
|
||||
};
|
||||
|
||||
inst(COMPARE_AND_BRANCH, (unused/2, left, right -- )) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -1787,6 +1804,7 @@ dummy_func(
|
||||
}
|
||||
STAT_INC(COMPARE_AND_BRANCH, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
assert((oparg >> 4) <= Py_GE);
|
||||
PyObject *cond = PyObject_RichCompare(left, right, oparg>>4);
|
||||
Py_DECREF(left);
|
||||
@ -2194,6 +2212,7 @@ dummy_func(
|
||||
|
||||
// stack effect: ( -- __0)
|
||||
inst(FOR_ITER) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyForIterCache *cache = (_PyForIterCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -2203,6 +2222,7 @@ dummy_func(
|
||||
}
|
||||
STAT_INC(FOR_ITER, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
/* before: [iter]; after: [iter, iter()] *or* [] */
|
||||
PyObject *iter = TOP();
|
||||
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
|
||||
@ -2518,6 +2538,7 @@ dummy_func(
|
||||
|
||||
// stack effect: (__0, __array[oparg] -- )
|
||||
inst(CALL) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyCallCache *cache = (_PyCallCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -2530,6 +2551,7 @@ dummy_func(
|
||||
}
|
||||
STAT_INC(CALL, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
int total_args, is_meth;
|
||||
is_meth = is_method(stack_pointer, oparg);
|
||||
PyObject *function = PEEK(oparg + 1);
|
||||
@ -3262,6 +3284,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
inst(BINARY_OP, (unused/1, lhs, rhs -- res)) {
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -3271,6 +3294,7 @@ dummy_func(
|
||||
}
|
||||
STAT_INC(BINARY_OP, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
assert(0 <= oparg);
|
||||
assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops));
|
||||
assert(binary_ops[oparg]);
|
||||
|
24
Python/generated_cases.c.h
generated
24
Python/generated_cases.c.h
generated
@ -410,6 +410,7 @@
|
||||
PyObject *sub = PEEK(1);
|
||||
PyObject *container = PEEK(2);
|
||||
PyObject *res;
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -419,6 +420,7 @@
|
||||
}
|
||||
STAT_INC(BINARY_SUBSCR, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
res = PyObject_GetItem(container, sub);
|
||||
Py_DECREF(container);
|
||||
Py_DECREF(sub);
|
||||
@ -598,6 +600,7 @@
|
||||
PyObject *container = PEEK(2);
|
||||
PyObject *v = PEEK(3);
|
||||
uint16_t counter = read_u16(&next_instr[0].cache);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
next_instr--;
|
||||
@ -607,6 +610,9 @@
|
||||
STAT_INC(STORE_SUBSCR, deferred);
|
||||
_PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr;
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#else
|
||||
(void)counter; // Unused.
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
/* container[sub] = v */
|
||||
int err = PyObject_SetItem(container, sub, v);
|
||||
Py_DECREF(v);
|
||||
@ -1092,6 +1098,7 @@
|
||||
|
||||
TARGET(UNPACK_SEQUENCE) {
|
||||
PREDICTED(UNPACK_SEQUENCE);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -1102,6 +1109,7 @@
|
||||
}
|
||||
STAT_INC(UNPACK_SEQUENCE, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
PyObject *seq = POP();
|
||||
PyObject **top = stack_pointer + oparg;
|
||||
if (!unpack_iterable(tstate, seq, oparg, -1, top)) {
|
||||
@ -1174,6 +1182,7 @@
|
||||
PyObject *owner = PEEK(1);
|
||||
PyObject *v = PEEK(2);
|
||||
uint16_t counter = read_u16(&next_instr[0].cache);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *name = GETITEM(names, oparg);
|
||||
@ -1184,6 +1193,9 @@
|
||||
STAT_INC(STORE_ATTR, deferred);
|
||||
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#else
|
||||
(void)counter; // Unused.
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
PyObject *name = GETITEM(names, oparg);
|
||||
int err = PyObject_SetAttr(owner, name, v);
|
||||
Py_DECREF(v);
|
||||
@ -1296,6 +1308,7 @@
|
||||
|
||||
TARGET(LOAD_GLOBAL) {
|
||||
PREDICTED(LOAD_GLOBAL);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -1306,6 +1319,7 @@
|
||||
}
|
||||
STAT_INC(LOAD_GLOBAL, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
int push_null = oparg & 1;
|
||||
PEEK(0) = NULL;
|
||||
PyObject *name = GETITEM(names, oparg>>1);
|
||||
@ -1733,6 +1747,7 @@
|
||||
|
||||
TARGET(LOAD_ATTR) {
|
||||
PREDICTED(LOAD_ATTR);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyAttrCache *cache = (_PyAttrCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -1744,6 +1759,7 @@
|
||||
}
|
||||
STAT_INC(LOAD_ATTR, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
PyObject *name = GETITEM(names, oparg >> 1);
|
||||
PyObject *owner = TOP();
|
||||
if (oparg & 1) {
|
||||
@ -2104,6 +2120,7 @@
|
||||
PREDICTED(COMPARE_AND_BRANCH);
|
||||
PyObject *right = PEEK(1);
|
||||
PyObject *left = PEEK(2);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -2113,6 +2130,7 @@
|
||||
}
|
||||
STAT_INC(COMPARE_AND_BRANCH, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
assert((oparg >> 4) <= Py_GE);
|
||||
PyObject *cond = PyObject_RichCompare(left, right, oparg>>4);
|
||||
Py_DECREF(left);
|
||||
@ -2571,6 +2589,7 @@
|
||||
|
||||
TARGET(FOR_ITER) {
|
||||
PREDICTED(FOR_ITER);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyForIterCache *cache = (_PyForIterCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -2580,6 +2599,7 @@
|
||||
}
|
||||
STAT_INC(FOR_ITER, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
/* before: [iter]; after: [iter, iter()] *or* [] */
|
||||
PyObject *iter = TOP();
|
||||
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
|
||||
@ -2901,6 +2921,7 @@
|
||||
|
||||
TARGET(CALL) {
|
||||
PREDICTED(CALL);
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyCallCache *cache = (_PyCallCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -2913,6 +2934,7 @@
|
||||
}
|
||||
STAT_INC(CALL, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
int total_args, is_meth;
|
||||
is_meth = is_method(stack_pointer, oparg);
|
||||
PyObject *function = PEEK(oparg + 1);
|
||||
@ -3650,6 +3672,7 @@
|
||||
PyObject *rhs = PEEK(1);
|
||||
PyObject *lhs = PEEK(2);
|
||||
PyObject *res;
|
||||
#if ENABLE_SPECIALIZATION
|
||||
_PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
|
||||
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
@ -3659,6 +3682,7 @@
|
||||
}
|
||||
STAT_INC(BINARY_OP, deferred);
|
||||
DECREMENT_ADAPTIVE_COUNTER(cache->counter);
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
assert(0 <= oparg);
|
||||
assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops));
|
||||
assert(binary_ops[oparg]);
|
||||
|
@ -276,6 +276,7 @@ static int compare_masks[] = {
|
||||
void
|
||||
_PyCode_Quicken(PyCodeObject *code)
|
||||
{
|
||||
#if ENABLE_SPECIALIZATION
|
||||
int opcode = 0;
|
||||
_Py_CODEUNIT *instructions = _PyCode_CODE(code);
|
||||
for (int i = 0; i < Py_SIZE(code); i++) {
|
||||
@ -318,6 +319,7 @@ _PyCode_Quicken(PyCodeObject *code)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_SPECIALIZATION */
|
||||
}
|
||||
|
||||
#define SIMPLE_FUNCTION 0
|
||||
@ -703,6 +705,7 @@ static int specialize_class_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyOb
|
||||
void
|
||||
_Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[LOAD_ATTR] == INLINE_CACHE_ENTRIES_LOAD_ATTR);
|
||||
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
|
||||
PyTypeObject *type = Py_TYPE(owner);
|
||||
@ -875,6 +878,7 @@ success:
|
||||
void
|
||||
_Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[STORE_ATTR] == INLINE_CACHE_ENTRIES_STORE_ATTR);
|
||||
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
|
||||
PyTypeObject *type = Py_TYPE(owner);
|
||||
@ -1146,6 +1150,7 @@ _Py_Specialize_LoadGlobal(
|
||||
PyObject *globals, PyObject *builtins,
|
||||
_Py_CODEUNIT *instr, PyObject *name)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[LOAD_GLOBAL] == INLINE_CACHE_ENTRIES_LOAD_GLOBAL);
|
||||
/* Use inline cache */
|
||||
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr + 1);
|
||||
@ -1317,6 +1322,7 @@ void
|
||||
_Py_Specialize_BinarySubscr(
|
||||
PyObject *container, PyObject *sub, _Py_CODEUNIT *instr)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[BINARY_SUBSCR] ==
|
||||
INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
|
||||
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)(instr + 1);
|
||||
@ -1399,6 +1405,7 @@ success:
|
||||
void
|
||||
_Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
_PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)(instr + 1);
|
||||
PyTypeObject *container_type = Py_TYPE(container);
|
||||
if (container_type == &PyList_Type) {
|
||||
@ -1778,6 +1785,7 @@ void
|
||||
_Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
|
||||
PyObject *kwnames)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[CALL] == INLINE_CACHE_ENTRIES_CALL);
|
||||
_PyCallCache *cache = (_PyCallCache *)(instr + 1);
|
||||
int fail;
|
||||
@ -1896,6 +1904,7 @@ void
|
||||
_Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
||||
int oparg, PyObject **locals)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[BINARY_OP] == INLINE_CACHE_ENTRIES_BINARY_OP);
|
||||
_PyBinaryOpCache *cache = (_PyBinaryOpCache *)(instr + 1);
|
||||
switch (oparg) {
|
||||
@ -2003,6 +2012,7 @@ void
|
||||
_Py_Specialize_CompareAndBranch(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
||||
int oparg)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[COMPARE_AND_BRANCH] == INLINE_CACHE_ENTRIES_COMPARE_OP);
|
||||
_PyCompareOpCache *cache = (_PyCompareOpCache *)(instr + 1);
|
||||
#ifndef NDEBUG
|
||||
@ -2066,6 +2076,7 @@ unpack_sequence_fail_kind(PyObject *seq)
|
||||
void
|
||||
_Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[UNPACK_SEQUENCE] ==
|
||||
INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE);
|
||||
_PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)(instr + 1);
|
||||
@ -2175,6 +2186,7 @@ int
|
||||
void
|
||||
_Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg)
|
||||
{
|
||||
assert(ENABLE_SPECIALIZATION);
|
||||
assert(_PyOpcode_Caches[FOR_ITER] == INLINE_CACHE_ENTRIES_FOR_ITER);
|
||||
_PyForIterCache *cache = (_PyForIterCache *)(instr + 1);
|
||||
PyTypeObject *tp = Py_TYPE(iter);
|
||||
|
@ -85,6 +85,7 @@ def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/interna
|
||||
is_pseudo = opcode['is_pseudo']
|
||||
_pseudo_ops = opcode['_pseudo_ops']
|
||||
|
||||
ENABLE_SPECIALIZATION = opcode["ENABLE_SPECIALIZATION"]
|
||||
HAVE_ARGUMENT = opcode["HAVE_ARGUMENT"]
|
||||
MIN_PSEUDO_OPCODE = opcode["MIN_PSEUDO_OPCODE"]
|
||||
MAX_PSEUDO_OPCODE = opcode["MAX_PSEUDO_OPCODE"]
|
||||
@ -171,6 +172,10 @@ def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/interna
|
||||
for i, (op, _) in enumerate(opcode["_nb_ops"]):
|
||||
fobj.write(DEFINE.format(op, i))
|
||||
|
||||
fobj.write("\n")
|
||||
fobj.write("/* Defined in Lib/opcode.py */\n")
|
||||
fobj.write(f"#define ENABLE_SPECIALIZATION {int(ENABLE_SPECIALIZATION)}")
|
||||
|
||||
iobj.write("\n")
|
||||
iobj.write("#ifdef Py_DEBUG\n")
|
||||
iobj.write(f"static const char *const _PyOpcode_OpName[{NUM_OPCODES}] = {{\n")
|
||||
|
Loading…
Reference in New Issue
Block a user