Skip to content

Commit 464aba1

Browse files
authored
Merge branch 'main' into patch-1
2 parents fba0344 + bd6bf91 commit 464aba1

8 files changed

Lines changed: 38 additions & 11 deletions

File tree

Lib/test/test_capi/test_opt.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3154,20 +3154,22 @@ def testfunc(n):
31543154
uops = get_opnames(ex)
31553155
self.assertNotIn("_CHECK_IS_NOT_PY_CALLABLE_KW", uops)
31563156

3157-
def test_call_len_string(self):
3157+
def test_call_len_string_frozen_set_dict(self):
31583158
def testfunc(n):
31593159
for _ in range(n):
31603160
_ = len("abc")
31613161
d = ''
31623162
_ = len(d)
31633163
_ = len(b"def")
31643164
_ = len(b"")
3165+
_ = len(FROZEN_SET_CONST)
3166+
_ = len(FROZEN_DICT_CONST)
31653167

31663168
_, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
31673169
self.assertIsNotNone(ex)
31683170
uops = get_opnames(ex)
31693171
self.assertNotIn("_CALL_LEN", uops)
3170-
self.assertGreaterEqual(count_ops(ex, "_LOAD_CONST_INLINE_BORROW"), 8)
3172+
self.assertGreaterEqual(count_ops(ex, "_LOAD_CONST_INLINE_BORROW"), 10)
31713173

31723174
def test_call_len_known_length_small_int(self):
31733175
# Make sure that len(t) is optimized for a tuple of length 5.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Speed up converting a list to a tuple in the ``tuple(genexpr)`` fast path
2+
and in starred tuple displays (e.g. ``(*a, *b)``) by stealing the list's
3+
items into the tuple instead of copying them.

Modules/_remote_debugging/code_objects.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ parse_code_object(RemoteUnwinderObject *unwinder,
432432

433433
#ifdef Py_GIL_DISABLED
434434
// Handle thread-local bytecode (TLBC) in free threading builds
435-
if (ctx->tlbc_index == 0 || unwinder->debug_offsets.code_object.co_tlbc == 0 || unwinder == NULL) {
435+
if (ctx->tlbc_index == 0 || unwinder == NULL || unwinder->debug_offsets.code_object.co_tlbc == 0) {
436436
// No TLBC or no unwinder - use main bytecode directly
437437
addrq = (uint16_t *)ip - (uint16_t *)meta->addr_code_adaptive;
438438
goto done_tlbc;

Python/intrinsics.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "pycore_genobject.h" // _PyAsyncGenValueWrapperNew
88
#include "pycore_interpframe.h" // _PyFrame_GetLocals()
99
#include "pycore_intrinsics.h" // INTRINSIC_PRINT
10+
#include "pycore_list.h" // _PyList_AsTupleAndClear()
11+
#include "pycore_object.h" // _PyObject_IsUniquelyReferenced()
1012
#include "pycore_pyerrors.h" // _PyErr_SetString()
1113
#include "pycore_runtime.h" // _Py_ID()
1214
#include "pycore_typevarobject.h" // _Py_make_typevar()
@@ -190,8 +192,12 @@ unary_pos(PyThreadState* unused, PyObject *value)
190192
static PyObject *
191193
list_to_tuple(PyThreadState* unused, PyObject *v)
192194
{
193-
assert(PyList_Check(v));
194-
return PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
195+
/* INTRINSIC_LIST_TO_TUPLE is only emitted by the compiler for a
196+
freshly-built, uniquely-referenced temporary list, so steal its items
197+
into the tuple instead of copying them. */
198+
assert(PyList_CheckExact(v));
199+
assert(_PyObject_IsUniquelyReferenced(v));
200+
return _PyList_AsTupleAndClear((PyListObject *)v);
195201
}
196202

197203
static PyObject *

Python/optimizer_bytecodes.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2378,7 +2378,7 @@ dummy_func(void) {
23782378
res = sym_new_type(ctx, &PyLong_Type);
23792379
Py_ssize_t length = sym_tuple_length(arg);
23802380

2381-
// Not a tuple, check if it's a const string
2381+
// Not a tuple, check if it's another immutable const with known length
23822382
if (length < 0 && sym_is_const(ctx, arg)) {
23832383
PyObject *const_val = sym_get_const(ctx, arg);
23842384
if (const_val != NULL) {
@@ -2388,6 +2388,12 @@ dummy_func(void) {
23882388
else if (PyBytes_CheckExact(const_val)) {
23892389
length = PyBytes_GET_SIZE(const_val);
23902390
}
2391+
else if (PyFrozenDict_CheckExact(const_val)) {
2392+
length = PyDict_GET_SIZE(const_val);
2393+
}
2394+
else if (PyFrozenSet_CheckExact(const_val)) {
2395+
length = PySet_GET_SIZE(const_val);
2396+
}
23912397
}
23922398
}
23932399

Python/optimizer_cases.c.h

Lines changed: 6 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/analyzer.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,9 @@ def has_error_without_pop(op: parser.CodeDef) -> bool:
616616
"PyStackRef_RefcountOnObject",
617617
"PyStackRef_TYPE",
618618
"PyStackRef_True",
619+
"PyBytes_GET_SIZE",
620+
"PyDict_GET_SIZE",
621+
"PySet_GET_SIZE",
619622
"PyTuple_GET_ITEM",
620623
"PyTuple_GET_SIZE",
621624
"PyType_HasFeature",

Tools/msi/dev/dev_files.wxs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
<Component Id="libs_python3.lib" Directory="libs" Guid="*">
1414
<File Id="libs_python_stable.lib" Name="python$(var.MajorVersionNumber).lib" KeyPath="yes" />
1515
</Component>
16+
<Component Id="libs_python3t.lib" Directory="libs" Guid="*">
17+
<File Id="libs_python_abi3tcompat.lib" Name="python$(var.MajorVersionNumber)t.lib" KeyPath="yes" />
18+
</Component>
1619
<Component Id="libs_python.lib" Directory="libs" Guid="*">
1720
<File Id="libs_python.lib" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber).lib" KeyPath="yes" />
1821
</Component>
@@ -24,6 +27,9 @@
2427
<Component Id="libs_python3_d.lib" Directory="libs" Guid="*">
2528
<File Id="libs_python_stable_d.lib" Name="python$(var.MajorVersionNumber)_d.lib" />
2629
</Component>
30+
<Component Id="libs_python3t_d.lib" Directory="libs" Guid="*">
31+
<File Id="libs_python_abi3tcompat_d.lib" Name="python$(var.MajorVersionNumber)t_d.lib" />
32+
</Component>
2733
<Component Id="libs_python_d.lib" Directory="libs" Guid="*">
2834
<File Id="libs_python_d.lib" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber)_d.lib" />
2935
</Component>

0 commit comments

Comments
 (0)