Python-checkins
Threads by month
- ----- 2024 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
October 2023
- 1 participants
- 899 discussions
gh-109181: Speed up Traceback object creation by lazily compute the line number (#111548)
by pablogsal 31 Oct '23
by pablogsal 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/abb15420c11d9dda9c89f74eac8417240b…
commit: abb15420c11d9dda9c89f74eac8417240b321109
branch: main
author: Pablo Galindo Salgado <Pablogsal(a)gmail.com>
committer: pablogsal <Pablogsal(a)gmail.com>
date: 2023-10-31T15:02:31Z
summary:
gh-109181: Speed up Traceback object creation by lazily compute the line number (#111548)
Signed-off-by: Pablo Galindo <pablogsal(a)gmail.com>
files:
A Misc/NEWS.d/next/Core and Builtins/2023-10-31-14-25-21.gh-issue-109181.11h6Mc.rst
M Python/traceback.c
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-10-31-14-25-21.gh-issue-109181.11h6Mc.rst b/Misc/NEWS.d/next/Core and Builtins/2023-10-31-14-25-21.gh-issue-109181.11h6Mc.rst
new file mode 100644
index 0000000000000..61a15b471cfb2
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-10-31-14-25-21.gh-issue-109181.11h6Mc.rst
@@ -0,0 +1,2 @@
+Speed up :obj:`Traceback` object creation by lazily compute the line number.
+Patch by Pablo Galindo
diff --git a/Python/traceback.c b/Python/traceback.c
index 05d841e56ad7b..8aba802ae3678 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -109,6 +109,26 @@ tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
return Py_NewRef(ret);
}
+static int
+tb_get_lineno(PyTracebackObject* tb) {
+ _PyInterpreterFrame* frame = tb->tb_frame->f_frame;
+ assert(frame != NULL);
+ return PyCode_Addr2Line(_PyFrame_GetCode(frame), tb->tb_lasti);
+}
+
+static PyObject *
+tb_lineno_get(PyTracebackObject *self, void *Py_UNUSED(_))
+{
+ int lineno = self->tb_lineno;
+ if (lineno == -1) {
+ lineno = tb_get_lineno(self);
+ if (lineno < 0) {
+ Py_RETURN_NONE;
+ }
+ }
+ return PyLong_FromLong(lineno);
+}
+
static int
tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
{
@@ -152,12 +172,12 @@ static PyMethodDef tb_methods[] = {
static PyMemberDef tb_memberlist[] = {
{"tb_frame", _Py_T_OBJECT, OFF(tb_frame), Py_READONLY|Py_AUDIT_READ},
{"tb_lasti", Py_T_INT, OFF(tb_lasti), Py_READONLY},
- {"tb_lineno", Py_T_INT, OFF(tb_lineno), Py_READONLY},
{NULL} /* Sentinel */
};
static PyGetSetDef tb_getsetters[] = {
{"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL},
+ {"tb_lineno", (getter)tb_lineno_get, NULL, NULL, NULL},
{NULL} /* Sentinel */
};
@@ -236,8 +256,7 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
assert(tb_next == NULL || PyTraceBack_Check(tb_next));
assert(frame != NULL);
int addr = _PyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT);
- return tb_create_raw((PyTracebackObject *)tb_next, frame, addr,
- PyFrame_GetLineNumber(frame));
+ return tb_create_raw((PyTracebackObject *)tb_next, frame, addr, -1);
}
@@ -681,9 +700,13 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
}
while (tb != NULL) {
code = PyFrame_GetCode(tb->tb_frame);
+ int tb_lineno = tb->tb_lineno;
+ if (tb_lineno == -1) {
+ tb_lineno = tb_get_lineno(tb);
+ }
if (last_file == NULL ||
code->co_filename != last_file ||
- last_line == -1 || tb->tb_lineno != last_line ||
+ last_line == -1 || tb_lineno != last_line ||
last_name == NULL || code->co_name != last_name) {
if (cnt > TB_RECURSIVE_CUTOFF) {
if (tb_print_line_repeated(f, cnt) < 0) {
@@ -691,13 +714,13 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
}
}
last_file = code->co_filename;
- last_line = tb->tb_lineno;
+ last_line = tb_lineno;
last_name = code->co_name;
cnt = 0;
}
cnt++;
if (cnt <= TB_RECURSIVE_CUTOFF) {
- if (tb_displayline(tb, f, code->co_filename, tb->tb_lineno,
+ if (tb_displayline(tb, f, code->co_filename, tb_lineno,
tb->tb_frame, code->co_name) < 0) {
goto error;
}
1
0
[3.11] gh-111366: Correctly show custom syntax error messages in the codeop module functions (GH-111384). (#111516)
by pablogsal 31 Oct '23
by pablogsal 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/19a266ca8961d8dcb85799adb1025e4f4f…
commit: 19a266ca8961d8dcb85799adb1025e4f4fb2f087
branch: 3.11
author: Pablo Galindo Salgado <Pablogsal(a)gmail.com>
committer: pablogsal <Pablogsal(a)gmail.com>
date: 2023-10-31T14:41:20Z
summary:
[3.11] gh-111366: Correctly show custom syntax error messages in the codeop module functions (GH-111384). (#111516)
(cherry picked from commit cd6e0a04a16535d8bc727c84f73730c53267184e)
files:
A Misc/NEWS.d/next/Core and Builtins/2023-10-27-12-17-49.gh-issue-111366._TSknV.rst
M Lib/codeop.py
M Lib/test/test_codeop.py
diff --git a/Lib/codeop.py b/Lib/codeop.py
index 2213b69f231f9..e64911ee5ad41 100644
--- a/Lib/codeop.py
+++ b/Lib/codeop.py
@@ -70,8 +70,7 @@ def _maybe_compile(compiler, source, filename, symbol):
return None
# fallthrough
- return compiler(source, filename, symbol)
-
+ return compiler(source, filename, symbol, incomplete_input=False)
def _is_syntax_error(err1, err2):
rep1 = repr(err1)
@@ -82,8 +81,12 @@ def _is_syntax_error(err1, err2):
return True
return False
-def _compile(source, filename, symbol):
- return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT)
+def _compile(source, filename, symbol, incomplete_input=True):
+ flags = 0
+ if incomplete_input:
+ flags |= PyCF_ALLOW_INCOMPLETE_INPUT
+ flags |= PyCF_DONT_IMPLY_DEDENT
+ return compile(source, filename, symbol, flags)
def compile_command(source, filename="<input>", symbol="single"):
r"""Compile a command and determine whether it is incomplete.
@@ -114,8 +117,12 @@ class Compile:
def __init__(self):
self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT
- def __call__(self, source, filename, symbol):
- codeob = compile(source, filename, symbol, self.flags, True)
+ def __call__(self, source, filename, symbol, **kwargs):
+ flags = self.flags
+ if kwargs.get('incomplete_input', True) is False:
+ flags &= ~PyCF_DONT_IMPLY_DEDENT
+ flags &= ~PyCF_ALLOW_INCOMPLETE_INPUT
+ codeob = compile(source, filename, symbol, flags, True)
for feature in _features:
if codeob.co_flags & feature.compiler_flag:
self.flags |= feature.compiler_flag
diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py
index 133096d25a44b..94ea06f79d361 100644
--- a/Lib/test/test_codeop.py
+++ b/Lib/test/test_codeop.py
@@ -7,6 +7,7 @@
import warnings
from test import support
from test.support import warnings_helper
+from textwrap import dedent
from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT
import io
@@ -341,6 +342,19 @@ def test_invalid_warning(self):
self.assertRegex(str(w[0].message), 'invalid escape sequence')
self.assertEqual(w[0].filename, '<input>')
+ def assertSyntaxErrorMatches(self, code, message):
+ with self.subTest(code):
+ with self.assertRaisesRegex(SyntaxError, message):
+ compile_command(code, symbol='exec')
+
+ def test_syntax_errors(self):
+ self.assertSyntaxErrorMatches(
+ dedent("""\
+ def foo(x,x):
+ pass
+ """), "duplicate argument 'x' in function definition")
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-10-27-12-17-49.gh-issue-111366._TSknV.rst b/Misc/NEWS.d/next/Core and Builtins/2023-10-27-12-17-49.gh-issue-111366._TSknV.rst
new file mode 100644
index 0000000000000..7e76ce916ea71
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-10-27-12-17-49.gh-issue-111366._TSknV.rst
@@ -0,0 +1,3 @@
+Fix an issue in the :mod:`codeop` that was causing :exc:`SyntaxError`
+exceptions raised in the presence of invalid syntax to not contain precise
+error messages. Patch by Pablo Galindo
1
0
GH-111438: Add Support for Sharing Floats Between Interpreters (gh-111439)
by ericsnowcurrently 31 Oct '23
by ericsnowcurrently 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/ad6380bc340900e0977ce54928b0d3e166…
commit: ad6380bc340900e0977ce54928b0d3e166c7cf99
branch: main
author: Anthony Shaw <anthony.p.shaw(a)gmail.com>
committer: ericsnowcurrently <ericsnowcurrently(a)gmail.com>
date: 2023-10-31T08:17:20-06:00
summary:
GH-111438: Add Support for Sharing Floats Between Interpreters (gh-111439)
This only affects users of the APIs in pycore_crossinterp.h (AKA _xxsubinterpretersmodule.c and _xxinterpchannels.c).
files:
A Misc/NEWS.d/next/Core and Builtins/2023-10-29-12-33-33.gh-issue-111438.bHTLLl.rst
M Lib/test/test__xxsubinterpreters.py
M Lib/test/test_interpreters.py
M Python/crossinterp.c
diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py
index f0b9101f0a20b..5dce3e5f4031c 100644
--- a/Lib/test/test__xxsubinterpreters.py
+++ b/Lib/test/test__xxsubinterpreters.py
@@ -102,6 +102,7 @@ def test_default_shareables(self):
'spam',
10,
-10,
+ 100.0,
]
for obj in shareables:
with self.subTest(obj):
@@ -129,7 +130,6 @@ class SubBytes(bytes):
object,
object(),
Exception(),
- 100.0,
# user-defined types and objects
Cheese,
Cheese('Wensleydale'),
@@ -189,6 +189,9 @@ def test_non_shareable_int(self):
with self.assertRaises(OverflowError):
_testinternalcapi.get_crossinterp_data(i)
+ def test_float(self):
+ self._assert_values([0.0, 1.1, -1.0, 0.12345678, -0.12345678])
+
class ModuleTests(TestBase):
diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py
index e124a7cc7259a..7a2f489408b96 100644
--- a/Lib/test/test_interpreters.py
+++ b/Lib/test/test_interpreters.py
@@ -778,6 +778,7 @@ def test_default_shareables(self):
'spam',
10,
-10,
+ 100.0,
]
for obj in shareables:
with self.subTest(obj):
@@ -805,7 +806,6 @@ class SubBytes(bytes):
object,
object(),
Exception(),
- 100.0,
# user-defined types and objects
Cheese,
Cheese('Wensleydale'),
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-10-29-12-33-33.gh-issue-111438.bHTLLl.rst b/Misc/NEWS.d/next/Core and Builtins/2023-10-29-12-33-33.gh-issue-111438.bHTLLl.rst
new file mode 100644
index 0000000000000..b181977d8d195
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-10-29-12-33-33.gh-issue-111438.bHTLLl.rst
@@ -0,0 +1 @@
+Added support for sharing of float type with interpreters API.
diff --git a/Python/crossinterp.c b/Python/crossinterp.c
index 74f1d6ecef132..17c476ba4369c 100644
--- a/Python/crossinterp.c
+++ b/Python/crossinterp.c
@@ -585,6 +585,29 @@ _long_shared(PyThreadState *tstate, PyObject *obj,
return 0;
}
+static PyObject *
+_new_float_object(_PyCrossInterpreterData *data)
+{
+ double * value_ptr = data->data;
+ return PyFloat_FromDouble(*value_ptr);
+}
+
+static int
+_float_shared(PyThreadState *tstate, PyObject *obj,
+ _PyCrossInterpreterData *data)
+{
+ if (_PyCrossInterpreterData_InitWithSize(
+ data, tstate->interp, sizeof(double), NULL,
+ _new_float_object
+ ) < 0)
+ {
+ return -1;
+ }
+ double *shared = (double *)data->data;
+ *shared = PyFloat_AsDouble(obj);
+ return 0;
+}
+
static PyObject *
_new_none_object(_PyCrossInterpreterData *data)
{
@@ -624,4 +647,9 @@ _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry)
if (_xidregistry_add_type(xidregistry, &PyUnicode_Type, _str_shared) != 0) {
Py_FatalError("could not register str for cross-interpreter sharing");
}
+
+ // float
+ if (_xidregistry_add_type(xidregistry, &PyFloat_Type, _float_shared) != 0) {
+ Py_FatalError("could not register float for cross-interpreter sharing");
+ }
}
1
0
[3.11] gh-108303: Move all inspect test files to `test_inspect/` (GH-109607) (#111543)
by vstinner 31 Oct '23
by vstinner 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/bc9f47097ef5c44c87cb91a441c19ee532…
commit: bc9f47097ef5c44c87cb91a441c19ee532907684
branch: 3.11
author: Nikita Sobolev <mail(a)sobolevn.me>
committer: vstinner <vstinner(a)python.org>
date: 2023-10-31T14:00:39Z
summary:
[3.11] gh-108303: Move all inspect test files to `test_inspect/` (GH-109607) (#111543)
files:
A Lib/test/test_inspect/__init__.py
A Lib/test/test_inspect/inspect_fodder.py
A Lib/test/test_inspect/inspect_fodder2.py
A Lib/test/test_inspect/inspect_stock_annotations.py
A Lib/test/test_inspect/inspect_stringized_annotations.py
A Lib/test/test_inspect/inspect_stringized_annotations_2.py
A Lib/test/test_inspect/test_inspect.py
D Lib/test/inspect_fodder.py
D Lib/test/inspect_fodder2.py
D Lib/test/inspect_stock_annotations.py
D Lib/test/inspect_stringized_annotations.py
D Lib/test/inspect_stringized_annotations_2.py
D Lib/test/test_inspect.py
M Lib/test/libregrtest/findtests.py
M Lib/test/test_import/__init__.py
M Lib/test/test_tokenize.py
M Makefile.pre.in
diff --git a/Lib/test/libregrtest/findtests.py b/Lib/test/libregrtest/findtests.py
index a4235b52eca0a..78343775bc5b9 100644
--- a/Lib/test/libregrtest/findtests.py
+++ b/Lib/test/libregrtest/findtests.py
@@ -21,6 +21,7 @@
"test_concurrent_futures",
"test_future_stmt",
"test_gdb",
+ "test_inspect",
"test_multiprocessing_fork",
"test_multiprocessing_forkserver",
"test_multiprocessing_spawn",
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index 131aebbd4e1f5..8632ac2e818fa 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -1,5 +1,4 @@
import builtins
-import contextlib
import errno
import glob
import importlib.util
diff --git a/Lib/test/test_inspect/__init__.py b/Lib/test/test_inspect/__init__.py
new file mode 100644
index 0000000000000..f2a39a3fe29c7
--- /dev/null
+++ b/Lib/test/test_inspect/__init__.py
@@ -0,0 +1,6 @@
+import os
+from test import support
+
+
+def load_tests(*args):
+ return support.load_package_tests(os.path.dirname(__file__), *args)
diff --git a/Lib/test/inspect_fodder.py b/Lib/test/test_inspect/inspect_fodder.py
similarity index 100%
rename from Lib/test/inspect_fodder.py
rename to Lib/test/test_inspect/inspect_fodder.py
diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/test_inspect/inspect_fodder2.py
similarity index 100%
rename from Lib/test/inspect_fodder2.py
rename to Lib/test/test_inspect/inspect_fodder2.py
diff --git a/Lib/test/inspect_stock_annotations.py b/Lib/test/test_inspect/inspect_stock_annotations.py
similarity index 100%
rename from Lib/test/inspect_stock_annotations.py
rename to Lib/test/test_inspect/inspect_stock_annotations.py
diff --git a/Lib/test/inspect_stringized_annotations.py b/Lib/test/test_inspect/inspect_stringized_annotations.py
similarity index 100%
rename from Lib/test/inspect_stringized_annotations.py
rename to Lib/test/test_inspect/inspect_stringized_annotations.py
diff --git a/Lib/test/inspect_stringized_annotations_2.py b/Lib/test/test_inspect/inspect_stringized_annotations_2.py
similarity index 100%
rename from Lib/test/inspect_stringized_annotations_2.py
rename to Lib/test/test_inspect/inspect_stringized_annotations_2.py
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect/test_inspect.py
similarity index 99%
rename from Lib/test/test_inspect.py
rename to Lib/test/test_inspect/test_inspect.py
index 650d56e39c415..6d4050a5ded10 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -30,12 +30,13 @@
from test.support.import_helper import DirsOnSysPath, ready_to_import
from test.support.os_helper import TESTFN
from test.support.script_helper import assert_python_ok, assert_python_failure
-from test import inspect_fodder as mod
-from test import inspect_fodder2 as mod2
from test import support
-from test import inspect_stock_annotations
-from test import inspect_stringized_annotations
-from test import inspect_stringized_annotations_2
+
+from . import inspect_fodder as mod
+from . import inspect_fodder2 as mod2
+from . import inspect_stock_annotations
+from . import inspect_stringized_annotations
+from . import inspect_stringized_annotations_2
# Functions tested in this suite:
diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py
index 62f152fe431d5..b5f57f693474d 100644
--- a/Lib/test/test_tokenize.py
+++ b/Lib/test/test_tokenize.py
@@ -1624,7 +1624,7 @@ def test_random_files(self):
# 7 more testfiles fail. Remove them also until the failure is diagnosed.
testfiles.remove(os.path.join(tempdir, "test_unicode_identifiers.py"))
- for f in ('buffer', 'builtin', 'fileio', 'inspect', 'os', 'platform', 'sys'):
+ for f in ('buffer', 'builtin', 'fileio', 'os', 'platform', 'sys'):
testfiles.remove(os.path.join(tempdir, "test_%s.py") % f)
if not support.is_resource_enabled("cpu"):
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 49238902718eb..ada866d83c042 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -1969,6 +1969,7 @@ TESTSUBDIRS= ctypes/test \
test/test_email/data \
test/test_future_stmt \
test/test_gdb \
+ test/test_inspect \
test/test_import \
test/test_import/data \
test/test_import/data/circular_imports \
1
0
[3.11] gh-111380: Show SyntaxWarnings only once when parsing if invalid syntax is encouintered (GH-111381) (#111383)
by pablogsal 31 Oct '23
by pablogsal 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/08e4e11b758517ad614d71ff2377dd4057…
commit: 08e4e11b758517ad614d71ff2377dd4057ffdcb1
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: pablogsal <Pablogsal(a)gmail.com>
date: 2023-10-31T13:29:42Z
summary:
[3.11] gh-111380: Show SyntaxWarnings only once when parsing if invalid syntax is encouintered (GH-111381) (#111383)
gh-111380: Show SyntaxWarnings only once when parsing if invalid syntax is encouintered (GH-111381)
(cherry picked from commit 3d2f1f0b830d86f16f42c42b54d3ea4453dac318)
Co-authored-by: Pablo Galindo Salgado <Pablogsal(a)gmail.com>
files:
A Misc/NEWS.d/next/Core and Builtins/2023-10-27-11-51-40.gh-issue-111380.vgSbir.rst
M Lib/test/test_string_literals.py
M Parser/string_parser.c
diff --git a/Lib/test/test_string_literals.py b/Lib/test/test_string_literals.py
index 7247b7e48bc2b..aeec703d5f5ab 100644
--- a/Lib/test/test_string_literals.py
+++ b/Lib/test/test_string_literals.py
@@ -131,6 +131,18 @@ def test_eval_str_invalid_escape(self):
self.assertEqual(exc.lineno, 1)
self.assertEqual(exc.offset, 1)
+ # Check that the warning is raised ony once if there are syntax errors
+
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter('always', category=DeprecationWarning)
+ with self.assertRaises(SyntaxError) as cm:
+ eval("'\\e' $")
+ exc = cm.exception
+ self.assertEqual(len(w), 1)
+ self.assertEqual(w[0].category, DeprecationWarning)
+ self.assertRegex(str(w[0].message), 'invalid escape sequence')
+ self.assertEqual(w[0].filename, '<string>')
+
def test_eval_str_invalid_octal_escape(self):
for i in range(0o400, 0o1000):
with self.assertWarns(DeprecationWarning):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-10-27-11-51-40.gh-issue-111380.vgSbir.rst b/Misc/NEWS.d/next/Core and Builtins/2023-10-27-11-51-40.gh-issue-111380.vgSbir.rst
new file mode 100644
index 0000000000000..4ce6398dbfe3b
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-10-27-11-51-40.gh-issue-111380.vgSbir.rst
@@ -0,0 +1,2 @@
+Fix a bug that was causing :exc:`SyntaxWarning` to appear twice when parsing
+if invalid syntax is encountered later. Patch by Pablo galindo
diff --git a/Parser/string_parser.c b/Parser/string_parser.c
index fb2b9808af15a..7079b82d04f8e 100644
--- a/Parser/string_parser.c
+++ b/Parser/string_parser.c
@@ -11,6 +11,11 @@
static int
warn_invalid_escape_sequence(Parser *p, const char *first_invalid_escape, Token *t)
{
+ if (p->call_invalid_rules) {
+ // Do not report warnings if we are in the second pass of the parser
+ // to avoid showing the warning twice.
+ return 0;
+ }
unsigned char c = *first_invalid_escape;
int octal = ('4' <= c && c <= '7');
PyObject *msg =
1
0
GH-111485: Remove some special cases from the code generator and bytecodes.c (GH-111540)
by markshannon 31 Oct '23
by markshannon 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/2904d99839cd4620818fd0556a1c0b0229…
commit: 2904d99839cd4620818fd0556a1c0b0229944abc
branch: main
author: Mark Shannon <mark(a)hotpy.org>
committer: markshannon <mark(a)hotpy.org>
date: 2023-10-31T13:21:07Z
summary:
GH-111485: Remove some special cases from the code generator and bytecodes.c (GH-111540)
files:
M Include/internal/pycore_opcode_metadata.h
M Python/abstract_interp_cases.c.h
M Python/bytecodes.c
M Python/executor_cases.c.h
M Python/generated_cases.c.h
M Tools/cases_generator/analysis.py
M Tools/cases_generator/generate_cases.py
M Tools/cases_generator/instructions.py
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index 27948749d58eb..7b89f89b3f69c 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1298,9 +1298,9 @@ struct opcode_macro_expansion {
#define OPARG_BOTTOM 6
#define OPARG_SAVE_RETURN_OFFSET 7
-#define OPCODE_METADATA_FMT(OP) (_PyOpcode_opcode_metadata[(OP)].instr_format)
+#define OPCODE_METADATA_FLAGS(OP) (_PyOpcode_opcode_metadata[(OP)].flags & (HAS_ARG_FLAG | HAS_JUMP_FLAG))
#define SAME_OPCODE_METADATA(OP1, OP2) \
- (OPCODE_METADATA_FMT(OP1) == OPCODE_METADATA_FMT(OP2))
+ (OPCODE_METADATA_FLAGS(OP1) == OPCODE_METADATA_FLAGS(OP2))
#define OPCODE_METADATA_SIZE 512
#define OPCODE_UOP_NAME_SIZE 512
@@ -1313,14 +1313,14 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
[RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
[INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
- [LOAD_CLOSURE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+ [LOAD_CLOSURE] = { true, 0, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[LOAD_FAST_CHECK] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG },
[LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[LOAD_FAST_AND_CLEAR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[LOAD_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[LOAD_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG },
[STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
- [STORE_FAST_MAYBE_NULL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+ [STORE_FAST_MAYBE_NULL] = { true, 0, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[STORE_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[STORE_FAST_STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
[POP_TOP] = { true, INSTR_FMT_IX, 0 },
@@ -1436,13 +1436,13 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
[LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
- [LOAD_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
- [LOAD_ZERO_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
- [LOAD_ZERO_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
+ [LOAD_SUPER_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
+ [LOAD_ZERO_SUPER_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
+ [LOAD_ZERO_SUPER_ATTR] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
[LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
- [LOAD_METHOD] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
+ [LOAD_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
[_GUARD_TYPE_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
[_CHECK_MANAGED_OBJECT_HAS_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
[_LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
@@ -1477,9 +1477,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
[IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
[JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
- [JUMP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [JUMP_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
+ [JUMP] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [JUMP_NO_INTERRUPT] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
[POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
@@ -1515,10 +1515,10 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[BEFORE_ASYNC_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
[BEFORE_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
[WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
- [SETUP_FINALLY] = { true, INSTR_FMT_IX, 0 },
- [SETUP_CLEANUP] = { true, INSTR_FMT_IX, 0 },
- [SETUP_WITH] = { true, INSTR_FMT_IX, 0 },
- [POP_BLOCK] = { true, INSTR_FMT_IX, 0 },
+ [SETUP_FINALLY] = { true, 0, 0 },
+ [SETUP_CLEANUP] = { true, 0, 0 },
+ [SETUP_WITH] = { true, 0, 0 },
+ [POP_BLOCK] = { true, 0, 0 },
[PUSH_EXC_INFO] = { true, INSTR_FMT_IX, 0 },
[_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
[_GUARD_KEYS_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
@@ -1577,7 +1577,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[SWAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
- [INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG },
+ [INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG },
[INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
[INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
@@ -1670,6 +1670,7 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN
[LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _LOAD_GLOBAL_MODULE, 1, 3 } } },
[LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION, 1, 2 }, { _LOAD_GLOBAL_BUILTINS, 1, 3 } } },
[DELETE_FAST] = { .nuops = 1, .uops = { { DELETE_FAST, 0, 0 } } },
+ [MAKE_CELL] = { .nuops = 1, .uops = { { MAKE_CELL, 0, 0 } } },
[DELETE_DEREF] = { .nuops = 1, .uops = { { DELETE_DEREF, 0, 0 } } },
[LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { LOAD_FROM_DICT_OR_DEREF, 0, 0 } } },
[LOAD_DEREF] = { .nuops = 1, .uops = { { LOAD_DEREF, 0, 0 } } },
@@ -1712,6 +1713,7 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN
[MATCH_KEYS] = { .nuops = 1, .uops = { { MATCH_KEYS, 0, 0 } } },
[GET_ITER] = { .nuops = 1, .uops = { { GET_ITER, 0, 0 } } },
[GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { GET_YIELD_FROM_ITER, 0, 0 } } },
+ [BEFORE_ASYNC_WITH] = { .nuops = 1, .uops = { { BEFORE_ASYNC_WITH, 0, 0 } } },
[WITH_EXCEPT_START] = { .nuops = 1, .uops = { { WITH_EXCEPT_START, 0, 0 } } },
[PUSH_EXC_INFO] = { .nuops = 1, .uops = { { PUSH_EXC_INFO, 0, 0 } } },
[LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } },
@@ -2057,6 +2059,7 @@ const uint8_t _PyOpcode_Caches[256] = {
[LOAD_SUPER_ATTR] = 1,
[LOAD_ATTR] = 9,
[COMPARE_OP] = 1,
+ [JUMP_BACKWARD] = 1,
[POP_JUMP_IF_FALSE] = 1,
[POP_JUMP_IF_TRUE] = 1,
[POP_JUMP_IF_NONE] = 1,
@@ -2064,7 +2067,6 @@ const uint8_t _PyOpcode_Caches[256] = {
[FOR_ITER] = 1,
[CALL] = 3,
[BINARY_OP] = 1,
- [JUMP_BACKWARD] = 1,
};
#endif // NEED_OPCODE_METADATA
diff --git a/Python/abstract_interp_cases.c.h b/Python/abstract_interp_cases.c.h
index 232c569a3ddb3..11090ee4dba39 100644
--- a/Python/abstract_interp_cases.c.h
+++ b/Python/abstract_interp_cases.c.h
@@ -344,6 +344,10 @@
break;
}
+ case MAKE_CELL: {
+ break;
+ }
+
case DELETE_DEREF: {
break;
}
@@ -668,6 +672,13 @@
break;
}
+ case BEFORE_ASYNC_WITH: {
+ STACK_GROW(1);
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true);
+ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
+ break;
+ }
+
case WITH_EXCEPT_START: {
STACK_GROW(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index d33ee3265d254..bb2d491523ca4 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -742,6 +742,7 @@ dummy_func(
}
inst(RAISE_VARARGS, (args[oparg] -- )) {
+ TIER_ONE_ONLY
PyObject *cause = NULL, *exc = NULL;
switch (oparg) {
case 2:
@@ -1073,6 +1074,7 @@ dummy_func(
}
inst(RERAISE, (values[oparg], exc -- values[oparg])) {
+ TIER_ONE_ONLY
assert(oparg >= 0 && oparg <= 2);
if (oparg) {
PyObject *lasti = values[0];
@@ -1094,6 +1096,7 @@ dummy_func(
}
inst(END_ASYNC_FOR, (awaitable, exc -- )) {
+ TIER_ONE_ONLY
assert(exc && PyExceptionInstance_Check(exc));
if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) {
DECREF_INPUTS();
@@ -1107,6 +1110,7 @@ dummy_func(
}
inst(CLEANUP_THROW, (sub_iter, last_sent_val, exc_value -- none, value)) {
+ TIER_ONE_ONLY
assert(throwflag);
assert(exc_value && PyExceptionInstance_Check(exc_value));
if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) {
@@ -1467,7 +1471,7 @@ dummy_func(
PyObject *initial = GETLOCAL(oparg);
PyObject *cell = PyCell_New(initial);
if (cell == NULL) {
- goto resume_with_error;
+ goto error;
}
SETLOCAL(oparg, cell);
}
@@ -2247,6 +2251,7 @@ dummy_func(
}
inst(IMPORT_NAME, (level, fromlist -- res)) {
+ TIER_ONE_ONLY
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
res = import_name(tstate, frame, name, fromlist, level);
DECREF_INPUTS();
@@ -2254,6 +2259,7 @@ dummy_func(
}
inst(IMPORT_FROM, (from -- from, res)) {
+ TIER_ONE_ONLY
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
res = import_from(tstate, from, name);
ERROR_IF(res == NULL, error);
@@ -2263,10 +2269,10 @@ dummy_func(
JUMPBY(oparg);
}
- inst(JUMP_BACKWARD, (--)) {
+ inst(JUMP_BACKWARD, (unused/1 --)) {
CHECK_EVAL_BREAKER();
assert(oparg <= INSTR_OFFSET());
- JUMPBY(1-oparg);
+ JUMPBY(-oparg);
#if ENABLE_SPECIALIZATION
this_instr[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
if (this_instr[1].cache > tstate->interp->optimizer_backedge_threshold &&
@@ -2297,6 +2303,7 @@ dummy_func(
};
inst(ENTER_EXECUTOR, (--)) {
+ TIER_ONE_ONLY
CHECK_EVAL_BREAKER();
PyCodeObject *code = _PyFrame_GetCode(frame);
@@ -2703,6 +2710,7 @@ dummy_func(
}
inst(BEFORE_WITH, (mgr -- exit, res)) {
+ TIER_ONE_ONLY
/* pop the context manager, push its __exit__ and the
* value returned from calling its __enter__
*/
@@ -3831,9 +3839,9 @@ dummy_func(
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_JUMP);
}
- inst(INSTRUMENTED_JUMP_BACKWARD, ( -- )) {
+ inst(INSTRUMENTED_JUMP_BACKWARD, (unused/1 -- )) {
CHECK_EVAL_BREAKER();
- INSTRUMENTED_JUMP(this_instr, next_instr + 1 - oparg, PY_MONITORING_EVENT_JUMP);
+ INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP);
}
inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 24de9eadf5904..4d5b6dc7f0105 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -1240,6 +1240,18 @@
break;
}
+ case MAKE_CELL: {
+ // "initial" is probably NULL but not if it's an arg (or set
+ // via PyFrame_LocalsToFast() before MAKE_CELL has run).
+ PyObject *initial = GETLOCAL(oparg);
+ PyObject *cell = PyCell_New(initial);
+ if (cell == NULL) {
+ goto error;
+ }
+ SETLOCAL(oparg, cell);
+ break;
+ }
+
case DELETE_DEREF: {
PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell);
@@ -2320,6 +2332,46 @@
break;
}
+ case BEFORE_ASYNC_WITH: {
+ PyObject *mgr;
+ PyObject *exit;
+ PyObject *res;
+ mgr = stack_pointer[-1];
+ PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__));
+ if (enter == NULL) {
+ if (!_PyErr_Occurred(tstate)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'%.200s' object does not support the "
+ "asynchronous context manager protocol",
+ Py_TYPE(mgr)->tp_name);
+ }
+ goto error;
+ }
+ exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__));
+ if (exit == NULL) {
+ if (!_PyErr_Occurred(tstate)) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "'%.200s' object does not support the "
+ "asynchronous context manager protocol "
+ "(missed __aexit__ method)",
+ Py_TYPE(mgr)->tp_name);
+ }
+ Py_DECREF(enter);
+ goto error;
+ }
+ Py_DECREF(mgr);
+ res = _PyObject_CallNoArgs(enter);
+ Py_DECREF(enter);
+ if (res == NULL) {
+ Py_DECREF(exit);
+ if (true) goto pop_1_error;
+ }
+ STACK_GROW(1);
+ stack_pointer[-2] = exit;
+ stack_pointer[-1] = res;
+ break;
+ }
+
case WITH_EXCEPT_START: {
PyObject *val;
PyObject *lasti;
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 40c8cd8798c93..8b6ebe4f8ab4a 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -1090,6 +1090,7 @@
INSTRUCTION_STATS(RAISE_VARARGS);
PyObject **args;
args = stack_pointer - oparg;
+ TIER_ONE_ONLY
PyObject *cause = NULL, *exc = NULL;
switch (oparg) {
case 2:
@@ -1532,6 +1533,7 @@
PyObject **values;
exc = stack_pointer[-1];
values = stack_pointer - 1 - oparg;
+ TIER_ONE_ONLY
assert(oparg >= 0 && oparg <= 2);
if (oparg) {
PyObject *lasti = values[0];
@@ -1560,6 +1562,7 @@
PyObject *awaitable;
exc = stack_pointer[-1];
awaitable = stack_pointer[-2];
+ TIER_ONE_ONLY
assert(exc && PyExceptionInstance_Check(exc));
if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) {
Py_DECREF(awaitable);
@@ -1587,6 +1590,7 @@
exc_value = stack_pointer[-1];
last_sent_val = stack_pointer[-2];
sub_iter = stack_pointer[-3];
+ TIER_ONE_ONLY
assert(throwflag);
assert(exc_value && PyExceptionInstance_Check(exc_value));
if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) {
@@ -2107,7 +2111,7 @@
PyObject *initial = GETLOCAL(oparg);
PyObject *cell = PyCell_New(initial);
if (cell == NULL) {
- goto resume_with_error;
+ goto error;
}
SETLOCAL(oparg, cell);
DISPATCH();
@@ -3282,6 +3286,7 @@
PyObject *res;
fromlist = stack_pointer[-1];
level = stack_pointer[-2];
+ TIER_ONE_ONLY
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
res = import_name(tstate, frame, name, fromlist, level);
Py_DECREF(level);
@@ -3299,6 +3304,7 @@
PyObject *from;
PyObject *res;
from = stack_pointer[-1];
+ TIER_ONE_ONLY
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
res = import_from(tstate, from, name);
if (res == NULL) goto error;
@@ -3317,11 +3323,11 @@
TARGET(JUMP_BACKWARD) {
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
- next_instr += 1;
+ next_instr += 2;
INSTRUCTION_STATS(JUMP_BACKWARD);
CHECK_EVAL_BREAKER();
assert(oparg <= INSTR_OFFSET());
- JUMPBY(1-oparg);
+ JUMPBY(-oparg);
#if ENABLE_SPECIALIZATION
this_instr[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
if (this_instr[1].cache > tstate->interp->optimizer_backedge_threshold &&
@@ -3346,6 +3352,7 @@
frame->instr_ptr = next_instr;
next_instr += 1;
INSTRUCTION_STATS(ENTER_EXECUTOR);
+ TIER_ONE_ONLY
CHECK_EVAL_BREAKER();
PyCodeObject *code = _PyFrame_GetCode(frame);
@@ -3890,6 +3897,7 @@
PyObject *exit;
PyObject *res;
mgr = stack_pointer[-1];
+ TIER_ONE_ONLY
/* pop the context manager, push its __exit__ and the
* value returned from calling its __enter__
*/
@@ -5560,10 +5568,10 @@
TARGET(INSTRUMENTED_JUMP_BACKWARD) {
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
- next_instr += 1;
+ next_instr += 2;
INSTRUCTION_STATS(INSTRUMENTED_JUMP_BACKWARD);
CHECK_EVAL_BREAKER();
- INSTRUMENTED_JUMP(this_instr, next_instr + 1 - oparg, PY_MONITORING_EVENT_JUMP);
+ INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP);
DISPATCH();
}
diff --git a/Tools/cases_generator/analysis.py b/Tools/cases_generator/analysis.py
index 180bd01302ec1..027d953fe4739 100644
--- a/Tools/cases_generator/analysis.py
+++ b/Tools/cases_generator/analysis.py
@@ -385,12 +385,9 @@ def analyze_macro(self, macro: parsing.Macro) -> MacroInstruction:
def analyze_pseudo(self, pseudo: parsing.Pseudo) -> PseudoInstruction:
targets = [self.instrs[target] for target in pseudo.targets]
assert targets
- # Make sure the targets have the same fmt
- fmts = list(set([t.instr_fmt for t in targets]))
- assert len(fmts) == 1
ignored_flags = {"HAS_EVAL_BREAK_FLAG", "HAS_DEOPT_FLAG", "HAS_ERROR_FLAG"}
assert len({t.instr_flags.bitmap(ignore=ignored_flags) for t in targets}) == 1
- return PseudoInstruction(pseudo.name, targets, fmts[0], targets[0].instr_flags)
+ return PseudoInstruction(pseudo.name, targets, targets[0].instr_flags)
def analyze_instruction(
self, instr: Instruction, offset: int
diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py
index ef96ed3748b05..ed4fc8d6130ce 100644
--- a/Tools/cases_generator/generate_cases.py
+++ b/Tools/cases_generator/generate_cases.py
@@ -395,13 +395,9 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
case parsing.Macro():
format = self.macro_instrs[thing.name].instr_fmt
case parsing.Pseudo():
- for target in self.pseudos[thing.name].targets:
- target_instr = self.instrs.get(target)
- assert target_instr
- if format is None:
- format = target_instr.instr_fmt
- else:
- assert format == target_instr.instr_fmt
+ # Pseudo instructions exist only in the compiler,
+ # so do not have a format
+ continue
case _:
assert_never(thing)
assert format is not None
@@ -464,12 +460,12 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
self.out.emit("")
self.out.emit(
- "#define OPCODE_METADATA_FMT(OP) "
- "(_PyOpcode_opcode_metadata[(OP)].instr_format)"
+ "#define OPCODE_METADATA_FLAGS(OP) "
+ "(_PyOpcode_opcode_metadata[(OP)].flags & (HAS_ARG_FLAG | HAS_JUMP_FLAG))"
)
self.out.emit("#define SAME_OPCODE_METADATA(OP1, OP2) \\")
self.out.emit(
- " (OPCODE_METADATA_FMT(OP1) == OPCODE_METADATA_FMT(OP2))"
+ " (OPCODE_METADATA_FLAGS(OP1) == OPCODE_METADATA_FLAGS(OP2))"
)
self.out.emit("")
@@ -545,8 +541,6 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
and not mac.name.startswith("INSTRUMENTED_")
):
self.out.emit(f"[{mac.name}] = {mac.cache_offset},")
- # Irregular case:
- self.out.emit("[JUMP_BACKWARD] = 1,")
deoptcodes = {}
for name, op in self.opmap.items():
@@ -732,12 +726,13 @@ def write_expansions(
f"{{ .nuops = {len(pieces)}, .uops = {{ {', '.join(pieces)} }} }},"
)
- def emit_metadata_entry(self, name: str, fmt: str, flags: InstructionFlags) -> None:
+ def emit_metadata_entry(self, name: str, fmt: str | None, flags: InstructionFlags) -> None:
flag_names = flags.names(value=True)
if not flag_names:
flag_names.append("0")
+ fmt_macro = "0" if fmt is None else INSTR_FMT_PREFIX + fmt
self.out.emit(
- f"[{name}] = {{ true, {INSTR_FMT_PREFIX}{fmt},"
+ f"[{name}] = {{ true, {fmt_macro},"
f" {' | '.join(flag_names)} }},"
)
@@ -751,7 +746,7 @@ def write_metadata_for_macro(self, mac: MacroInstruction) -> None:
def write_metadata_for_pseudo(self, ps: PseudoInstruction) -> None:
"""Write metadata for a macro-instruction."""
- self.emit_metadata_entry(ps.name, ps.instr_fmt, ps.instr_flags)
+ self.emit_metadata_entry(ps.name, None, ps.instr_flags)
def write_instructions(
self, output_filename: str, emit_line_directives: bool
diff --git a/Tools/cases_generator/instructions.py b/Tools/cases_generator/instructions.py
index e9ed2a867ae2b..636a6beb818a1 100644
--- a/Tools/cases_generator/instructions.py
+++ b/Tools/cases_generator/instructions.py
@@ -25,18 +25,10 @@ class ActiveCacheEffect:
FORBIDDEN_NAMES_IN_UOPS = (
- "resume_with_error",
- "kwnames",
"next_instr",
"oparg1", # Proxy for super-instructions like LOAD_FAST_LOAD_FAST
"JUMPBY",
"DISPATCH",
- "INSTRUMENTED_JUMP",
- "throwflag",
- "exception_unwind",
- "import_from",
- "import_name",
- "_PyObject_CallNoArgs", # Proxy for BEFORE_WITH
"TIER_ONE_ONLY",
)
@@ -294,7 +286,6 @@ class PseudoInstruction:
name: str
targets: list[Instruction]
- instr_fmt: str
instr_flags: InstructionFlags
1
0
GH-111485: Increment `next_instr` consistently at the start of the instruction. (GH-111486)
by markshannon 31 Oct '23
by markshannon 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/d27acd4461ee603bcf6f4a81ca6afccc9f…
commit: d27acd4461ee603bcf6f4a81ca6afccc9fc87331
branch: main
author: Mark Shannon <mark(a)hotpy.org>
committer: markshannon <mark(a)hotpy.org>
date: 2023-10-31T10:09:54Z
summary:
GH-111485: Increment `next_instr` consistently at the start of the instruction. (GH-111486)
files:
M Include/internal/pycore_opcode_metadata.h
M Lib/test/test_generated_cases.py
M Lib/test/test_monitoring.py
M Python/bytecodes.c
M Python/ceval.c
M Python/ceval_macros.h
M Python/executor_cases.c.h
M Python/generated_cases.c.h
M Tools/cases_generator/analysis.py
M Tools/cases_generator/instructions.py
M Tools/cases_generator/stacking.py
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index e2ed9bad7833a..27948749d58eb 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1356,8 +1356,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[_GUARD_BOTH_UNICODE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
[_BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
[BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
- [_BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IX, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
- [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IX, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
+ [_BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
+ [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
[BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
[STORE_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
@@ -1434,7 +1434,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[DICT_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[DICT_MERGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
- [INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG },
+ [INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
[LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
[LOAD_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
[LOAD_ZERO_SUPER_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG },
@@ -1495,7 +1495,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[GET_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
[GET_YIELD_FROM_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
[FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG },
- [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
+ [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[_ITER_CHECK_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
[_ITER_JUMP_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[_IS_ITER_EXHAUSTED_LIST] = { true, INSTR_FMT_IX, 0 },
@@ -1533,7 +1533,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[_CHECK_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
[_LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
[LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
- [INSTRUMENTED_CALL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
+ [INSTRUMENTED_CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
[_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
@@ -2047,6 +2047,7 @@ extern const uint8_t _PyOpcode_Caches[256];
#ifdef NEED_OPCODE_METADATA
const uint8_t _PyOpcode_Caches[256] = {
[TO_BOOL] = 3,
+ [BINARY_OP_INPLACE_ADD_UNICODE] = 1,
[BINARY_SUBSCR] = 1,
[STORE_SUBSCR] = 1,
[SEND] = 1,
diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py
index 790e6b1b1b91e..475d7492040b7 100644
--- a/Lib/test/test_generated_cases.py
+++ b/Lib/test/test_generated_cases.py
@@ -138,6 +138,9 @@ def test_inst_no_args(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
spam();
DISPATCH();
}
@@ -152,6 +155,9 @@ def test_inst_one_pop(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject *value;
value = stack_pointer[-1];
spam();
@@ -169,6 +175,9 @@ def test_inst_one_push(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject *res;
spam();
STACK_GROW(1);
@@ -186,6 +195,9 @@ def test_inst_one_push_one_pop(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -204,6 +216,9 @@ def test_binary_op(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -225,6 +240,9 @@ def test_overlap(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject *right;
PyObject *left;
PyObject *result;
@@ -249,6 +267,9 @@ def test_predictions_and_eval_breaker(self):
"""
output = """
TARGET(OP1) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP1);
PREDICTED(OP1);
static_assert(INLINE_CACHE_ENTRIES_OP1 == 0, "incorrect cache size");
PyObject *arg;
@@ -259,6 +280,9 @@ def test_predictions_and_eval_breaker(self):
}
TARGET(OP3) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP3);
PyObject *arg;
PyObject *res;
arg = stack_pointer[-1];
@@ -278,6 +302,9 @@ def test_error_if_plain(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
if (cond) goto label;
DISPATCH();
}
@@ -292,6 +319,9 @@ def test_error_if_plain_with_comment(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
if (cond) goto label;
DISPATCH();
}
@@ -306,6 +336,9 @@ def test_error_if_pop(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -326,12 +359,14 @@ def test_cache_effect(self):
"""
output = """
TARGET(OP) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(OP);
PyObject *value;
value = stack_pointer[-1];
- uint16_t counter = read_u16(&next_instr[0].cache);
- uint32_t extra = read_u32(&next_instr[1].cache);
+ uint16_t counter = read_u16(&this_instr[1].cache);
+ uint32_t extra = read_u32(&this_instr[2].cache);
STACK_SHRINK(1);
- next_instr += 3;
DISPATCH();
}
"""
@@ -345,6 +380,9 @@ def test_suppress_dispatch(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
goto somewhere;
}
"""
@@ -366,18 +404,24 @@ def test_macro_instruction(self):
"""
output = """
TARGET(OP1) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(OP1);
PyObject *right;
PyObject *left;
right = stack_pointer[-1];
left = stack_pointer[-2];
- uint16_t counter = read_u16(&next_instr[0].cache);
+ uint16_t counter = read_u16(&this_instr[1].cache);
op1(left, right);
- next_instr += 1;
DISPATCH();
}
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 6;
+ INSTRUCTION_STATS(OP);
PREDICTED(OP);
+ _Py_CODEUNIT *this_instr = next_instr - 6;
static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size");
PyObject *right;
PyObject *left;
@@ -387,22 +431,24 @@ def test_macro_instruction(self):
right = stack_pointer[-1];
left = stack_pointer[-2];
{
- uint16_t counter = read_u16(&next_instr[0].cache);
+ uint16_t counter = read_u16(&this_instr[1].cache);
op1(left, right);
}
// OP2
arg2 = stack_pointer[-3];
{
- uint32_t extra = read_u32(&next_instr[3].cache);
+ uint32_t extra = read_u32(&this_instr[4].cache);
res = op2(arg2, left, right);
}
STACK_SHRINK(2);
stack_pointer[-1] = res;
- next_instr += 5;
DISPATCH();
}
TARGET(OP3) {
+ frame->instr_ptr = next_instr;
+ next_instr += 6;
+ INSTRUCTION_STATS(OP3);
PyObject *right;
PyObject *left;
PyObject *arg2;
@@ -413,7 +459,6 @@ def test_macro_instruction(self):
res = op3(arg2, left, right);
STACK_SHRINK(2);
stack_pointer[-1] = res;
- next_instr += 5;
DISPATCH();
}
"""
@@ -427,6 +472,9 @@ def test_array_input(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject *above;
PyObject **values;
PyObject *below;
@@ -449,6 +497,9 @@ def test_array_output(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject *below;
PyObject **values;
PyObject *above;
@@ -470,6 +521,9 @@ def test_array_input_output(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject **values;
PyObject *above;
values = stack_pointer - oparg;
@@ -489,6 +543,9 @@ def test_array_error_if(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject **values;
PyObject *extra;
values = stack_pointer - oparg;
@@ -509,6 +566,9 @@ def test_cond_effect(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
PyObject *cc;
PyObject *input = NULL;
PyObject *aa;
@@ -541,6 +601,9 @@ def test_macro_cond_effect(self):
"""
output = """
TARGET(M) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(M);
PyObject *right;
PyObject *middle;
PyObject *left;
@@ -580,6 +643,9 @@ def test_macro_push_push(self):
"""
output = """
TARGET(M) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(M);
PyObject *val1;
PyObject *val2;
// A
@@ -609,6 +675,9 @@ def test_override_inst(self):
"""
output = """
TARGET(OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(OP);
ham();
DISPATCH();
}
@@ -627,6 +696,9 @@ def test_override_op(self):
"""
output = """
TARGET(M) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(M);
ham();
DISPATCH();
}
diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py
index 3b8ecb765c23f..d12cd9637dd96 100644
--- a/Lib/test/test_monitoring.py
+++ b/Lib/test/test_monitoring.py
@@ -1378,15 +1378,16 @@ def func():
x = 4
else:
x = 6
+ 7
self.check_events(func, recorders = JUMP_AND_BRANCH_RECORDERS, expected = [
('branch', 'func', 2, 2),
- ('branch', 'func', 3, 4),
+ ('branch', 'func', 3, 6),
('jump', 'func', 6, 2),
('branch', 'func', 2, 2),
- ('branch', 'func', 3, 3),
+ ('branch', 'func', 3, 4),
('jump', 'func', 4, 2),
- ('branch', 'func', 2, 2)])
+ ('branch', 'func', 2, 7)])
self.check_events(func, recorders = JUMP_BRANCH_AND_LINE_RECORDERS, expected = [
('line', 'get_events', 10),
@@ -1394,17 +1395,18 @@ def func():
('line', 'func', 2),
('branch', 'func', 2, 2),
('line', 'func', 3),
- ('branch', 'func', 3, 4),
+ ('branch', 'func', 3, 6),
('line', 'func', 6),
('jump', 'func', 6, 2),
('line', 'func', 2),
('branch', 'func', 2, 2),
('line', 'func', 3),
- ('branch', 'func', 3, 3),
+ ('branch', 'func', 3, 4),
('line', 'func', 4),
('jump', 'func', 4, 2),
('line', 'func', 2),
- ('branch', 'func', 2, 2),
+ ('branch', 'func', 2, 7),
+ ('line', 'func', 7),
('line', 'get_events', 11)])
def test_except_star(self):
@@ -1434,7 +1436,7 @@ def func():
('line', 'meth', 1),
('jump', 'func', 5, 5),
('jump', 'func', 5, '[offset=114]'),
- ('branch', 'func', '[offset=120]', '[offset=122]'),
+ ('branch', 'func', '[offset=120]', '[offset=124]'),
('line', 'get_events', 11)])
self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [
@@ -1450,7 +1452,7 @@ def func():
('return', None),
('jump', 'func', 5, 5),
('jump', 'func', 5, '[offset=114]'),
- ('branch', 'func', '[offset=120]', '[offset=122]'),
+ ('branch', 'func', '[offset=120]', '[offset=124]'),
('return', None),
('line', 'get_events', 11)])
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 5b1d70b303060..d33ee3265d254 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -80,6 +80,7 @@ dummy_func(
pop_1_error:
// Dummy locals.
PyObject *dummy;
+ _Py_CODEUNIT *this_instr;
PyObject *attr;
PyObject *attrs;
PyObject *bottom;
@@ -144,13 +145,13 @@ dummy_func(
if (code_version != global_version) {
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
ERROR_IF(err, error);
- next_instr--;
+ next_instr = this_instr;
}
else {
if (oparg < RESUME_AFTER_YIELD_FROM) {
CHECK_EVAL_BREAKER();
}
- next_instr[-1].op.code = RESUME_CHECK;
+ this_instr->op.code = RESUME_CHECK;
}
}
@@ -172,7 +173,7 @@ dummy_func(
if (_Py_Instrument(_PyFrame_GetCode(frame), tstate->interp)) {
goto error;
}
- next_instr--;
+ next_instr = this_instr;
}
else {
if (oparg < 2) {
@@ -180,12 +181,12 @@ dummy_func(
}
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_call_instrumentation(
- tstate, oparg > 0, frame, next_instr-1);
+ tstate, oparg > 0, frame, this_instr);
stack_pointer = _PyFrame_GetStackPointer(frame);
ERROR_IF(err, error);
- if (frame->instr_ptr != next_instr-1) {
+ if (frame->instr_ptr != this_instr) {
/* Instrumentation has jumped */
- next_instr = frame->instr_ptr;
+ next_instr = this_instr;
DISPATCH();
}
}
@@ -261,11 +262,12 @@ dummy_func(
macro(END_FOR) = POP_TOP + POP_TOP;
inst(INSTRUMENTED_END_FOR, (receiver, value --)) {
+ TIER_ONE_ONLY
/* Need to create a fake StopIteration error here,
* to conform to PEP 380 */
if (PyGen_Check(receiver)) {
PyErr_SetObject(PyExc_StopIteration, value);
- if (monitor_stop_iteration(tstate, frame, next_instr-1)) {
+ if (monitor_stop_iteration(tstate, frame, this_instr)) {
goto error;
}
PyErr_SetRaisedException(NULL);
@@ -278,9 +280,10 @@ dummy_func(
}
inst(INSTRUMENTED_END_SEND, (receiver, value -- value)) {
+ TIER_ONE_ONLY
if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) {
PyErr_SetObject(PyExc_StopIteration, value);
- if (monitor_stop_iteration(tstate, frame, next_instr-1)) {
+ if (monitor_stop_iteration(tstate, frame, this_instr)) {
goto error;
}
PyErr_SetRaisedException(NULL);
@@ -310,14 +313,13 @@ dummy_func(
inst(TO_BOOL, (unused/1, unused/2, value -- res)) {
#if ENABLE_SPECIALIZATION
- _PyToBoolCache *cache = (_PyToBoolCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_ToBool(value, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(TO_BOOL, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
int err = PyObject_IsTrue(value);
DECREF_INPUTS();
@@ -491,10 +493,9 @@ dummy_func(
// So the inputs are the same as for all BINARY_OP
// specializations, but there is no output.
// At the end we just skip over the STORE_FAST.
- op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) {
- _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP];
- assert(true_next.op.code == STORE_FAST);
- PyObject **target_local = &GETLOCAL(true_next.op.arg);
+ op(_BINARY_OP_INPLACE_ADD_UNICODE, (unused/1, left, right --)) {
+ assert(next_instr->op.code == STORE_FAST);
+ PyObject **target_local = &GETLOCAL(next_instr->op.arg);
DEOPT_IF(*target_local != left);
STAT_INC(BINARY_OP, hit);
/* Handle `left = left + right` or `left += right` for str.
@@ -514,7 +515,8 @@ dummy_func(
_Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc);
ERROR_IF(*target_local == NULL, error);
// The STORE_FAST is already done.
- SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_OP + 1);
+ assert(next_instr->op.code == STORE_FAST);
+ SKIP_OVER(1);
}
macro(BINARY_OP_INPLACE_ADD_UNICODE) =
@@ -530,14 +532,13 @@ dummy_func(
inst(BINARY_SUBSCR, (unused/1, container, sub -- res)) {
#if ENABLE_SPECIALIZATION
- _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_BinarySubscr(container, sub, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(BINARY_SUBSCR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
res = PyObject_GetItem(container, sub);
DECREF_INPUTS();
@@ -656,8 +657,7 @@ dummy_func(
STACK_SHRINK(2);
new_frame->localsplus[0] = container;
new_frame->localsplus[1] = sub;
- SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
- assert(1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR;
DISPATCH_INLINED(new_frame);
}
@@ -679,14 +679,13 @@ dummy_func(
inst(STORE_SUBSCR, (unused/1, v, container, sub -- )) {
#if ENABLE_SPECIALIZATION
- _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_StoreSubscr(container, sub, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(STORE_SUBSCR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
/* container[sub] = v */
int err = PyObject_SetItem(container, sub, v);
@@ -754,7 +753,7 @@ dummy_func(
case 0:
if (do_raise(tstate, exc, cause)) {
assert(oparg == 0);
- monitor_reraise(tstate, frame, next_instr-1);
+ monitor_reraise(tstate, frame, this_instr);
goto exception_unwind;
}
break;
@@ -808,7 +807,7 @@ dummy_func(
inst(INSTRUMENTED_RETURN_VALUE, (retval --)) {
int err = _Py_call_instrumentation_arg(
tstate, PY_MONITORING_EVENT_PY_RETURN,
- frame, next_instr-1, retval);
+ frame, this_instr, retval);
if (err) goto error;
STACK_SHRINK(1);
assert(EMPTY());
@@ -832,7 +831,7 @@ dummy_func(
PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg);
int err = _Py_call_instrumentation_arg(
tstate, PY_MONITORING_EVENT_PY_RETURN,
- frame, next_instr-1, retval);
+ frame, this_instr, retval);
if (err) goto error;
Py_INCREF(retval);
assert(EMPTY());
@@ -958,14 +957,13 @@ dummy_func(
inst(SEND, (unused/1, receiver, v -- receiver, retval)) {
#if ENABLE_SPECIALIZATION
- _PySendCache *cache = (_PySendCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_Send(receiver, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(SEND, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
assert(frame != &entry_frame);
if ((tstate->interp->eval_frame == NULL) &&
@@ -979,8 +977,7 @@ dummy_func(
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
- SKIP_OVER(INLINE_CACHE_ENTRIES_SEND);
- assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - this_instr);
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_SEND + oparg);
DISPATCH_INLINED(gen_frame);
}
@@ -993,7 +990,7 @@ dummy_func(
if (retval == NULL) {
if (_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)
) {
- monitor_raise(tstate, frame, next_instr-1);
+ monitor_raise(tstate, frame, this_instr);
}
if (_PyGen_FetchStopIterationValue(&retval) == 0) {
assert(retval != NULL);
@@ -1018,8 +1015,7 @@ dummy_func(
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
- SKIP_OVER(INLINE_CACHE_ENTRIES_SEND);
- assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - this_instr);
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_SEND + oparg);
DISPATCH_INLINED(gen_frame);
}
@@ -1033,7 +1029,7 @@ dummy_func(
_PyFrame_SetStackPointer(frame, stack_pointer - 1);
int err = _Py_call_instrumentation_arg(
tstate, PY_MONITORING_EVENT_PY_YIELD,
- frame, next_instr-1, retval);
+ frame, this_instr, retval);
if (err) goto error;
tstate->exc_info = gen->gi_exc_state.previous_item;
gen->gi_exc_state.previous_item = NULL;
@@ -1093,7 +1089,7 @@ dummy_func(
assert(exc && PyExceptionInstance_Check(exc));
Py_INCREF(exc);
_PyErr_SetRaisedException(tstate, exc);
- monitor_reraise(tstate, frame, next_instr-1);
+ monitor_reraise(tstate, frame, this_instr);
goto exception_unwind;
}
@@ -1105,7 +1101,7 @@ dummy_func(
else {
Py_INCREF(exc);
_PyErr_SetRaisedException(tstate, exc);
- monitor_reraise(tstate, frame, next_instr-1);
+ monitor_reraise(tstate, frame, this_instr);
goto exception_unwind;
}
}
@@ -1120,7 +1116,7 @@ dummy_func(
}
else {
_PyErr_SetRaisedException(tstate, Py_NewRef(exc_value));
- monitor_reraise(tstate, frame, next_instr-1);
+ monitor_reraise(tstate, frame, this_instr);
goto exception_unwind;
}
}
@@ -1184,14 +1180,13 @@ dummy_func(
inst(UNPACK_SEQUENCE, (unused/1, seq -- unused[oparg])) {
#if ENABLE_SPECIALIZATION
- _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_UnpackSequence(seq, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
STAT_INC(UNPACK_SEQUENCE, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject **top = stack_pointer + oparg - 1;
int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top);
@@ -1247,15 +1242,14 @@ dummy_func(
inst(STORE_ATTR, (unused/1, unused/3, v, owner --)) {
#if ENABLE_SPECIALIZATION
- _PyAttrCache *cache = (_PyAttrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
- next_instr--;
+ next_instr = this_instr;
_Py_Specialize_StoreAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG();
}
STAT_INC(STORE_ATTR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyObject_SetAttr(owner, name, v);
@@ -1369,15 +1363,14 @@ dummy_func(
inst(LOAD_GLOBAL, (unused/1, unused/1, unused/1, unused/1 -- res, null if (oparg & 1))) {
#if ENABLE_SPECIALIZATION
- _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- next_instr--;
+ next_instr = this_instr;
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
DISPATCH_SAME_OPARG();
}
STAT_INC(LOAD_GLOBAL, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
if (PyDict_CheckExact(GLOBALS())
@@ -1692,11 +1685,10 @@ dummy_func(
ERROR_IF(_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0, error);
}
- inst(INSTRUMENTED_LOAD_SUPER_ATTR, (unused/9, unused, unused, unused -- unused, unused if (oparg & 1))) {
- _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr;
+ inst(INSTRUMENTED_LOAD_SUPER_ATTR, (unused/1, unused, unused, unused -- unused, unused if (oparg & 1))) {
// cancel out the decrement that will happen in LOAD_SUPER_ATTR; we
// don't want to specialize instrumented instructions
- INCREMENT_ADAPTIVE_COUNTER(cache->counter);
+ INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
}
@@ -1706,24 +1698,24 @@ dummy_func(
};
inst(LOAD_SUPER_ATTR, (unused/1, global_super, class, self -- attr, null if (oparg & 1))) {
+ TIER_ONE_ONLY
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
- int load_method = oparg & 1;
#if ENABLE_SPECIALIZATION
- _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ int load_method = oparg & 1;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_LoadSuperAttr(global_super, class, next_instr, load_method);
DISPATCH_SAME_OPARG();
}
STAT_INC(LOAD_SUPER_ATTR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
- frame, next_instr-1, global_super, arg);
+ frame, this_instr, global_super, arg);
ERROR_IF(err, error);
}
@@ -1736,12 +1728,12 @@ dummy_func(
if (super == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, next_instr-1, global_super, arg);
+ frame, this_instr, global_super, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, next_instr-1, global_super, arg);
+ frame, this_instr, global_super, arg);
if (err < 0) {
Py_CLEAR(super);
}
@@ -1819,15 +1811,14 @@ dummy_func(
inst(LOAD_ATTR, (unused/9, owner -- attr, self_or_null if (oparg & 1))) {
#if ENABLE_SPECIALIZATION
- _PyAttrCache *cache = (_PyAttrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- next_instr--;
+ next_instr = this_instr;
_Py_Specialize_LoadAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG();
}
STAT_INC(LOAD_ATTR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
if (oparg & 1) {
@@ -2018,8 +2009,7 @@ dummy_func(
// Manipulate stack directly because we exit with DISPATCH_INLINED().
STACK_SHRINK(1);
new_frame->localsplus[0] = owner;
- SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR);
- assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_LOAD_ATTR;
DISPATCH_INLINED(new_frame);
}
@@ -2046,8 +2036,7 @@ dummy_func(
STACK_SHRINK(1);
new_frame->localsplus[0] = owner;
new_frame->localsplus[1] = Py_NewRef(name);
- SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR);
- assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_LOAD_ATTR;
DISPATCH_INLINED(new_frame);
}
@@ -2142,14 +2131,13 @@ dummy_func(
inst(COMPARE_OP, (unused/1, left, right -- res)) {
#if ENABLE_SPECIALIZATION
- _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_CompareOp(left, right, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
STAT_INC(COMPARE_OP, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
assert((oparg >> 5) <= Py_GE);
res = PyObject_RichCompare(left, right, oparg >> 5);
@@ -2277,24 +2265,23 @@ dummy_func(
inst(JUMP_BACKWARD, (--)) {
CHECK_EVAL_BREAKER();
- _Py_CODEUNIT *here = next_instr - 1;
assert(oparg <= INSTR_OFFSET());
JUMPBY(1-oparg);
#if ENABLE_SPECIALIZATION
- here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
- if (here[1].cache > tstate->interp->optimizer_backedge_threshold &&
+ this_instr[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
+ if (this_instr[1].cache > tstate->interp->optimizer_backedge_threshold &&
// Double-check that the opcode isn't instrumented or something:
- here->op.code == JUMP_BACKWARD)
+ this_instr->op.code == JUMP_BACKWARD)
{
OPT_STAT_INC(attempts);
- int optimized = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
+ int optimized = _PyOptimizer_BackEdge(frame, this_instr, next_instr, stack_pointer);
ERROR_IF(optimized < 0, error);
if (optimized) {
// Rewind and enter the executor:
- assert(here->op.code == ENTER_EXECUTOR);
- next_instr = here;
+ assert(this_instr->op.code == ENTER_EXECUTOR);
+ next_instr = this_instr;
}
- here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1);
+ this_instr[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1);
}
#endif /* ENABLE_SPECIALIZATION */
}
@@ -2331,7 +2318,7 @@ dummy_func(
assert(PyBool_Check(cond));
int flag = Py_IsFalse(cond);
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
JUMPBY(oparg * flag);
}
@@ -2340,7 +2327,7 @@ dummy_func(
assert(PyBool_Check(cond));
int flag = Py_IsTrue(cond);
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
JUMPBY(oparg * flag);
}
@@ -2456,14 +2443,13 @@ dummy_func(
inst(FOR_ITER, (unused/1, iter -- iter, next)) {
#if ENABLE_SPECIALIZATION
- _PyForIterCache *cache = (_PyForIterCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_ForIter(iter, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
STAT_INC(FOR_ITER, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
/* before: [iter]; after: [iter, iter()] *or* [] (and jump over END_FOR.) */
next = (*Py_TYPE(iter)->tp_iternext)(iter);
@@ -2472,15 +2458,14 @@ dummy_func(
if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) {
goto error;
}
- monitor_raise(tstate, frame, next_instr-1);
+ monitor_raise(tstate, frame, this_instr);
_PyErr_Clear(tstate);
}
/* iterator ended normally */
- assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR ||
- next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR);
+ assert(next_instr[oparg].op.code == END_FOR ||
+ next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
Py_DECREF(iter);
STACK_SHRINK(1);
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
/* Jump forward oparg, then skip following END_FOR instruction */
JUMPBY(oparg + 1);
DISPATCH();
@@ -2488,32 +2473,31 @@ dummy_func(
// Common case: no jump, leave it to the code generator
}
- inst(INSTRUMENTED_FOR_ITER, ( -- )) {
- _Py_CODEUNIT *here = frame->instr_ptr;
+ inst(INSTRUMENTED_FOR_ITER, (unused/1 -- )) {
_Py_CODEUNIT *target;
PyObject *iter = TOP();
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
if (next != NULL) {
PUSH(next);
- target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER;
+ target = next_instr;
}
else {
if (_PyErr_Occurred(tstate)) {
if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) {
goto error;
}
- monitor_raise(tstate, frame, here);
+ monitor_raise(tstate, frame, this_instr);
_PyErr_Clear(tstate);
}
/* iterator ended normally */
- assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR ||
- next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR);
+ assert(next_instr[oparg].op.code == END_FOR ||
+ next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
STACK_SHRINK(1);
Py_DECREF(iter);
/* Skip END_FOR */
- target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1;
+ target = next_instr + oparg + 1;
}
- INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH);
+ INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH);
}
op(_ITER_CHECK_LIST, (iter -- iter)) {
@@ -2532,7 +2516,6 @@ dummy_func(
}
Py_DECREF(iter);
STACK_SHRINK(1);
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
/* Jump forward oparg, then skip following END_FOR instruction */
JUMPBY(oparg + 1);
DISPATCH();
@@ -2588,7 +2571,6 @@ dummy_func(
}
Py_DECREF(iter);
STACK_SHRINK(1);
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
/* Jump forward oparg, then skip following END_FOR instruction */
JUMPBY(oparg + 1);
DISPATCH();
@@ -2640,7 +2622,6 @@ dummy_func(
if (r->len <= 0) {
STACK_SHRINK(1);
Py_DECREF(r);
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
// Jump over END_FOR instruction.
JUMPBY(oparg + 1);
DISPATCH();
@@ -2682,10 +2663,9 @@ dummy_func(
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
assert(next_instr[oparg].op.code == END_FOR ||
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
- assert(1 + INLINE_CACHE_ENTRIES_FOR_ITER == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_FOR_ITER == next_instr - this_instr);
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
DISPATCH_INLINED(gen_frame);
}
@@ -2912,7 +2892,7 @@ dummy_func(
unused/2 +
_LOAD_ATTR_METHOD_LAZY_DICT;
- inst(INSTRUMENTED_CALL, ( -- )) {
+ inst(INSTRUMENTED_CALL, (unused/3 -- )) {
int is_meth = PEEK(oparg + 1) != NULL;
int total_args = oparg + is_meth;
PyObject *function = PEEK(oparg + 2);
@@ -2920,10 +2900,9 @@ dummy_func(
&_PyInstrumentation_MISSING : PEEK(total_args);
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
- frame, next_instr-1, function, arg);
+ frame, this_instr, function, arg);
ERROR_IF(err, error);
- _PyCallCache *cache = (_PyCallCache *)next_instr;
- INCREMENT_ADAPTIVE_COUNTER(cache->counter);
+ INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
GO_TO_INSTRUCTION(CALL);
}
@@ -2959,14 +2938,13 @@ dummy_func(
total_args++;
}
#if ENABLE_SPECIALIZATION
- _PyCallCache *cache = (_PyCallCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_Call(callable, next_instr, total_args);
DISPATCH_SAME_OPARG();
}
STAT_INC(CALL, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
if (self_or_null == NULL && Py_TYPE(callable) == &PyMethod_Type) {
args--;
@@ -2996,8 +2974,7 @@ dummy_func(
if (new_frame == NULL) {
goto error;
}
- SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
- assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
DISPATCH_INLINED(new_frame);
}
@@ -3012,12 +2989,12 @@ dummy_func(
if (res == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, next_instr-1, callable, arg);
+ frame, this_instr, callable, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, next_instr-1, callable, arg);
+ frame, this_instr, callable, arg);
if (err < 0) {
Py_CLEAR(res);
}
@@ -3151,8 +3128,7 @@ dummy_func(
}
// Manipulate stack and cache directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 2);
- SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
- assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
DISPATCH_INLINED(new_frame);
}
@@ -3200,7 +3176,7 @@ dummy_func(
* 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``)
* 3. Pushes the frame for ``__init__`` to the frame stack
* */
- _PyCallCache *cache = (_PyCallCache *)next_instr;
+ _PyCallCache *cache = (_PyCallCache *)&this_instr[1];
DEOPT_IF(null != NULL);
DEOPT_IF(!PyType_Check(callable));
PyTypeObject *tp = (PyTypeObject *)callable;
@@ -3229,8 +3205,7 @@ dummy_func(
for (int i = 0; i < oparg; i++) {
init_frame->localsplus[i+1] = args[i];
}
- SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
- assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
STACK_SHRINK(oparg+2);
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -3426,9 +3401,9 @@ dummy_func(
Py_DECREF(self);
Py_DECREF(callable);
STACK_SHRINK(3);
- // CALL + POP_TOP
- SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1);
- assert(next_instr[-1].op.code == POP_TOP);
+ // Skip POP_TOP
+ assert(next_instr->op.code == POP_TOP);
+ SKIP_OVER(1);
DISPATCH();
}
@@ -3558,7 +3533,7 @@ dummy_func(
: PEEK(total_args + 1);
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
- frame, next_instr - 1, function, arg);
+ frame, this_instr, function, arg);
ERROR_IF(err, error);
GO_TO_INSTRUCTION(CALL_KW);
}
@@ -3600,7 +3575,7 @@ dummy_func(
if (new_frame == NULL) {
goto error;
}
- assert(next_instr - frame->instr_ptr == 1);
+ assert(next_instr - this_instr == 1);
frame->return_offset = 1;
DISPATCH_INLINED(new_frame);
}
@@ -3615,12 +3590,12 @@ dummy_func(
if (res == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, next_instr-1, callable, arg);
+ frame, this_instr, callable, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, next_instr-1, callable, arg);
+ frame, this_instr, callable, arg);
if (err < 0) {
Py_CLEAR(res);
}
@@ -3663,18 +3638,18 @@ dummy_func(
PyTuple_GET_ITEM(callargs, 0) : Py_None;
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
- frame, next_instr-1, func, arg);
+ frame, this_instr, func, arg);
if (err) goto error;
result = PyObject_Call(func, callargs, kwargs);
if (result == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, next_instr-1, func, arg);
+ frame, this_instr, func, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, next_instr-1, func, arg);
+ frame, this_instr, func, arg);
if (err < 0) {
Py_CLEAR(result);
}
@@ -3697,7 +3672,7 @@ dummy_func(
if (new_frame == NULL) {
goto error;
}
- assert(next_instr - frame->instr_ptr == 1);
+ assert(next_instr - this_instr == 1);
frame->return_offset = 1;
DISPATCH_INLINED(new_frame);
}
@@ -3818,14 +3793,13 @@ 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)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, LOCALS_ARRAY);
DISPATCH_SAME_OPARG();
}
STAT_INC(BINARY_OP, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
assert(NB_ADD <= oparg);
assert(oparg <= NB_INPLACE_XOR);
@@ -3842,12 +3816,11 @@ dummy_func(
inst(INSTRUMENTED_INSTRUCTION, ( -- )) {
int next_opcode = _Py_call_instrumentation_instruction(
- tstate, frame, next_instr-1);
+ tstate, frame, this_instr);
ERROR_IF(next_opcode < 0, error);
- next_instr--;
+ next_instr = this_instr;
if (_PyOpcode_Caches[next_opcode]) {
- _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1);
- INCREMENT_ADAPTIVE_COUNTER(cache->counter);
+ INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
}
assert(next_opcode > 0 && next_opcode < 256);
opcode = next_opcode;
@@ -3855,43 +3828,38 @@ dummy_func(
}
inst(INSTRUMENTED_JUMP_FORWARD, ( -- )) {
- _Py_CODEUNIT *here = frame->instr_ptr;
- INSTRUMENTED_JUMP(here, next_instr + oparg, PY_MONITORING_EVENT_JUMP);
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_JUMP);
}
inst(INSTRUMENTED_JUMP_BACKWARD, ( -- )) {
- _Py_CODEUNIT *here = frame->instr_ptr;
CHECK_EVAL_BREAKER();
- INSTRUMENTED_JUMP(here, next_instr + 1 - oparg, PY_MONITORING_EVENT_JUMP);
+ INSTRUMENTED_JUMP(this_instr, next_instr + 1 - oparg, PY_MONITORING_EVENT_JUMP);
}
inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
PyObject *cond = POP();
assert(PyBool_Check(cond));
- _Py_CODEUNIT *here = frame->instr_ptr;
int flag = Py_IsTrue(cond);
int offset = flag * oparg;
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
- INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1 -- )) {
PyObject *cond = POP();
assert(PyBool_Check(cond));
- _Py_CODEUNIT *here = frame->instr_ptr;
int flag = Py_IsFalse(cond);
int offset = flag * oparg;
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
- INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
inst(INSTRUMENTED_POP_JUMP_IF_NONE, (unused/1 -- )) {
PyObject *value = POP();
- _Py_CODEUNIT *here = frame->instr_ptr;
int flag = Py_IsNone(value);
int offset;
if (flag) {
@@ -3902,14 +3870,13 @@ dummy_func(
offset = 0;
}
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
- INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, (unused/1 -- )) {
PyObject *value = POP();
- _Py_CODEUNIT *here = frame->instr_ptr;
int offset;
int nflag = Py_IsNone(value);
if (nflag) {
@@ -3920,9 +3887,9 @@ dummy_func(
offset = oparg;
}
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | !nflag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | !nflag;
#endif
- INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
inst(EXTENDED_ARG, ( -- )) {
@@ -3969,7 +3936,7 @@ dummy_func(
op(_SAVE_RETURN_OFFSET, (--)) {
#if TIER_ONE
- frame->return_offset = (uint16_t)(next_instr - frame->instr_ptr);
+ frame->return_offset = (uint16_t)(next_instr - this_instr);
#endif
#if TIER_TWO
frame->return_offset = oparg;
diff --git a/Python/ceval.c b/Python/ceval.c
index 6f8584c15b7bd..bada365011226 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -867,7 +867,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
monitor_raise(tstate, frame, next_instr-1);
exception_unwind:
{
- /* We can't use frame->f_lasti here, as RERAISE may have set it */
+ /* We can't use frame->instr_ptr here, as RERAISE may have set it */
int offset = INSTR_OFFSET()-1;
int level, handler, lasti;
if (get_exception_handler(_PyFrame_GetCode(frame), offset, &level, &handler, &lasti) == 0) {
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index 544e8ef8fa8c0..b11240b1faed4 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -60,25 +60,21 @@
#endif
#ifdef Py_STATS
-#define INSTRUCTION_START(op) \
+#define INSTRUCTION_STATS(op) \
do { \
- frame->instr_ptr = next_instr++; \
OPCODE_EXE_INC(op); \
if (_Py_stats) _Py_stats->opcode_stats[lastopcode].pair_count[op]++; \
lastopcode = op; \
} while (0)
#else
-#define INSTRUCTION_START(op) \
- do { \
- frame->instr_ptr = next_instr++; \
- } while(0)
+#define INSTRUCTION_STATS(op) ((void)0)
#endif
#if USE_COMPUTED_GOTOS
-# define TARGET(op) TARGET_##op: INSTRUCTION_START(op);
+# define TARGET(op) TARGET_##op:
# define DISPATCH_GOTO() goto *opcode_targets[opcode]
#else
-# define TARGET(op) case op: TARGET_##op: INSTRUCTION_START(op);
+# define TARGET(op) case op: TARGET_##op:
# define DISPATCH_GOTO() goto dispatch_opcode
#endif
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 9f37cd75b47ef..24de9eadf5904 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -119,14 +119,13 @@
PyObject *res;
value = stack_pointer[-1];
#if ENABLE_SPECIALIZATION
- _PyToBoolCache *cache = (_PyToBoolCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_ToBool(value, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(TO_BOOL, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
int err = PyObject_IsTrue(value);
Py_DECREF(value);
@@ -380,14 +379,13 @@
sub = stack_pointer[-1];
container = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
- _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_BinarySubscr(container, sub, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(BINARY_SUBSCR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
res = PyObject_GetItem(container, sub);
Py_DECREF(container);
@@ -574,14 +572,13 @@
container = stack_pointer[-2];
v = stack_pointer[-3];
#if ENABLE_SPECIALIZATION
- _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_StoreSubscr(container, sub, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(STORE_SUBSCR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
/* container[sub] = v */
int err = PyObject_SetItem(container, sub, v);
@@ -900,14 +897,13 @@
PyObject *seq;
seq = stack_pointer[-1];
#if ENABLE_SPECIALIZATION
- _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_UnpackSequence(seq, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
STAT_INC(UNPACK_SEQUENCE, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject **top = stack_pointer + oparg - 1;
int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top);
@@ -989,15 +985,14 @@
owner = stack_pointer[-1];
v = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
- _PyAttrCache *cache = (_PyAttrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
- next_instr--;
+ next_instr = this_instr;
_Py_Specialize_StoreAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG();
}
STAT_INC(STORE_ATTR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyObject_SetAttr(owner, name, v);
@@ -1133,15 +1128,14 @@
PyObject *res;
PyObject *null = NULL;
#if ENABLE_SPECIALIZATION
- _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- next_instr--;
+ next_instr = this_instr;
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
DISPATCH_SAME_OPARG();
}
STAT_INC(LOAD_GLOBAL, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
if (PyDict_CheckExact(GLOBALS())
@@ -1624,15 +1618,14 @@
PyObject *self_or_null = NULL;
owner = stack_pointer[-1];
#if ENABLE_SPECIALIZATION
- _PyAttrCache *cache = (_PyAttrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- next_instr--;
+ next_instr = this_instr;
_Py_Specialize_LoadAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG();
}
STAT_INC(LOAD_ATTR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
if (oparg & 1) {
@@ -1887,14 +1880,13 @@
right = stack_pointer[-1];
left = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
- _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_CompareOp(left, right, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
STAT_INC(COMPARE_OP, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
assert((oparg >> 5) <= Py_GE);
res = PyObject_RichCompare(left, right, oparg >> 5);
@@ -3209,14 +3201,13 @@
rhs = stack_pointer[-1];
lhs = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
- _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, LOCALS_ARRAY);
DISPATCH_SAME_OPARG();
}
STAT_INC(BINARY_OP, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
assert(NB_ADD <= oparg);
assert(oparg <= NB_INPLACE_XOR);
@@ -3275,7 +3266,7 @@
case _SAVE_RETURN_OFFSET: {
#if TIER_ONE
- frame->return_offset = (uint16_t)(next_instr - frame->instr_ptr);
+ frame->return_offset = (uint16_t)(next_instr - this_instr);
#endif
#if TIER_TWO
frame->return_offset = oparg;
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index fb4506e68765e..40c8cd8798c93 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -4,11 +4,18 @@
// Do not edit!
TARGET(NOP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(NOP);
DISPATCH();
}
TARGET(RESUME) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(RESUME);
PREDICTED(RESUME);
+ _Py_CODEUNIT *this_instr = next_instr - 1;
static_assert(0 == 0, "incorrect cache size");
TIER_ONE_ONLY
assert(frame == tstate->current_frame);
@@ -20,18 +27,21 @@
if (code_version != global_version) {
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
if (err) goto error;
- next_instr--;
+ next_instr = this_instr;
}
else {
if (oparg < RESUME_AFTER_YIELD_FROM) {
CHECK_EVAL_BREAKER();
}
- next_instr[-1].op.code = RESUME_CHECK;
+ this_instr->op.code = RESUME_CHECK;
}
DISPATCH();
}
TARGET(RESUME_CHECK) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(RESUME_CHECK);
#if defined(__EMSCRIPTEN__)
DEOPT_IF(_Py_emscripten_signal_clock == 0, RESUME);
_Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING;
@@ -44,13 +54,16 @@
}
TARGET(INSTRUMENTED_RESUME) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_RESUME);
uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker) & ~_PY_EVAL_EVENTS_MASK;
uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version;
if (code_version != global_version) {
if (_Py_Instrument(_PyFrame_GetCode(frame), tstate->interp)) {
goto error;
}
- next_instr--;
+ next_instr = this_instr;
}
else {
if (oparg < 2) {
@@ -58,12 +71,12 @@
}
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_call_instrumentation(
- tstate, oparg > 0, frame, next_instr-1);
+ tstate, oparg > 0, frame, this_instr);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err) goto error;
- if (frame->instr_ptr != next_instr-1) {
+ if (frame->instr_ptr != this_instr) {
/* Instrumentation has jumped */
- next_instr = frame->instr_ptr;
+ next_instr = this_instr;
DISPATCH();
}
}
@@ -71,6 +84,9 @@
}
TARGET(LOAD_FAST_CHECK) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_FAST_CHECK);
PyObject *value;
value = GETLOCAL(oparg);
if (value == NULL) goto unbound_local_error;
@@ -81,6 +97,9 @@
}
TARGET(LOAD_FAST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_FAST);
PyObject *value;
value = GETLOCAL(oparg);
assert(value != NULL);
@@ -91,6 +110,9 @@
}
TARGET(LOAD_FAST_AND_CLEAR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_FAST_AND_CLEAR);
PyObject *value;
value = GETLOCAL(oparg);
// do not use SETLOCAL here, it decrefs the old value
@@ -101,6 +123,9 @@
}
TARGET(LOAD_FAST_LOAD_FAST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_FAST_LOAD_FAST);
PyObject *value1;
PyObject *value2;
uint32_t oparg1 = oparg >> 4;
@@ -116,6 +141,9 @@
}
TARGET(LOAD_CONST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_CONST);
PyObject *value;
value = GETITEM(FRAME_CO_CONSTS, oparg);
Py_INCREF(value);
@@ -125,6 +153,9 @@
}
TARGET(STORE_FAST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(STORE_FAST);
PyObject *value;
value = stack_pointer[-1];
SETLOCAL(oparg, value);
@@ -133,6 +164,9 @@
}
TARGET(STORE_FAST_LOAD_FAST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(STORE_FAST_LOAD_FAST);
PyObject *value1;
PyObject *value2;
value1 = stack_pointer[-1];
@@ -146,6 +180,9 @@
}
TARGET(STORE_FAST_STORE_FAST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(STORE_FAST_STORE_FAST);
PyObject *value1;
PyObject *value2;
value1 = stack_pointer[-1];
@@ -159,6 +196,9 @@
}
TARGET(POP_TOP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(POP_TOP);
PyObject *value;
value = stack_pointer[-1];
Py_DECREF(value);
@@ -167,6 +207,9 @@
}
TARGET(PUSH_NULL) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(PUSH_NULL);
PyObject *res;
res = NULL;
STACK_GROW(1);
@@ -175,6 +218,9 @@
}
TARGET(END_FOR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(END_FOR);
PyObject *value;
// POP_TOP
value = stack_pointer[-1];
@@ -191,15 +237,19 @@
}
TARGET(INSTRUMENTED_END_FOR) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_END_FOR);
PyObject *value;
PyObject *receiver;
value = stack_pointer[-1];
receiver = stack_pointer[-2];
+ TIER_ONE_ONLY
/* Need to create a fake StopIteration error here,
* to conform to PEP 380 */
if (PyGen_Check(receiver)) {
PyErr_SetObject(PyExc_StopIteration, value);
- if (monitor_stop_iteration(tstate, frame, next_instr-1)) {
+ if (monitor_stop_iteration(tstate, frame, this_instr)) {
goto error;
}
PyErr_SetRaisedException(NULL);
@@ -211,6 +261,9 @@
}
TARGET(END_SEND) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(END_SEND);
PyObject *value;
PyObject *receiver;
value = stack_pointer[-1];
@@ -222,13 +275,17 @@
}
TARGET(INSTRUMENTED_END_SEND) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_END_SEND);
PyObject *value;
PyObject *receiver;
value = stack_pointer[-1];
receiver = stack_pointer[-2];
+ TIER_ONE_ONLY
if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) {
PyErr_SetObject(PyExc_StopIteration, value);
- if (monitor_stop_iteration(tstate, frame, next_instr-1)) {
+ if (monitor_stop_iteration(tstate, frame, this_instr)) {
goto error;
}
PyErr_SetRaisedException(NULL);
@@ -240,6 +297,9 @@
}
TARGET(UNARY_NEGATIVE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(UNARY_NEGATIVE);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -251,6 +311,9 @@
}
TARGET(UNARY_NOT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(UNARY_NOT);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -261,40 +324,47 @@
}
TARGET(TO_BOOL) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(TO_BOOL);
PREDICTED(TO_BOOL);
+ _Py_CODEUNIT *this_instr = next_instr - 4;
static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size");
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
#if ENABLE_SPECIALIZATION
- _PyToBoolCache *cache = (_PyToBoolCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_ToBool(value, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(TO_BOOL, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
int err = PyObject_IsTrue(value);
Py_DECREF(value);
if (err < 0) goto pop_1_error;
res = err ? Py_True : Py_False;
stack_pointer[-1] = res;
- next_instr += 3;
DISPATCH();
}
TARGET(TO_BOOL_BOOL) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(TO_BOOL_BOOL);
PyObject *value;
value = stack_pointer[-1];
DEOPT_IF(!PyBool_Check(value), TO_BOOL);
STAT_INC(TO_BOOL, hit);
- next_instr += 3;
DISPATCH();
}
TARGET(TO_BOOL_INT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(TO_BOOL_INT);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -309,11 +379,13 @@
res = Py_True;
}
stack_pointer[-1] = res;
- next_instr += 3;
DISPATCH();
}
TARGET(TO_BOOL_LIST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(TO_BOOL_LIST);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -322,11 +394,13 @@
res = Py_SIZE(value) ? Py_True : Py_False;
Py_DECREF(value);
stack_pointer[-1] = res;
- next_instr += 3;
DISPATCH();
}
TARGET(TO_BOOL_NONE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(TO_BOOL_NONE);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -335,11 +409,13 @@
STAT_INC(TO_BOOL, hit);
res = Py_False;
stack_pointer[-1] = res;
- next_instr += 3;
DISPATCH();
}
TARGET(TO_BOOL_STR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(TO_BOOL_STR);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -355,15 +431,17 @@
res = Py_True;
}
stack_pointer[-1] = res;
- next_instr += 3;
DISPATCH();
}
TARGET(TO_BOOL_ALWAYS_TRUE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(TO_BOOL_ALWAYS_TRUE);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
- uint32_t version = read_u32(&next_instr[1].cache);
+ uint32_t version = read_u32(&this_instr[2].cache);
// This one is a bit weird, because we expect *some* failures:
assert(version);
DEOPT_IF(Py_TYPE(value)->tp_version_tag != version, TO_BOOL);
@@ -371,11 +449,13 @@
Py_DECREF(value);
res = Py_True;
stack_pointer[-1] = res;
- next_instr += 3;
DISPATCH();
}
TARGET(UNARY_INVERT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(UNARY_INVERT);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -387,6 +467,9 @@
}
TARGET(BINARY_OP_MULTIPLY_INT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_OP_MULTIPLY_INT);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -407,11 +490,13 @@
}
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_ADD_INT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_OP_ADD_INT);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -432,11 +517,13 @@
}
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_SUBTRACT_INT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_OP_SUBTRACT_INT);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -457,11 +544,13 @@
}
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_MULTIPLY_FLOAT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_OP_MULTIPLY_FLOAT);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -482,11 +571,13 @@
}
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_ADD_FLOAT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_OP_ADD_FLOAT);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -507,11 +598,13 @@
}
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_SUBTRACT_FLOAT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_OP_SUBTRACT_FLOAT);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -532,11 +625,13 @@
}
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_ADD_UNICODE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_OP_ADD_UNICODE);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -557,11 +652,13 @@
}
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_INPLACE_ADD_UNICODE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_OP_INPLACE_ADD_UNICODE);
PyObject *right;
PyObject *left;
// _GUARD_BOTH_UNICODE
@@ -573,9 +670,8 @@
}
// _BINARY_OP_INPLACE_ADD_UNICODE
{
- _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP];
- assert(true_next.op.code == STORE_FAST);
- PyObject **target_local = &GETLOCAL(true_next.op.arg);
+ assert(next_instr->op.code == STORE_FAST);
+ PyObject **target_local = &GETLOCAL(next_instr->op.arg);
DEOPT_IF(*target_local != left, BINARY_OP);
STAT_INC(BINARY_OP, hit);
/* Handle `left = left + right` or `left += right` for str.
@@ -595,14 +691,19 @@
_Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc);
if (*target_local == NULL) goto pop_2_error;
// The STORE_FAST is already done.
- SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_OP + 1);
+ assert(next_instr->op.code == STORE_FAST);
+ SKIP_OVER(1);
}
STACK_SHRINK(2);
DISPATCH();
}
TARGET(BINARY_SUBSCR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_SUBSCR);
PREDICTED(BINARY_SUBSCR);
+ _Py_CODEUNIT *this_instr = next_instr - 2;
static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size");
PyObject *sub;
PyObject *container;
@@ -610,14 +711,13 @@
sub = stack_pointer[-1];
container = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
- _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_BinarySubscr(container, sub, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(BINARY_SUBSCR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
res = PyObject_GetItem(container, sub);
Py_DECREF(container);
@@ -625,11 +725,13 @@
if (res == NULL) goto pop_2_error;
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_SLICE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BINARY_SLICE);
PyObject *stop;
PyObject *start;
PyObject *container;
@@ -655,6 +757,9 @@
}
TARGET(STORE_SLICE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(STORE_SLICE);
PyObject *stop;
PyObject *start;
PyObject *container;
@@ -680,6 +785,9 @@
}
TARGET(BINARY_SUBSCR_LIST_INT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_SUBSCR_LIST_INT);
PyObject *sub;
PyObject *list;
PyObject *res;
@@ -700,11 +808,13 @@
Py_DECREF(list);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_SUBSCR_STR_INT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_SUBSCR_STR_INT);
PyObject *sub;
PyObject *str;
PyObject *res;
@@ -724,11 +834,13 @@
Py_DECREF(str);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_SUBSCR_TUPLE_INT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_SUBSCR_TUPLE_INT);
PyObject *sub;
PyObject *tuple;
PyObject *res;
@@ -749,11 +861,13 @@
Py_DECREF(tuple);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_SUBSCR_DICT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_SUBSCR_DICT);
PyObject *sub;
PyObject *dict;
PyObject *res;
@@ -775,11 +889,13 @@
Py_DECREF(sub);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(BINARY_SUBSCR_GETITEM) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_SUBSCR_GETITEM);
PyObject *sub;
PyObject *container;
sub = stack_pointer[-1];
@@ -803,13 +919,15 @@
STACK_SHRINK(2);
new_frame->localsplus[0] = container;
new_frame->localsplus[1] = sub;
- SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
- assert(1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_BINARY_SUBSCR;
DISPATCH_INLINED(new_frame);
}
TARGET(LIST_APPEND) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LIST_APPEND);
PyObject *v;
PyObject *list;
v = stack_pointer[-1];
@@ -820,6 +938,9 @@
}
TARGET(SET_ADD) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(SET_ADD);
PyObject *v;
PyObject *set;
v = stack_pointer[-1];
@@ -832,7 +953,11 @@
}
TARGET(STORE_SUBSCR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(STORE_SUBSCR);
PREDICTED(STORE_SUBSCR);
+ _Py_CODEUNIT *this_instr = next_instr - 2;
static_assert(INLINE_CACHE_ENTRIES_STORE_SUBSCR == 1, "incorrect cache size");
PyObject *sub;
PyObject *container;
@@ -841,14 +966,13 @@
container = stack_pointer[-2];
v = stack_pointer[-3];
#if ENABLE_SPECIALIZATION
- _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_StoreSubscr(container, sub, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(STORE_SUBSCR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
/* container[sub] = v */
int err = PyObject_SetItem(container, sub, v);
@@ -857,11 +981,13 @@
Py_DECREF(sub);
if (err) goto pop_3_error;
STACK_SHRINK(3);
- next_instr += 1;
DISPATCH();
}
TARGET(STORE_SUBSCR_LIST_INT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(STORE_SUBSCR_LIST_INT);
PyObject *sub;
PyObject *list;
PyObject *value;
@@ -885,11 +1011,13 @@
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
Py_DECREF(list);
STACK_SHRINK(3);
- next_instr += 1;
DISPATCH();
}
TARGET(STORE_SUBSCR_DICT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(STORE_SUBSCR_DICT);
PyObject *sub;
PyObject *dict;
PyObject *value;
@@ -902,11 +1030,13 @@
Py_DECREF(dict);
if (err) goto pop_3_error;
STACK_SHRINK(3);
- next_instr += 1;
DISPATCH();
}
TARGET(DELETE_SUBSCR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(DELETE_SUBSCR);
PyObject *sub;
PyObject *container;
sub = stack_pointer[-1];
@@ -921,6 +1051,9 @@
}
TARGET(CALL_INTRINSIC_1) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CALL_INTRINSIC_1);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -933,6 +1066,9 @@
}
TARGET(CALL_INTRINSIC_2) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CALL_INTRINSIC_2);
PyObject *value1;
PyObject *value2;
PyObject *res;
@@ -949,6 +1085,9 @@
}
TARGET(RAISE_VARARGS) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(RAISE_VARARGS);
PyObject **args;
args = stack_pointer - oparg;
PyObject *cause = NULL, *exc = NULL;
@@ -962,7 +1101,7 @@
case 0:
if (do_raise(tstate, exc, cause)) {
assert(oparg == 0);
- monitor_reraise(tstate, frame, next_instr-1);
+ monitor_reraise(tstate, frame, this_instr);
goto exception_unwind;
}
break;
@@ -975,6 +1114,9 @@
}
TARGET(INTERPRETER_EXIT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INTERPRETER_EXIT);
PyObject *retval;
retval = stack_pointer[-1];
assert(frame == &entry_frame);
@@ -987,6 +1129,9 @@
}
TARGET(RETURN_VALUE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(RETURN_VALUE);
PyObject *retval;
retval = stack_pointer[-1];
STACK_SHRINK(1);
@@ -1013,11 +1158,14 @@
}
TARGET(INSTRUMENTED_RETURN_VALUE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE);
PyObject *retval;
retval = stack_pointer[-1];
int err = _Py_call_instrumentation_arg(
tstate, PY_MONITORING_EVENT_PY_RETURN,
- frame, next_instr-1, retval);
+ frame, this_instr, retval);
if (err) goto error;
STACK_SHRINK(1);
assert(EMPTY());
@@ -1034,6 +1182,9 @@
}
TARGET(RETURN_CONST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(RETURN_CONST);
PyObject *value;
PyObject *retval;
// LOAD_CONST
@@ -1068,10 +1219,13 @@
}
TARGET(INSTRUMENTED_RETURN_CONST) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_RETURN_CONST);
PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg);
int err = _Py_call_instrumentation_arg(
tstate, PY_MONITORING_EVENT_PY_RETURN,
- frame, next_instr-1, retval);
+ frame, this_instr, retval);
if (err) goto error;
Py_INCREF(retval);
assert(EMPTY());
@@ -1088,6 +1242,9 @@
}
TARGET(GET_AITER) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(GET_AITER);
PyObject *obj;
PyObject *iter;
obj = stack_pointer[-1];
@@ -1126,6 +1283,9 @@
}
TARGET(GET_ANEXT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(GET_ANEXT);
PyObject *aiter;
PyObject *awaitable;
aiter = stack_pointer[-1];
@@ -1177,6 +1337,9 @@
}
TARGET(GET_AWAITABLE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(GET_AWAITABLE);
PyObject *iterable;
PyObject *iter;
iterable = stack_pointer[-1];
@@ -1208,7 +1371,11 @@
}
TARGET(SEND) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(SEND);
PREDICTED(SEND);
+ _Py_CODEUNIT *this_instr = next_instr - 2;
static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size");
PyObject *v;
PyObject *receiver;
@@ -1216,14 +1383,13 @@
v = stack_pointer[-1];
receiver = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
- _PySendCache *cache = (_PySendCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_Send(receiver, next_instr);
DISPATCH_SAME_OPARG();
}
STAT_INC(SEND, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
assert(frame != &entry_frame);
if ((tstate->interp->eval_frame == NULL) &&
@@ -1237,8 +1403,7 @@
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
- SKIP_OVER(INLINE_CACHE_ENTRIES_SEND);
- assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - this_instr);
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_SEND + oparg);
DISPATCH_INLINED(gen_frame);
}
@@ -1251,7 +1416,7 @@
if (retval == NULL) {
if (_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)
) {
- monitor_raise(tstate, frame, next_instr-1);
+ monitor_raise(tstate, frame, this_instr);
}
if (_PyGen_FetchStopIterationValue(&retval) == 0) {
assert(retval != NULL);
@@ -1263,11 +1428,13 @@
}
Py_DECREF(v);
stack_pointer[-1] = retval;
- next_instr += 1;
DISPATCH();
}
TARGET(SEND_GEN) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(SEND_GEN);
PyObject *v;
PyObject *receiver;
v = stack_pointer[-1];
@@ -1283,13 +1450,15 @@
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
- SKIP_OVER(INLINE_CACHE_ENTRIES_SEND);
- assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_SEND == next_instr - this_instr);
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_SEND + oparg);
DISPATCH_INLINED(gen_frame);
}
TARGET(INSTRUMENTED_YIELD_VALUE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_YIELD_VALUE);
PyObject *retval;
retval = stack_pointer[-1];
assert(frame != &entry_frame);
@@ -1300,7 +1469,7 @@
_PyFrame_SetStackPointer(frame, stack_pointer - 1);
int err = _Py_call_instrumentation_arg(
tstate, PY_MONITORING_EVENT_PY_YIELD,
- frame, next_instr-1, retval);
+ frame, this_instr, retval);
if (err) goto error;
tstate->exc_info = gen->gi_exc_state.previous_item;
gen->gi_exc_state.previous_item = NULL;
@@ -1316,6 +1485,9 @@
}
TARGET(YIELD_VALUE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(YIELD_VALUE);
PyObject *retval;
retval = stack_pointer[-1];
// NOTE: It's important that YIELD_VALUE never raises an exception!
@@ -1341,6 +1513,9 @@
}
TARGET(POP_EXCEPT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(POP_EXCEPT);
PyObject *exc_value;
exc_value = stack_pointer[-1];
_PyErr_StackItem *exc_info = tstate->exc_info;
@@ -1350,6 +1525,9 @@
}
TARGET(RERAISE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(RERAISE);
PyObject *exc;
PyObject **values;
exc = stack_pointer[-1];
@@ -1370,11 +1548,14 @@
assert(exc && PyExceptionInstance_Check(exc));
Py_INCREF(exc);
_PyErr_SetRaisedException(tstate, exc);
- monitor_reraise(tstate, frame, next_instr-1);
+ monitor_reraise(tstate, frame, this_instr);
goto exception_unwind;
}
TARGET(END_ASYNC_FOR) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(END_ASYNC_FOR);
PyObject *exc;
PyObject *awaitable;
exc = stack_pointer[-1];
@@ -1387,7 +1568,7 @@
else {
Py_INCREF(exc);
_PyErr_SetRaisedException(tstate, exc);
- monitor_reraise(tstate, frame, next_instr-1);
+ monitor_reraise(tstate, frame, this_instr);
goto exception_unwind;
}
STACK_SHRINK(2);
@@ -1395,6 +1576,9 @@
}
TARGET(CLEANUP_THROW) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CLEANUP_THROW);
PyObject *exc_value;
PyObject *last_sent_val;
PyObject *sub_iter;
@@ -1414,7 +1598,7 @@
}
else {
_PyErr_SetRaisedException(tstate, Py_NewRef(exc_value));
- monitor_reraise(tstate, frame, next_instr-1);
+ monitor_reraise(tstate, frame, this_instr);
goto exception_unwind;
}
STACK_SHRINK(1);
@@ -1424,6 +1608,9 @@
}
TARGET(LOAD_ASSERTION_ERROR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_ASSERTION_ERROR);
PyObject *value;
value = Py_NewRef(PyExc_AssertionError);
STACK_GROW(1);
@@ -1432,6 +1619,9 @@
}
TARGET(LOAD_BUILD_CLASS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_BUILD_CLASS);
PyObject *bc;
if (PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc) < 0) goto error;
if (bc == NULL) {
@@ -1445,6 +1635,9 @@
}
TARGET(STORE_NAME) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(STORE_NAME);
PyObject *v;
v = stack_pointer[-1];
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
@@ -1467,6 +1660,9 @@
}
TARGET(DELETE_NAME) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(DELETE_NAME);
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
PyObject *ns = LOCALS();
int err;
@@ -1487,19 +1683,22 @@
}
TARGET(UNPACK_SEQUENCE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(UNPACK_SEQUENCE);
PREDICTED(UNPACK_SEQUENCE);
+ _Py_CODEUNIT *this_instr = next_instr - 2;
static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size");
PyObject *seq;
seq = stack_pointer[-1];
#if ENABLE_SPECIALIZATION
- _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_UnpackSequence(seq, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
STAT_INC(UNPACK_SEQUENCE, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject **top = stack_pointer + oparg - 1;
int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top);
@@ -1507,11 +1706,13 @@
if (res == 0) goto pop_1_error;
STACK_SHRINK(1);
STACK_GROW(oparg);
- next_instr += 1;
DISPATCH();
}
TARGET(UNPACK_SEQUENCE_TWO_TUPLE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(UNPACK_SEQUENCE_TWO_TUPLE);
PyObject *seq;
PyObject **values;
seq = stack_pointer[-1];
@@ -1525,11 +1726,13 @@
Py_DECREF(seq);
STACK_SHRINK(1);
STACK_GROW(oparg);
- next_instr += 1;
DISPATCH();
}
TARGET(UNPACK_SEQUENCE_TUPLE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(UNPACK_SEQUENCE_TUPLE);
PyObject *seq;
PyObject **values;
seq = stack_pointer[-1];
@@ -1544,11 +1747,13 @@
Py_DECREF(seq);
STACK_SHRINK(1);
STACK_GROW(oparg);
- next_instr += 1;
DISPATCH();
}
TARGET(UNPACK_SEQUENCE_LIST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(UNPACK_SEQUENCE_LIST);
PyObject *seq;
PyObject **values;
seq = stack_pointer[-1];
@@ -1563,11 +1768,13 @@
Py_DECREF(seq);
STACK_SHRINK(1);
STACK_GROW(oparg);
- next_instr += 1;
DISPATCH();
}
TARGET(UNPACK_EX) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(UNPACK_EX);
PyObject *seq;
seq = stack_pointer[-1];
int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
@@ -1580,22 +1787,25 @@
}
TARGET(STORE_ATTR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 5;
+ INSTRUCTION_STATS(STORE_ATTR);
PREDICTED(STORE_ATTR);
+ _Py_CODEUNIT *this_instr = next_instr - 5;
static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size");
PyObject *owner;
PyObject *v;
owner = stack_pointer[-1];
v = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
- _PyAttrCache *cache = (_PyAttrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
- next_instr--;
+ next_instr = this_instr;
_Py_Specialize_StoreAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG();
}
STAT_INC(STORE_ATTR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err = PyObject_SetAttr(owner, name, v);
@@ -1603,11 +1813,13 @@
Py_DECREF(owner);
if (err) goto pop_2_error;
STACK_SHRINK(2);
- next_instr += 4;
DISPATCH();
}
TARGET(DELETE_ATTR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(DELETE_ATTR);
PyObject *owner;
owner = stack_pointer[-1];
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
@@ -1619,6 +1831,9 @@
}
TARGET(STORE_GLOBAL) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(STORE_GLOBAL);
PyObject *v;
v = stack_pointer[-1];
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
@@ -1630,6 +1845,9 @@
}
TARGET(DELETE_GLOBAL) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(DELETE_GLOBAL);
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err;
err = PyDict_DelItem(GLOBALS(), name);
@@ -1645,6 +1863,9 @@
}
TARGET(LOAD_LOCALS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_LOCALS);
PyObject *locals;
locals = LOCALS();
if (locals == NULL) {
@@ -1659,6 +1880,9 @@
}
TARGET(LOAD_FROM_DICT_OR_GLOBALS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_FROM_DICT_OR_GLOBALS);
PyObject *mod_or_class_dict;
PyObject *v;
mod_or_class_dict = stack_pointer[-1];
@@ -1692,6 +1916,9 @@
}
TARGET(LOAD_NAME) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_NAME);
PyObject *v;
PyObject *mod_or_class_dict = LOCALS();
if (mod_or_class_dict == NULL) {
@@ -1729,20 +1956,23 @@
}
TARGET(LOAD_GLOBAL) {
+ frame->instr_ptr = next_instr;
+ next_instr += 5;
+ INSTRUCTION_STATS(LOAD_GLOBAL);
PREDICTED(LOAD_GLOBAL);
+ _Py_CODEUNIT *this_instr = next_instr - 5;
static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
PyObject *res;
PyObject *null = NULL;
#if ENABLE_SPECIALIZATION
- _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- next_instr--;
+ next_instr = this_instr;
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
DISPATCH_SAME_OPARG();
}
STAT_INC(LOAD_GLOBAL, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
if (PyDict_CheckExact(GLOBALS())
@@ -1783,16 +2013,18 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
- next_instr += 4;
DISPATCH();
}
TARGET(LOAD_GLOBAL_MODULE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 5;
+ INSTRUCTION_STATS(LOAD_GLOBAL_MODULE);
PyObject *res;
PyObject *null = NULL;
// _GUARD_GLOBALS_VERSION
{
- uint16_t version = read_u16(&next_instr[1].cache);
+ uint16_t version = read_u16(&this_instr[2].cache);
PyDictObject *dict = (PyDictObject *)GLOBALS();
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
@@ -1800,7 +2032,7 @@
}
// _LOAD_GLOBAL_MODULE
{
- uint16_t index = read_u16(&next_instr[3].cache);
+ uint16_t index = read_u16(&this_instr[4].cache);
PyDictObject *dict = (PyDictObject *)GLOBALS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
res = entries[index].me_value;
@@ -1813,16 +2045,18 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
- next_instr += 4;
DISPATCH();
}
TARGET(LOAD_GLOBAL_BUILTIN) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 5;
+ INSTRUCTION_STATS(LOAD_GLOBAL_BUILTIN);
PyObject *res;
PyObject *null = NULL;
// _GUARD_GLOBALS_VERSION
{
- uint16_t version = read_u16(&next_instr[1].cache);
+ uint16_t version = read_u16(&this_instr[2].cache);
PyDictObject *dict = (PyDictObject *)GLOBALS();
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
@@ -1830,7 +2064,7 @@
}
// _GUARD_BUILTINS_VERSION
{
- uint16_t version = read_u16(&next_instr[2].cache);
+ uint16_t version = read_u16(&this_instr[3].cache);
PyDictObject *dict = (PyDictObject *)BUILTINS();
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
@@ -1838,7 +2072,7 @@
}
// _LOAD_GLOBAL_BUILTINS
{
- uint16_t index = read_u16(&next_instr[3].cache);
+ uint16_t index = read_u16(&this_instr[4].cache);
PyDictObject *bdict = (PyDictObject *)BUILTINS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys);
res = entries[index].me_value;
@@ -1851,11 +2085,13 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
- next_instr += 4;
DISPATCH();
}
TARGET(DELETE_FAST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(DELETE_FAST);
PyObject *v = GETLOCAL(oparg);
if (v == NULL) goto unbound_local_error;
SETLOCAL(oparg, NULL);
@@ -1863,6 +2099,9 @@
}
TARGET(MAKE_CELL) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(MAKE_CELL);
// "initial" is probably NULL but not if it's an arg (or set
// via PyFrame_LocalsToFast() before MAKE_CELL has run).
PyObject *initial = GETLOCAL(oparg);
@@ -1875,6 +2114,9 @@
}
TARGET(DELETE_DEREF) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(DELETE_DEREF);
PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell);
// Can't use ERROR_IF here.
@@ -1889,6 +2131,9 @@
}
TARGET(LOAD_FROM_DICT_OR_DEREF) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_FROM_DICT_OR_DEREF);
PyObject *class_dict;
PyObject *value;
class_dict = stack_pointer[-1];
@@ -1915,6 +2160,9 @@
}
TARGET(LOAD_DEREF) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LOAD_DEREF);
PyObject *value;
PyObject *cell = GETLOCAL(oparg);
value = PyCell_GET(cell);
@@ -1929,6 +2177,9 @@
}
TARGET(STORE_DEREF) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(STORE_DEREF);
PyObject *v;
v = stack_pointer[-1];
PyObject *cell = GETLOCAL(oparg);
@@ -1940,6 +2191,9 @@
}
TARGET(COPY_FREE_VARS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(COPY_FREE_VARS);
/* Copy closure variables to free variables */
PyCodeObject *co = _PyFrame_GetCode(frame);
assert(PyFunction_Check(frame->f_funcobj));
@@ -1954,6 +2208,9 @@
}
TARGET(BUILD_STRING) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BUILD_STRING);
PyObject **pieces;
PyObject *str;
pieces = stack_pointer - oparg;
@@ -1969,6 +2226,9 @@
}
TARGET(BUILD_TUPLE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BUILD_TUPLE);
PyObject **values;
PyObject *tup;
values = stack_pointer - oparg;
@@ -1981,6 +2241,9 @@
}
TARGET(BUILD_LIST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BUILD_LIST);
PyObject **values;
PyObject *list;
values = stack_pointer - oparg;
@@ -1993,6 +2256,9 @@
}
TARGET(LIST_EXTEND) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(LIST_EXTEND);
PyObject *iterable;
PyObject *list;
iterable = stack_pointer[-1];
@@ -2017,6 +2283,9 @@
}
TARGET(SET_UPDATE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(SET_UPDATE);
PyObject *iterable;
PyObject *set;
iterable = stack_pointer[-1];
@@ -2029,6 +2298,9 @@
}
TARGET(BUILD_SET) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BUILD_SET);
PyObject **values;
PyObject *set;
values = stack_pointer - oparg;
@@ -2053,6 +2325,9 @@
}
TARGET(BUILD_MAP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BUILD_MAP);
PyObject **values;
PyObject *map;
values = stack_pointer - oparg*2;
@@ -2071,6 +2346,9 @@
}
TARGET(SETUP_ANNOTATIONS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(SETUP_ANNOTATIONS);
int err;
PyObject *ann_dict;
if (LOCALS() == NULL) {
@@ -2112,6 +2390,9 @@
}
TARGET(BUILD_CONST_KEY_MAP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BUILD_CONST_KEY_MAP);
PyObject *keys;
PyObject **values;
PyObject *map;
@@ -2137,6 +2418,9 @@
}
TARGET(DICT_UPDATE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(DICT_UPDATE);
PyObject *update;
PyObject *dict;
update = stack_pointer[-1];
@@ -2156,6 +2440,9 @@
}
TARGET(DICT_MERGE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(DICT_MERGE);
PyObject *update;
PyObject *dict;
PyObject *callable;
@@ -2173,6 +2460,9 @@
}
TARGET(MAP_ADD) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(MAP_ADD);
PyObject *value;
PyObject *key;
PyObject *dict;
@@ -2188,15 +2478,21 @@
}
TARGET(INSTRUMENTED_LOAD_SUPER_ATTR) {
- _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr;
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(INSTRUMENTED_LOAD_SUPER_ATTR);
// cancel out the decrement that will happen in LOAD_SUPER_ATTR; we
// don't want to specialize instrumented instructions
- INCREMENT_ADAPTIVE_COUNTER(cache->counter);
+ INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
}
TARGET(LOAD_SUPER_ATTR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(LOAD_SUPER_ATTR);
PREDICTED(LOAD_SUPER_ATTR);
+ _Py_CODEUNIT *this_instr = next_instr - 2;
static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size");
PyObject *self;
PyObject *class;
@@ -2206,24 +2502,24 @@
self = stack_pointer[-1];
class = stack_pointer[-2];
global_super = stack_pointer[-3];
+ TIER_ONE_ONLY
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
- int load_method = oparg & 1;
#if ENABLE_SPECIALIZATION
- _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ int load_method = oparg & 1;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_LoadSuperAttr(global_super, class, next_instr, load_method);
DISPATCH_SAME_OPARG();
}
STAT_INC(LOAD_SUPER_ATTR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
- frame, next_instr-1, global_super, arg);
+ frame, this_instr, global_super, arg);
if (err) goto pop_3_error;
}
@@ -2236,12 +2532,12 @@
if (super == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, next_instr-1, global_super, arg);
+ frame, this_instr, global_super, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, next_instr-1, global_super, arg);
+ frame, this_instr, global_super, arg);
if (err < 0) {
Py_CLEAR(super);
}
@@ -2259,11 +2555,13 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
- next_instr += 1;
DISPATCH();
}
TARGET(LOAD_SUPER_ATTR_ATTR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(LOAD_SUPER_ATTR_ATTR);
PyObject *self;
PyObject *class;
PyObject *global_super;
@@ -2283,11 +2581,13 @@
if (attr == NULL) goto pop_3_error;
STACK_SHRINK(2);
stack_pointer[-1] = attr;
- next_instr += 1;
DISPATCH();
}
TARGET(LOAD_SUPER_ATTR_METHOD) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(LOAD_SUPER_ATTR_METHOD);
PyObject *self;
PyObject *class;
PyObject *global_super;
@@ -2320,27 +2620,29 @@
STACK_SHRINK(1);
stack_pointer[-2] = attr;
stack_pointer[-1] = self_or_null;
- next_instr += 1;
DISPATCH();
}
TARGET(LOAD_ATTR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR);
PREDICTED(LOAD_ATTR);
+ _Py_CODEUNIT *this_instr = next_instr - 10;
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
PyObject *owner;
PyObject *attr;
PyObject *self_or_null = NULL;
owner = stack_pointer[-1];
#if ENABLE_SPECIALIZATION
- _PyAttrCache *cache = (_PyAttrCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- next_instr--;
+ next_instr = this_instr;
_Py_Specialize_LoadAttr(owner, next_instr, name);
DISPATCH_SAME_OPARG();
}
STAT_INC(LOAD_ATTR, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
if (oparg & 1) {
@@ -2377,18 +2679,20 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = self_or_null; }
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_INSTANCE_VALUE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_INSTANCE_VALUE);
PyObject *owner;
PyObject *attr;
PyObject *null = NULL;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
@@ -2402,7 +2706,7 @@
}
// _LOAD_ATTR_INSTANCE_VALUE
{
- uint16_t index = read_u16(&next_instr[3].cache);
+ uint16_t index = read_u16(&this_instr[4].cache);
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
attr = _PyDictOrValues_GetValues(dorv)->values[index];
DEOPT_IF(attr == NULL, LOAD_ATTR);
@@ -2414,18 +2718,20 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_MODULE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_MODULE);
PyObject *owner;
PyObject *attr;
PyObject *null = NULL;
// _CHECK_ATTR_MODULE
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR);
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
assert(dict != NULL);
@@ -2433,7 +2739,7 @@
}
// _LOAD_ATTR_MODULE
{
- uint16_t index = read_u16(&next_instr[3].cache);
+ uint16_t index = read_u16(&this_instr[4].cache);
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
assert(index < dict->ma_keys->dk_nentries);
@@ -2448,18 +2754,20 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_WITH_HINT) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_WITH_HINT);
PyObject *owner;
PyObject *attr;
PyObject *null = NULL;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
@@ -2475,7 +2783,7 @@
}
// _LOAD_ATTR_WITH_HINT
{
- uint16_t hint = read_u16(&next_instr[3].cache);
+ uint16_t hint = read_u16(&this_instr[4].cache);
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR);
@@ -2499,25 +2807,27 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_SLOT) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_SLOT);
PyObject *owner;
PyObject *attr;
PyObject *null = NULL;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
}
// _LOAD_ATTR_SLOT
{
- uint16_t index = read_u16(&next_instr[3].cache);
+ uint16_t index = read_u16(&this_instr[4].cache);
char *addr = (char *)owner + index;
attr = *(PyObject **)addr;
DEOPT_IF(attr == NULL, LOAD_ATTR);
@@ -2529,25 +2839,27 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_CLASS) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_CLASS);
PyObject *owner;
PyObject *attr;
PyObject *null = NULL;
// _CHECK_ATTR_CLASS
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
DEOPT_IF(!PyType_Check(owner), LOAD_ATTR);
assert(type_version != 0);
DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version, LOAD_ATTR);
}
// _LOAD_ATTR_CLASS
{
- PyObject *descr = read_obj(&next_instr[5].cache);
+ PyObject *descr = read_obj(&this_instr[6].cache);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
attr = Py_NewRef(descr);
@@ -2557,16 +2869,18 @@
STACK_GROW(((oparg & 1) ? 1 : 0));
stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr;
if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; }
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_PROPERTY) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_PROPERTY);
PyObject *owner;
owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- uint32_t func_version = read_u32(&next_instr[3].cache);
- PyObject *fget = read_obj(&next_instr[5].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
+ uint32_t func_version = read_u32(&this_instr[4].cache);
+ PyObject *fget = read_obj(&this_instr[6].cache);
assert((oparg & 1) == 0);
DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
@@ -2586,18 +2900,20 @@
// Manipulate stack directly because we exit with DISPATCH_INLINED().
STACK_SHRINK(1);
new_frame->localsplus[0] = owner;
- SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR);
- assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_LOAD_ATTR;
DISPATCH_INLINED(new_frame);
}
TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN);
PyObject *owner;
owner = stack_pointer[-1];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- uint32_t func_version = read_u32(&next_instr[3].cache);
- PyObject *getattribute = read_obj(&next_instr[5].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
+ uint32_t func_version = read_u32(&this_instr[4].cache);
+ PyObject *getattribute = read_obj(&this_instr[6].cache);
assert((oparg & 1) == 0);
DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
PyTypeObject *cls = Py_TYPE(owner);
@@ -2619,19 +2935,21 @@
STACK_SHRINK(1);
new_frame->localsplus[0] = owner;
new_frame->localsplus[1] = Py_NewRef(name);
- SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR);
- assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_LOAD_ATTR == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_LOAD_ATTR;
DISPATCH_INLINED(new_frame);
}
TARGET(STORE_ATTR_INSTANCE_VALUE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 5;
+ INSTRUCTION_STATS(STORE_ATTR_INSTANCE_VALUE);
PyObject *owner;
PyObject *value;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
@@ -2645,7 +2963,7 @@
// _STORE_ATTR_INSTANCE_VALUE
value = stack_pointer[-2];
{
- uint16_t index = read_u16(&next_instr[3].cache);
+ uint16_t index = read_u16(&this_instr[4].cache);
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
STAT_INC(STORE_ATTR, hit);
PyDictValues *values = _PyDictOrValues_GetValues(dorv);
@@ -2660,17 +2978,19 @@
Py_DECREF(owner);
}
STACK_SHRINK(2);
- next_instr += 4;
DISPATCH();
}
TARGET(STORE_ATTR_WITH_HINT) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 5;
+ INSTRUCTION_STATS(STORE_ATTR_WITH_HINT);
PyObject *owner;
PyObject *value;
owner = stack_pointer[-1];
value = stack_pointer[-2];
- uint32_t type_version = read_u32(&next_instr[1].cache);
- uint16_t hint = read_u16(&next_instr[3].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
+ uint16_t hint = read_u16(&this_instr[4].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
@@ -2710,17 +3030,19 @@
dict->ma_version_tag = new_version;
Py_DECREF(owner);
STACK_SHRINK(2);
- next_instr += 4;
DISPATCH();
}
TARGET(STORE_ATTR_SLOT) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 5;
+ INSTRUCTION_STATS(STORE_ATTR_SLOT);
PyObject *owner;
PyObject *value;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
@@ -2728,7 +3050,7 @@
// _STORE_ATTR_SLOT
value = stack_pointer[-2];
{
- uint16_t index = read_u16(&next_instr[3].cache);
+ uint16_t index = read_u16(&this_instr[4].cache);
char *addr = (char *)owner + index;
STAT_INC(STORE_ATTR, hit);
PyObject *old_value = *(PyObject **)addr;
@@ -2737,12 +3059,15 @@
Py_DECREF(owner);
}
STACK_SHRINK(2);
- next_instr += 4;
DISPATCH();
}
TARGET(COMPARE_OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(COMPARE_OP);
PREDICTED(COMPARE_OP);
+ _Py_CODEUNIT *this_instr = next_instr - 2;
static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size");
PyObject *right;
PyObject *left;
@@ -2750,14 +3075,13 @@
right = stack_pointer[-1];
left = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
- _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_CompareOp(left, right, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
STAT_INC(COMPARE_OP, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
assert((oparg >> 5) <= Py_GE);
res = PyObject_RichCompare(left, right, oparg >> 5);
@@ -2772,11 +3096,13 @@
}
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(COMPARE_OP_FLOAT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(COMPARE_OP_FLOAT);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -2795,11 +3121,13 @@
// It's always a bool, so we don't care about oparg & 16.
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(COMPARE_OP_INT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(COMPARE_OP_INT);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -2822,11 +3150,13 @@
// It's always a bool, so we don't care about oparg & 16.
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(COMPARE_OP_STR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(COMPARE_OP_STR);
PyObject *right;
PyObject *left;
PyObject *res;
@@ -2846,11 +3176,13 @@
// It's always a bool, so we don't care about oparg & 16.
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(IS_OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(IS_OP);
PyObject *right;
PyObject *left;
PyObject *b;
@@ -2866,6 +3198,9 @@
}
TARGET(CONTAINS_OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CONTAINS_OP);
PyObject *right;
PyObject *left;
PyObject *b;
@@ -2882,6 +3217,9 @@
}
TARGET(CHECK_EG_MATCH) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CHECK_EG_MATCH);
PyObject *match_type;
PyObject *exc_value;
PyObject *rest;
@@ -2914,6 +3252,9 @@
}
TARGET(CHECK_EXC_MATCH) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CHECK_EXC_MATCH);
PyObject *right;
PyObject *left;
PyObject *b;
@@ -2933,6 +3274,9 @@
}
TARGET(IMPORT_NAME) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(IMPORT_NAME);
PyObject *fromlist;
PyObject *level;
PyObject *res;
@@ -2949,6 +3293,9 @@
}
TARGET(IMPORT_FROM) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(IMPORT_FROM);
PyObject *from;
PyObject *res;
from = stack_pointer[-1];
@@ -2961,36 +3308,44 @@
}
TARGET(JUMP_FORWARD) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(JUMP_FORWARD);
JUMPBY(oparg);
DISPATCH();
}
TARGET(JUMP_BACKWARD) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(JUMP_BACKWARD);
CHECK_EVAL_BREAKER();
- _Py_CODEUNIT *here = next_instr - 1;
assert(oparg <= INSTR_OFFSET());
JUMPBY(1-oparg);
#if ENABLE_SPECIALIZATION
- here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
- if (here[1].cache > tstate->interp->optimizer_backedge_threshold &&
+ this_instr[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
+ if (this_instr[1].cache > tstate->interp->optimizer_backedge_threshold &&
// Double-check that the opcode isn't instrumented or something:
- here->op.code == JUMP_BACKWARD)
+ this_instr->op.code == JUMP_BACKWARD)
{
OPT_STAT_INC(attempts);
- int optimized = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
+ int optimized = _PyOptimizer_BackEdge(frame, this_instr, next_instr, stack_pointer);
if (optimized < 0) goto error;
if (optimized) {
// Rewind and enter the executor:
- assert(here->op.code == ENTER_EXECUTOR);
- next_instr = here;
+ assert(this_instr->op.code == ENTER_EXECUTOR);
+ next_instr = this_instr;
}
- here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1);
+ this_instr[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1);
}
#endif /* ENABLE_SPECIALIZATION */
DISPATCH();
}
TARGET(ENTER_EXECUTOR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(ENTER_EXECUTOR);
CHECK_EVAL_BREAKER();
PyCodeObject *code = _PyFrame_GetCode(frame);
@@ -3009,34 +3364,41 @@
}
TARGET(POP_JUMP_IF_FALSE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(POP_JUMP_IF_FALSE);
PyObject *cond;
cond = stack_pointer[-1];
assert(PyBool_Check(cond));
int flag = Py_IsFalse(cond);
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
JUMPBY(oparg * flag);
STACK_SHRINK(1);
- next_instr += 1;
DISPATCH();
}
TARGET(POP_JUMP_IF_TRUE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(POP_JUMP_IF_TRUE);
PyObject *cond;
cond = stack_pointer[-1];
assert(PyBool_Check(cond));
int flag = Py_IsTrue(cond);
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
JUMPBY(oparg * flag);
STACK_SHRINK(1);
- next_instr += 1;
DISPATCH();
}
TARGET(POP_JUMP_IF_NONE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(POP_JUMP_IF_NONE);
PyObject *value;
PyObject *b;
PyObject *cond;
@@ -3057,16 +3419,18 @@
assert(PyBool_Check(cond));
int flag = Py_IsTrue(cond);
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
JUMPBY(oparg * flag);
}
STACK_SHRINK(1);
- next_instr += 1;
DISPATCH();
}
TARGET(POP_JUMP_IF_NOT_NONE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(POP_JUMP_IF_NOT_NONE);
PyObject *value;
PyObject *b;
PyObject *cond;
@@ -3087,16 +3451,18 @@
assert(PyBool_Check(cond));
int flag = Py_IsFalse(cond);
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
JUMPBY(oparg * flag);
}
STACK_SHRINK(1);
- next_instr += 1;
DISPATCH();
}
TARGET(JUMP_BACKWARD_NO_INTERRUPT) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(JUMP_BACKWARD_NO_INTERRUPT);
/* This bytecode is used in the `yield from` or `await` loop.
* If there is an interrupt, we want it handled in the innermost
* generator or coroutine, so we deliberately do not check it here.
@@ -3107,6 +3473,9 @@
}
TARGET(GET_LEN) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(GET_LEN);
PyObject *obj;
PyObject *len_o;
obj = stack_pointer[-1];
@@ -3121,6 +3490,9 @@
}
TARGET(MATCH_CLASS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(MATCH_CLASS);
PyObject *names;
PyObject *type;
PyObject *subject;
@@ -3148,6 +3520,9 @@
}
TARGET(MATCH_MAPPING) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(MATCH_MAPPING);
PyObject *subject;
PyObject *res;
subject = stack_pointer[-1];
@@ -3159,6 +3534,9 @@
}
TARGET(MATCH_SEQUENCE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(MATCH_SEQUENCE);
PyObject *subject;
PyObject *res;
subject = stack_pointer[-1];
@@ -3170,6 +3548,9 @@
}
TARGET(MATCH_KEYS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(MATCH_KEYS);
PyObject *keys;
PyObject *subject;
PyObject *values_or_none;
@@ -3184,6 +3565,9 @@
}
TARGET(GET_ITER) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(GET_ITER);
PyObject *iterable;
PyObject *iter;
iterable = stack_pointer[-1];
@@ -3196,6 +3580,9 @@
}
TARGET(GET_YIELD_FROM_ITER) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(GET_YIELD_FROM_ITER);
PyObject *iterable;
PyObject *iter;
iterable = stack_pointer[-1];
@@ -3228,20 +3615,23 @@
}
TARGET(FOR_ITER) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(FOR_ITER);
PREDICTED(FOR_ITER);
+ _Py_CODEUNIT *this_instr = next_instr - 2;
static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size");
PyObject *iter;
PyObject *next;
iter = stack_pointer[-1];
#if ENABLE_SPECIALIZATION
- _PyForIterCache *cache = (_PyForIterCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_ForIter(iter, next_instr, oparg);
DISPATCH_SAME_OPARG();
}
STAT_INC(FOR_ITER, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
/* before: [iter]; after: [iter, iter()] *or* [] (and jump over END_FOR.) */
next = (*Py_TYPE(iter)->tp_iternext)(iter);
@@ -3250,15 +3640,14 @@
if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) {
goto error;
}
- monitor_raise(tstate, frame, next_instr-1);
+ monitor_raise(tstate, frame, this_instr);
_PyErr_Clear(tstate);
}
/* iterator ended normally */
- assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR ||
- next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR);
+ assert(next_instr[oparg].op.code == END_FOR ||
+ next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
Py_DECREF(iter);
STACK_SHRINK(1);
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
/* Jump forward oparg, then skip following END_FOR instruction */
JUMPBY(oparg + 1);
DISPATCH();
@@ -3266,40 +3655,44 @@
// Common case: no jump, leave it to the code generator
STACK_GROW(1);
stack_pointer[-1] = next;
- next_instr += 1;
DISPATCH();
}
TARGET(INSTRUMENTED_FOR_ITER) {
- _Py_CODEUNIT *here = frame->instr_ptr;
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(INSTRUMENTED_FOR_ITER);
_Py_CODEUNIT *target;
PyObject *iter = TOP();
PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter);
if (next != NULL) {
PUSH(next);
- target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER;
+ target = next_instr;
}
else {
if (_PyErr_Occurred(tstate)) {
if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) {
goto error;
}
- monitor_raise(tstate, frame, here);
+ monitor_raise(tstate, frame, this_instr);
_PyErr_Clear(tstate);
}
/* iterator ended normally */
- assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR ||
- next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR);
+ assert(next_instr[oparg].op.code == END_FOR ||
+ next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
STACK_SHRINK(1);
Py_DECREF(iter);
/* Skip END_FOR */
- target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1;
+ target = next_instr + oparg + 1;
}
- INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH);
+ INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH);
DISPATCH();
}
TARGET(FOR_ITER_LIST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(FOR_ITER_LIST);
PyObject *iter;
PyObject *next;
// _ITER_CHECK_LIST
@@ -3320,7 +3713,6 @@
}
Py_DECREF(iter);
STACK_SHRINK(1);
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
/* Jump forward oparg, then skip following END_FOR instruction */
JUMPBY(oparg + 1);
DISPATCH();
@@ -3337,11 +3729,13 @@
}
STACK_GROW(1);
stack_pointer[-1] = next;
- next_instr += 1;
DISPATCH();
}
TARGET(FOR_ITER_TUPLE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(FOR_ITER_TUPLE);
PyObject *iter;
PyObject *next;
// _ITER_CHECK_TUPLE
@@ -3362,7 +3756,6 @@
}
Py_DECREF(iter);
STACK_SHRINK(1);
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
/* Jump forward oparg, then skip following END_FOR instruction */
JUMPBY(oparg + 1);
DISPATCH();
@@ -3379,11 +3772,13 @@
}
STACK_GROW(1);
stack_pointer[-1] = next;
- next_instr += 1;
DISPATCH();
}
TARGET(FOR_ITER_RANGE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(FOR_ITER_RANGE);
PyObject *iter;
PyObject *next;
// _ITER_CHECK_RANGE
@@ -3400,7 +3795,6 @@
if (r->len <= 0) {
STACK_SHRINK(1);
Py_DECREF(r);
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
// Jump over END_FOR instruction.
JUMPBY(oparg + 1);
DISPATCH();
@@ -3419,11 +3813,13 @@
}
STACK_GROW(1);
stack_pointer[-1] = next;
- next_instr += 1;
DISPATCH();
}
TARGET(FOR_ITER_GEN) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(FOR_ITER_GEN);
PyObject *iter;
iter = stack_pointer[-1];
DEOPT_IF(tstate->interp->eval_frame, FOR_ITER);
@@ -3436,15 +3832,17 @@
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
- SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
assert(next_instr[oparg].op.code == END_FOR ||
next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
- assert(1 + INLINE_CACHE_ENTRIES_FOR_ITER == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_FOR_ITER == next_instr - this_instr);
frame->return_offset = (uint16_t)(1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
DISPATCH_INLINED(gen_frame);
}
TARGET(BEFORE_ASYNC_WITH) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BEFORE_ASYNC_WITH);
PyObject *mgr;
PyObject *exit;
PyObject *res;
@@ -3485,6 +3883,9 @@
}
TARGET(BEFORE_WITH) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BEFORE_WITH);
PyObject *mgr;
PyObject *exit;
PyObject *res;
@@ -3528,6 +3929,9 @@
}
TARGET(WITH_EXCEPT_START) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(WITH_EXCEPT_START);
PyObject *val;
PyObject *lasti;
PyObject *exit_func;
@@ -3566,6 +3970,9 @@
}
TARGET(PUSH_EXC_INFO) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(PUSH_EXC_INFO);
PyObject *new_exc;
PyObject *prev_exc;
new_exc = stack_pointer[-1];
@@ -3585,13 +3992,16 @@
}
TARGET(LOAD_ATTR_METHOD_WITH_VALUES) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_METHOD_WITH_VALUES);
PyObject *owner;
PyObject *attr;
PyObject *self;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
@@ -3604,14 +4014,14 @@
}
// _GUARD_KEYS_VERSION
{
- uint32_t keys_version = read_u32(&next_instr[3].cache);
+ uint32_t keys_version = read_u32(&this_instr[4].cache);
PyTypeObject *owner_cls = Py_TYPE(owner);
PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR);
}
// _LOAD_ATTR_METHOD_WITH_VALUES
{
- PyObject *descr = read_obj(&next_instr[5].cache);
+ PyObject *descr = read_obj(&this_instr[6].cache);
assert(oparg & 1);
/* Cached method object */
STAT_INC(LOAD_ATTR, hit);
@@ -3623,25 +4033,27 @@
STACK_GROW(1);
stack_pointer[-2] = attr;
stack_pointer[-1] = self;
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_METHOD_NO_DICT) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_METHOD_NO_DICT);
PyObject *owner;
PyObject *attr;
PyObject *self;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
}
// _LOAD_ATTR_METHOD_NO_DICT
{
- PyObject *descr = read_obj(&next_instr[5].cache);
+ PyObject *descr = read_obj(&this_instr[6].cache);
assert(oparg & 1);
assert(Py_TYPE(owner)->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
@@ -3653,17 +4065,19 @@
STACK_GROW(1);
stack_pointer[-2] = attr;
stack_pointer[-1] = self;
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES);
PyObject *owner;
PyObject *attr;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
@@ -3676,14 +4090,14 @@
}
// _GUARD_KEYS_VERSION
{
- uint32_t keys_version = read_u32(&next_instr[3].cache);
+ uint32_t keys_version = read_u32(&this_instr[4].cache);
PyTypeObject *owner_cls = Py_TYPE(owner);
PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR);
}
// _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES
{
- PyObject *descr = read_obj(&next_instr[5].cache);
+ PyObject *descr = read_obj(&this_instr[6].cache);
assert((oparg & 1) == 0);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
@@ -3691,24 +4105,26 @@
attr = Py_NewRef(descr);
}
stack_pointer[-1] = attr;
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_NONDESCRIPTOR_NO_DICT) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_NONDESCRIPTOR_NO_DICT);
PyObject *owner;
PyObject *attr;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
}
// _LOAD_ATTR_NONDESCRIPTOR_NO_DICT
{
- PyObject *descr = read_obj(&next_instr[5].cache);
+ PyObject *descr = read_obj(&this_instr[6].cache);
assert((oparg & 1) == 0);
assert(Py_TYPE(owner)->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit);
@@ -3717,18 +4133,20 @@
attr = Py_NewRef(descr);
}
stack_pointer[-1] = attr;
- next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_METHOD_LAZY_DICT) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 10;
+ INSTRUCTION_STATS(LOAD_ATTR_METHOD_LAZY_DICT);
PyObject *owner;
PyObject *attr;
PyObject *self;
// _GUARD_TYPE_VERSION
owner = stack_pointer[-1];
{
- uint32_t type_version = read_u32(&next_instr[1].cache);
+ uint32_t type_version = read_u32(&this_instr[2].cache);
PyTypeObject *tp = Py_TYPE(owner);
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
@@ -3743,7 +4161,7 @@
}
// _LOAD_ATTR_METHOD_LAZY_DICT
{
- PyObject *descr = read_obj(&next_instr[5].cache);
+ PyObject *descr = read_obj(&this_instr[6].cache);
assert(oparg & 1);
STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL);
@@ -3754,11 +4172,13 @@
STACK_GROW(1);
stack_pointer[-2] = attr;
stack_pointer[-1] = self;
- next_instr += 9;
DISPATCH();
}
TARGET(INSTRUMENTED_CALL) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(INSTRUMENTED_CALL);
int is_meth = PEEK(oparg + 1) != NULL;
int total_args = oparg + is_meth;
PyObject *function = PEEK(oparg + 2);
@@ -3766,15 +4186,18 @@
&_PyInstrumentation_MISSING : PEEK(total_args);
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
- frame, next_instr-1, function, arg);
+ frame, this_instr, function, arg);
if (err) goto error;
- _PyCallCache *cache = (_PyCallCache *)next_instr;
- INCREMENT_ADAPTIVE_COUNTER(cache->counter);
+ INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
GO_TO_INSTRUCTION(CALL);
}
TARGET(CALL) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL);
PREDICTED(CALL);
+ _Py_CODEUNIT *this_instr = next_instr - 4;
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
PyObject **args;
PyObject *self_or_null;
@@ -3790,14 +4213,13 @@
total_args++;
}
#if ENABLE_SPECIALIZATION
- _PyCallCache *cache = (_PyCallCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_Call(callable, next_instr, total_args);
DISPATCH_SAME_OPARG();
}
STAT_INC(CALL, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
if (self_or_null == NULL && Py_TYPE(callable) == &PyMethod_Type) {
args--;
@@ -3827,8 +4249,7 @@
if (new_frame == NULL) {
goto error;
}
- SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
- assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
DISPATCH_INLINED(new_frame);
}
@@ -3843,12 +4264,12 @@
if (res == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, next_instr-1, callable, arg);
+ frame, this_instr, callable, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, next_instr-1, callable, arg);
+ frame, this_instr, callable, arg);
if (err < 0) {
Py_CLEAR(res);
}
@@ -3863,12 +4284,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_BOUND_METHOD_EXACT_ARGS) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_BOUND_METHOD_EXACT_ARGS);
PyObject *null;
PyObject *callable;
PyObject *self;
@@ -3900,7 +4323,7 @@
self_or_null = self;
callable = func;
{
- uint32_t func_version = read_u32(&next_instr[1].cache);
+ uint32_t func_version = read_u32(&this_instr[2].cache);
DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL);
@@ -3930,10 +4353,9 @@
}
}
// _SAVE_RETURN_OFFSET
- next_instr += 3;
{
#if TIER_ONE
- frame->return_offset = (uint16_t)(next_instr - frame->instr_ptr);
+ frame->return_offset = (uint16_t)(next_instr - this_instr);
#endif
#if TIER_TWO
frame->return_offset = oparg;
@@ -3964,6 +4386,9 @@
}
TARGET(CALL_PY_EXACT_ARGS) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_PY_EXACT_ARGS);
PyObject *self_or_null;
PyObject *callable;
PyObject **args;
@@ -3976,7 +4401,7 @@
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
{
- uint32_t func_version = read_u32(&next_instr[1].cache);
+ uint32_t func_version = read_u32(&this_instr[2].cache);
DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL);
@@ -4006,10 +4431,9 @@
}
}
// _SAVE_RETURN_OFFSET
- next_instr += 3;
{
#if TIER_ONE
- frame->return_offset = (uint16_t)(next_instr - frame->instr_ptr);
+ frame->return_offset = (uint16_t)(next_instr - this_instr);
#endif
#if TIER_TWO
frame->return_offset = oparg;
@@ -4040,13 +4464,16 @@
}
TARGET(CALL_PY_WITH_DEFAULTS) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_PY_WITH_DEFAULTS);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
- uint32_t func_version = read_u32(&next_instr[1].cache);
+ uint32_t func_version = read_u32(&this_instr[2].cache);
DEOPT_IF(tstate->interp->eval_frame, CALL);
int argcount = oparg;
if (self_or_null != NULL) {
@@ -4076,13 +4503,15 @@
}
// Manipulate stack and cache directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 2);
- SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
- assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
DISPATCH_INLINED(new_frame);
}
TARGET(CALL_TYPE_1) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_TYPE_1);
PyObject **args;
PyObject *null;
PyObject *callable;
@@ -4101,11 +4530,13 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
DISPATCH();
}
TARGET(CALL_STR_1) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_STR_1);
PyObject **args;
PyObject *null;
PyObject *callable;
@@ -4125,12 +4556,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_TUPLE_1) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_TUPLE_1);
PyObject **args;
PyObject *null;
PyObject *callable;
@@ -4150,12 +4583,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_ALLOC_AND_ENTER_INIT) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_ALLOC_AND_ENTER_INIT);
PyObject **args;
PyObject *null;
PyObject *callable;
@@ -4167,7 +4602,7 @@
* 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``)
* 3. Pushes the frame for ``__init__`` to the frame stack
* */
- _PyCallCache *cache = (_PyCallCache *)next_instr;
+ _PyCallCache *cache = (_PyCallCache *)&this_instr[1];
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(!PyType_Check(callable), CALL);
PyTypeObject *tp = (PyTypeObject *)callable;
@@ -4196,8 +4631,7 @@
for (int i = 0; i < oparg; i++) {
init_frame->localsplus[i+1] = args[i];
}
- SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
- assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - frame->instr_ptr);
+ assert(1 + INLINE_CACHE_ENTRIES_CALL == next_instr - this_instr);
frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL;
STACK_SHRINK(oparg+2);
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -4214,6 +4648,9 @@
}
TARGET(EXIT_INIT_CHECK) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(EXIT_INIT_CHECK);
PyObject *should_be_none;
should_be_none = stack_pointer[-1];
assert(STACK_LEVEL() == 2);
@@ -4228,6 +4665,9 @@
}
TARGET(CALL_BUILTIN_CLASS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_BUILTIN_CLASS);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4254,12 +4694,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_BUILTIN_O) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_BUILTIN_O);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4294,12 +4736,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_BUILTIN_FAST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_BUILTIN_FAST);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4338,12 +4782,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_BUILTIN_FAST_WITH_KEYWORDS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_BUILTIN_FAST_WITH_KEYWORDS);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4376,12 +4822,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_LEN) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_LEN);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4413,11 +4861,13 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
DISPATCH();
}
TARGET(CALL_ISINSTANCE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_ISINSTANCE);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4451,11 +4901,13 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
DISPATCH();
}
TARGET(CALL_LIST_APPEND) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_LIST_APPEND);
PyObject **args;
PyObject *self;
PyObject *callable;
@@ -4474,13 +4926,16 @@
Py_DECREF(self);
Py_DECREF(callable);
STACK_SHRINK(3);
- // CALL + POP_TOP
- SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1);
- assert(next_instr[-1].op.code == POP_TOP);
+ // Skip POP_TOP
+ assert(next_instr->op.code == POP_TOP);
+ SKIP_OVER(1);
DISPATCH();
}
TARGET(CALL_METHOD_DESCRIPTOR_O) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_O);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4518,12 +4973,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4559,12 +5016,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_METHOD_DESCRIPTOR_NOARGS) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_NOARGS);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4601,12 +5060,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_METHOD_DESCRIPTOR_FAST) {
+ frame->instr_ptr = next_instr;
+ next_instr += 4;
+ INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST);
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@@ -4641,12 +5102,14 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 3;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(INSTRUMENTED_CALL_KW) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_CALL_KW);
int is_meth = PEEK(oparg + 2) != NULL;
int total_args = oparg + is_meth;
PyObject *function = PEEK(oparg + 3);
@@ -4654,13 +5117,17 @@
: PEEK(total_args + 1);
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
- frame, next_instr - 1, function, arg);
+ frame, this_instr, function, arg);
if (err) goto error;
GO_TO_INSTRUCTION(CALL_KW);
}
TARGET(CALL_KW) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CALL_KW);
PREDICTED(CALL_KW);
+ _Py_CODEUNIT *this_instr = next_instr - 1;
PyObject *kwnames;
PyObject **args;
PyObject *self_or_null;
@@ -4706,7 +5173,7 @@
if (new_frame == NULL) {
goto error;
}
- assert(next_instr - frame->instr_ptr == 1);
+ assert(next_instr - this_instr == 1);
frame->return_offset = 1;
DISPATCH_INLINED(new_frame);
}
@@ -4721,12 +5188,12 @@
if (res == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, next_instr-1, callable, arg);
+ frame, this_instr, callable, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, next_instr-1, callable, arg);
+ frame, this_instr, callable, arg);
if (err < 0) {
Py_CLEAR(res);
}
@@ -4747,11 +5214,18 @@
}
TARGET(INSTRUMENTED_CALL_FUNCTION_EX) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_CALL_FUNCTION_EX);
GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
}
TARGET(CALL_FUNCTION_EX) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CALL_FUNCTION_EX);
PREDICTED(CALL_FUNCTION_EX);
+ _Py_CODEUNIT *this_instr = next_instr - 1;
PyObject *kwargs = NULL;
PyObject *callargs;
PyObject *func;
@@ -4781,18 +5255,18 @@
PyTuple_GET_ITEM(callargs, 0) : Py_None;
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
- frame, next_instr-1, func, arg);
+ frame, this_instr, func, arg);
if (err) goto error;
result = PyObject_Call(func, callargs, kwargs);
if (result == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
- frame, next_instr-1, func, arg);
+ frame, this_instr, func, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
- frame, next_instr-1, func, arg);
+ frame, this_instr, func, arg);
if (err < 0) {
Py_CLEAR(result);
}
@@ -4815,7 +5289,7 @@
if (new_frame == NULL) {
goto error;
}
- assert(next_instr - frame->instr_ptr == 1);
+ assert(next_instr - this_instr == 1);
frame->return_offset = 1;
DISPATCH_INLINED(new_frame);
}
@@ -4834,6 +5308,9 @@
}
TARGET(MAKE_FUNCTION) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(MAKE_FUNCTION);
PyObject *codeobj;
PyObject *func;
codeobj = stack_pointer[-1];
@@ -4854,6 +5331,9 @@
}
TARGET(SET_FUNCTION_ATTRIBUTE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(SET_FUNCTION_ATTRIBUTE);
PyObject *func;
PyObject *attr;
func = stack_pointer[-1];
@@ -4888,6 +5368,9 @@
}
TARGET(RETURN_GENERATOR) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(RETURN_GENERATOR);
assert(PyFunction_Check(frame->f_funcobj));
PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj;
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
@@ -4913,6 +5396,9 @@
}
TARGET(BUILD_SLICE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(BUILD_SLICE);
PyObject *step = NULL;
PyObject *stop;
PyObject *start;
@@ -4932,6 +5418,9 @@
}
TARGET(CONVERT_VALUE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CONVERT_VALUE);
PyObject *value;
PyObject *result;
value = stack_pointer[-1];
@@ -4946,6 +5435,9 @@
}
TARGET(FORMAT_SIMPLE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(FORMAT_SIMPLE);
PyObject *value;
PyObject *res;
value = stack_pointer[-1];
@@ -4964,6 +5456,9 @@
}
TARGET(FORMAT_WITH_SPEC) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(FORMAT_WITH_SPEC);
PyObject *fmt_spec;
PyObject *value;
PyObject *res;
@@ -4979,6 +5474,9 @@
}
TARGET(COPY) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(COPY);
PyObject *bottom;
PyObject *top;
bottom = stack_pointer[-1 - (oparg-1)];
@@ -4990,7 +5488,11 @@
}
TARGET(BINARY_OP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(BINARY_OP);
PREDICTED(BINARY_OP);
+ _Py_CODEUNIT *this_instr = next_instr - 2;
static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size");
PyObject *rhs;
PyObject *lhs;
@@ -4998,14 +5500,13 @@
rhs = stack_pointer[-1];
lhs = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
- _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
- if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
- next_instr--;
+ if (ADAPTIVE_COUNTER_IS_ZERO(this_instr[1].cache)) {
+ next_instr = this_instr;
_Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, LOCALS_ARRAY);
DISPATCH_SAME_OPARG();
}
STAT_INC(BINARY_OP, deferred);
- DECREMENT_ADAPTIVE_COUNTER(cache->counter);
+ DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
#endif /* ENABLE_SPECIALIZATION */
assert(NB_ADD <= oparg);
assert(oparg <= NB_INPLACE_XOR);
@@ -5016,11 +5517,13 @@
if (res == NULL) goto pop_2_error;
STACK_SHRINK(1);
stack_pointer[-1] = res;
- next_instr += 1;
DISPATCH();
}
TARGET(SWAP) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(SWAP);
PyObject *top;
PyObject *bottom;
top = stack_pointer[-1];
@@ -5032,13 +5535,15 @@
}
TARGET(INSTRUMENTED_INSTRUCTION) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_INSTRUCTION);
int next_opcode = _Py_call_instrumentation_instruction(
- tstate, frame, next_instr-1);
+ tstate, frame, this_instr);
if (next_opcode < 0) goto error;
- next_instr--;
+ next_instr = this_instr;
if (_PyOpcode_Caches[next_opcode]) {
- _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1);
- INCREMENT_ADAPTIVE_COUNTER(cache->counter);
+ INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
}
assert(next_opcode > 0 && next_opcode < 256);
opcode = next_opcode;
@@ -5046,49 +5551,57 @@
}
TARGET(INSTRUMENTED_JUMP_FORWARD) {
- _Py_CODEUNIT *here = frame->instr_ptr;
- INSTRUMENTED_JUMP(here, next_instr + oparg, PY_MONITORING_EVENT_JUMP);
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_JUMP_FORWARD);
+ INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_JUMP);
DISPATCH();
}
TARGET(INSTRUMENTED_JUMP_BACKWARD) {
- _Py_CODEUNIT *here = frame->instr_ptr;
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(INSTRUMENTED_JUMP_BACKWARD);
CHECK_EVAL_BREAKER();
- INSTRUMENTED_JUMP(here, next_instr + 1 - oparg, PY_MONITORING_EVENT_JUMP);
+ INSTRUMENTED_JUMP(this_instr, next_instr + 1 - oparg, PY_MONITORING_EVENT_JUMP);
DISPATCH();
}
TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_TRUE);
PyObject *cond = POP();
assert(PyBool_Check(cond));
- _Py_CODEUNIT *here = frame->instr_ptr;
int flag = Py_IsTrue(cond);
int offset = flag * oparg;
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
- INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
- next_instr += 1;
+ INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
DISPATCH();
}
TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_FALSE);
PyObject *cond = POP();
assert(PyBool_Check(cond));
- _Py_CODEUNIT *here = frame->instr_ptr;
int flag = Py_IsFalse(cond);
int offset = flag * oparg;
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
- INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
- next_instr += 1;
+ INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
DISPATCH();
}
TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NONE);
PyObject *value = POP();
- _Py_CODEUNIT *here = frame->instr_ptr;
int flag = Py_IsNone(value);
int offset;
if (flag) {
@@ -5099,16 +5612,17 @@
offset = 0;
}
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | flag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | flag;
#endif
- INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
- next_instr += 1;
+ INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
DISPATCH();
}
TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) {
+ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
+ next_instr += 2;
+ INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NOT_NONE);
PyObject *value = POP();
- _Py_CODEUNIT *here = frame->instr_ptr;
int offset;
int nflag = Py_IsNone(value);
if (nflag) {
@@ -5119,14 +5633,16 @@
offset = oparg;
}
#if ENABLE_SPECIALIZATION
- next_instr->cache = (next_instr->cache << 1) | !nflag;
+ this_instr[1].cache = (this_instr[1].cache << 1) | !nflag;
#endif
- INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
- next_instr += 1;
+ INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
DISPATCH();
}
TARGET(EXTENDED_ARG) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(EXTENDED_ARG);
assert(oparg);
opcode = next_instr->op.code;
oparg = oparg << 8 | next_instr->op.arg;
@@ -5135,11 +5651,17 @@
}
TARGET(CACHE) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(CACHE);
assert(0 && "Executing a cache.");
Py_UNREACHABLE();
}
TARGET(RESERVED) {
+ frame->instr_ptr = next_instr;
+ next_instr += 1;
+ INSTRUCTION_STATS(RESERVED);
assert(0 && "Executing RESERVED instruction.");
Py_UNREACHABLE();
}
diff --git a/Tools/cases_generator/analysis.py b/Tools/cases_generator/analysis.py
index 53f715db6f24a..180bd01302ec1 100644
--- a/Tools/cases_generator/analysis.py
+++ b/Tools/cases_generator/analysis.py
@@ -432,7 +432,6 @@ def report_non_viable_uops(self, jsonfile: str) -> None:
"LOAD_FAST_LOAD_FAST",
"LOAD_CONST_LOAD_FAST",
"STORE_FAST_STORE_FAST",
- "_BINARY_OP_INPLACE_ADD_UNICODE",
"POP_JUMP_IF_TRUE",
"POP_JUMP_IF_FALSE",
"_ITER_JUMP_LIST",
diff --git a/Tools/cases_generator/instructions.py b/Tools/cases_generator/instructions.py
index c6b551675e3e7..e9ed2a867ae2b 100644
--- a/Tools/cases_generator/instructions.py
+++ b/Tools/cases_generator/instructions.py
@@ -61,6 +61,7 @@ class Instruction:
# Computed by constructor
always_exits: str # If the block always exits, its last line; else ""
has_deopt: bool
+ needs_this_instr: bool
cache_offset: int
cache_effects: list[parsing.CacheEffect]
input_effects: list[StackEffect]
@@ -87,6 +88,7 @@ def __init__(self, inst: parsing.InstDef):
effect for effect in inst.inputs if isinstance(effect, parsing.CacheEffect)
]
self.cache_offset = sum(c.size for c in self.cache_effects)
+ self.needs_this_instr = variable_used(self.inst, "this_instr") or any(c.name != UNUSED for c in self.cache_effects)
self.input_effects = [
effect for effect in inst.inputs if isinstance(effect, StackEffect)
]
@@ -164,7 +166,8 @@ def write_body(
func = f"read_u{bits}"
if tier == TIER_ONE:
out.emit(
- f"{typ}{ceffect.name} = {func}(&next_instr[{active.offset}].cache);"
+ f"{typ}{ceffect.name} = "
+ f"{func}(&this_instr[{active.offset + 1}].cache);"
)
else:
out.emit(f"{typ}{ceffect.name} = ({typ.strip()})operand;")
diff --git a/Tools/cases_generator/stacking.py b/Tools/cases_generator/stacking.py
index 69a6c10d6199c..123e38c524f49 100644
--- a/Tools/cases_generator/stacking.py
+++ b/Tools/cases_generator/stacking.py
@@ -365,8 +365,17 @@ def write_macro_instr(mac: MacroInstruction, out: Formatter) -> None:
]
out.emit("")
with out.block(f"TARGET({mac.name})"):
+ needs_this = any(part.instr.needs_this_instr for part in parts)
+ if needs_this and not mac.predicted:
+ out.emit(f"_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;")
+ else:
+ out.emit(f"frame->instr_ptr = next_instr;")
+ out.emit(f"next_instr += {mac.cache_offset+1};")
+ out.emit(f"INSTRUCTION_STATS({mac.name});")
if mac.predicted:
out.emit(f"PREDICTED({mac.name});")
+ if needs_this:
+ out.emit(f"_Py_CODEUNIT *this_instr = next_instr - {mac.cache_offset+1};")
out.static_assert_family_size(mac.name, mac.family, mac.cache_offset)
try:
next_instr_is_set = write_components(
@@ -375,8 +384,6 @@ def write_macro_instr(mac: MacroInstruction, out: Formatter) -> None:
except AssertionError as err:
raise AssertionError(f"Error writing macro {mac.name}") from err
if not parts[-1].instr.always_exits:
- if not next_instr_is_set and mac.cache_offset:
- out.emit(f"next_instr += {mac.cache_offset};")
if parts[-1].instr.check_eval_breaker:
out.emit("CHECK_EVAL_BREAKER();")
out.emit("DISPATCH();")
@@ -450,8 +457,6 @@ def write_components(
if mgr.instr.name == "_SAVE_RETURN_OFFSET":
next_instr_is_set = True
- if cache_offset:
- out.emit(f"next_instr += {cache_offset};")
if tier == TIER_ONE:
assert_no_pokes(managers)
1
0
[3.12] gh-111531: Tkinter: fix reference leaks in bind_class() and bind_all() (GH-111533) (GH-111535)
by serhiy-storchaka 31 Oct '23
by serhiy-storchaka 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/dde5a99ba2173cf1ffbc1692d680006102…
commit: dde5a99ba2173cf1ffbc1692d68000610250eacd
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2023-10-31T07:26:31Z
summary:
[3.12] gh-111531: Tkinter: fix reference leaks in bind_class() and bind_all() (GH-111533) (GH-111535)
(cherry picked from commit e3353c498d79f0f3f108a9baf8807a12e77c2ebe)
Co-authored-by: Serhiy Storchaka <storchaka(a)gmail.com>
files:
A Misc/NEWS.d/next/Library/2023-10-31-07-46-56.gh-issue-111531.6zUV_G.rst
M Lib/tkinter/__init__.py
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index c59f8d11e8a9d..cb3e5f1ebab49 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -1459,7 +1459,7 @@ def bind_all(self, sequence=None, func=None, add=None):
An additional boolean parameter ADD specifies whether FUNC will
be called additionally to the other bound function or whether
it will replace the previous function. See bind for the return value."""
- return self._bind(('bind', 'all'), sequence, func, add, 0)
+ return self._root()._bind(('bind', 'all'), sequence, func, add, True)
def unbind_all(self, sequence):
"""Unbind for all widgets for event SEQUENCE all functions."""
@@ -1473,7 +1473,7 @@ def bind_class(self, className, sequence=None, func=None, add=None):
whether it will replace the previous function. See bind for
the return value."""
- return self._bind(('bind', className), sequence, func, add, 0)
+ return self._root()._bind(('bind', className), sequence, func, add, True)
def unbind_class(self, className, sequence):
"""Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE
diff --git a/Misc/NEWS.d/next/Library/2023-10-31-07-46-56.gh-issue-111531.6zUV_G.rst b/Misc/NEWS.d/next/Library/2023-10-31-07-46-56.gh-issue-111531.6zUV_G.rst
new file mode 100644
index 0000000000000..b722f0414184b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-10-31-07-46-56.gh-issue-111531.6zUV_G.rst
@@ -0,0 +1,2 @@
+Fix reference leaks in ``bind_class()`` and ``bind_all()`` methods of
+:mod:`tkinter` widgets.
1
0
[3.11] gh-111531: Tkinter: fix reference leaks in bind_class() and bind_all() (GH-111533) (GH-111536)
by serhiy-storchaka 31 Oct '23
by serhiy-storchaka 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/c66f0bedebeb0f63f02999fdf5c9ce9e04…
commit: c66f0bedebeb0f63f02999fdf5c9ce9e045ea97d
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2023-10-31T07:13:29Z
summary:
[3.11] gh-111531: Tkinter: fix reference leaks in bind_class() and bind_all() (GH-111533) (GH-111536)
(cherry picked from commit e3353c498d79f0f3f108a9baf8807a12e77c2ebe)
Co-authored-by: Serhiy Storchaka <storchaka(a)gmail.com>
files:
A Misc/NEWS.d/next/Library/2023-10-31-07-46-56.gh-issue-111531.6zUV_G.rst
M Lib/tkinter/__init__.py
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index 6ae9839055382..704e7b8364b8e 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -1459,7 +1459,7 @@ def bind_all(self, sequence=None, func=None, add=None):
An additional boolean parameter ADD specifies whether FUNC will
be called additionally to the other bound function or whether
it will replace the previous function. See bind for the return value."""
- return self._bind(('bind', 'all'), sequence, func, add, 0)
+ return self._root()._bind(('bind', 'all'), sequence, func, add, True)
def unbind_all(self, sequence):
"""Unbind for all widgets for event SEQUENCE all functions."""
@@ -1473,7 +1473,7 @@ def bind_class(self, className, sequence=None, func=None, add=None):
whether it will replace the previous function. See bind for
the return value."""
- return self._bind(('bind', className), sequence, func, add, 0)
+ return self._root()._bind(('bind', className), sequence, func, add, True)
def unbind_class(self, className, sequence):
"""Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE
diff --git a/Misc/NEWS.d/next/Library/2023-10-31-07-46-56.gh-issue-111531.6zUV_G.rst b/Misc/NEWS.d/next/Library/2023-10-31-07-46-56.gh-issue-111531.6zUV_G.rst
new file mode 100644
index 0000000000000..b722f0414184b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-10-31-07-46-56.gh-issue-111531.6zUV_G.rst
@@ -0,0 +1,2 @@
+Fix reference leaks in ``bind_class()`` and ``bind_all()`` methods of
+:mod:`tkinter` widgets.
1
0
[3.12] gh-111301: Move `importlib.resources.files` change to What's new in Python 3.12 (#111512) (#111534)
by hugovk 31 Oct '23
by hugovk 31 Oct '23
31 Oct '23
https://github.com/python/cpython/commit/e820d7603bad40c4980633fc9fffea3eaf…
commit: e820d7603bad40c4980633fc9fffea3eafe34236
branch: 3.12
author: Hugo van Kemenade <hugovk(a)users.noreply.github.com>
committer: hugovk <hugovk(a)users.noreply.github.com>
date: 2023-10-31T06:49:24Z
summary:
[3.12] gh-111301: Move `importlib.resources.files` change to What's new in Python 3.12 (#111512) (#111534)
Co-authored-by: Karolina Surma <33810531+befeleme(a)users.noreply.github.com>
files:
M Doc/whatsnew/3.12.rst
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 99e566f7d253c..feed5238bfab2 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -716,6 +716,9 @@ importlib.resources
* :func:`importlib.resources.as_file` now supports resource directories.
(Contributed by Jason R. Coombs in :gh:`97930`.)
+* Rename first parameter of :func:`importlib.resources.files` to *anchor*.
+ (Contributed by Jason R. Coombs in :gh:`100598`.)
+
inspect
-------
1
0