Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Include/internal/pycore_opcode_metadata.h

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

14 changes: 14 additions & 0 deletions Lib/test/test_capi/test_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1858,6 +1858,20 @@ def testfunc(n):
self.assertNotIn("_GUARD_NOS_NULL", uops)
self.assertNotIn("_GUARD_CALLABLE_STR_1", uops)

def test_call_str_1_pop_top(self):
def testfunc(n):
x = 0
for _ in range(n):
t = str("")
x += 1 if len(t) == 0 else 0
return x
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertEqual(res, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_CALL_STR_1", uops)
self.assertIn("_POP_TOP_NOP", uops)

def test_call_str_1_result_is_str(self):
def testfunc(n):
x = 0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Eliminate redundant refcounting from ``_CALL_STR_1``.
10 changes: 4 additions & 6 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -4055,17 +4055,14 @@ dummy_func(
DEOPT_IF(callable_o != (PyObject *)&PyUnicode_Type);
}

op(_CALL_STR_1, (callable, null, arg -- res)) {
op(_CALL_STR_1, (callable, null, arg -- res, a)) {
PyObject *arg_o = PyStackRef_AsPyObjectBorrow(arg);

assert(oparg == 1);
STAT_INC(CALL, hit);
INPUTS_DEAD();
PyObject *res_o = PyObject_Str(arg_o);
DEAD(null);
DEAD(callable);
(void)callable; // Silence compiler warnings about unused variables
(void)null;
PyStackRef_CLOSE(arg);
a = arg;
ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
Expand All @@ -4076,6 +4073,7 @@ dummy_func(
_GUARD_NOS_NULL +
_GUARD_CALLABLE_STR_1 +
_CALL_STR_1 +
POP_TOP +
_CHECK_PERIODIC;

op(_GUARD_CALLABLE_TUPLE_1, (callable, unused, unused -- callable, unused, unused)) {
Expand Down
16 changes: 5 additions & 11 deletions Python/executor_cases.c.h

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

27 changes: 14 additions & 13 deletions Python/generated_cases.c.h

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

3 changes: 2 additions & 1 deletion Python/optimizer_bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -936,14 +936,15 @@ dummy_func(void) {
}
}

op(_CALL_STR_1, (unused, unused, arg -- res)) {
op(_CALL_STR_1, (unused, unused, arg -- res, a)) {
if (sym_matches_type(arg, &PyUnicode_Type)) {
// e.g. str('foo') or str(foo) where foo is known to be a string
res = arg;
}
else {
res = sym_new_type(ctx, &PyUnicode_Type);
}
a = arg;
}

op(_CALL_ISINSTANCE, (unused, unused, instance, cls -- res)) {
Expand Down
5 changes: 4 additions & 1 deletion Python/optimizer_cases.c.h

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

Loading