Skip to content

Commit 127ccd8

Browse files
committed
Add free-threaded specialization for COMPARE_OP, and tests for COMPARE_OP
specialization in general.
1 parent 359389e commit 127ccd8

File tree

4 files changed

+42
-11
lines changed

4 files changed

+42
-11
lines changed

Lib/test/test_opcache.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,39 @@ def binary_subscr_str_int():
15201520
self.assert_specialized(binary_subscr_str_int, "BINARY_SUBSCR_STR_INT")
15211521
self.assert_no_opcode(binary_subscr_str_int, "BINARY_SUBSCR")
15221522

1523+
@cpython_only
1524+
@requires_specialization_ft
1525+
def test_compare_op(self):
1526+
def compare_op_int():
1527+
for _ in range(100):
1528+
a, b = 1, 2
1529+
c = a == b
1530+
self.assertFalse(c)
1531+
1532+
compare_op_int()
1533+
self.assert_specialized(compare_op_int, "COMPARE_OP_INT")
1534+
self.assert_no_opcode(compare_op_int, "COMPARE_OP")
1535+
1536+
def compare_op_float():
1537+
for _ in range(100):
1538+
a, b = 1.0, 2.0
1539+
c = a == b
1540+
self.assertFalse(c)
1541+
1542+
compare_op_float()
1543+
self.assert_specialized(compare_op_float, "COMPARE_OP_FLOAT")
1544+
self.assert_no_opcode(compare_op_float, "COMPARE_OP")
1545+
1546+
def compare_op_str():
1547+
for _ in range(100):
1548+
a, b = "spam", "ham"
1549+
c = a == b
1550+
self.assertFalse(c)
1551+
1552+
compare_op_str()
1553+
self.assert_specialized(compare_op_str, "COMPARE_OP_STR")
1554+
self.assert_no_opcode(compare_op_str, "COMPARE_OP")
1555+
15231556

15241557
if __name__ == "__main__":
15251558
unittest.main()

Python/bytecodes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2404,7 +2404,7 @@ dummy_func(
24042404
};
24052405

24062406
specializing op(_SPECIALIZE_COMPARE_OP, (counter/1, left, right -- left, right)) {
2407-
#if ENABLE_SPECIALIZATION
2407+
#if ENABLE_SPECIALIZATION_FT
24082408
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
24092409
next_instr = this_instr;
24102410
_Py_Specialize_CompareOp(left, right, next_instr, oparg);

Python/generated_cases.c.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/specialize.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,8 +2415,9 @@ _Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *i
24152415
{
24162416
PyObject *lhs = PyStackRef_AsPyObjectBorrow(lhs_st);
24172417
PyObject *rhs = PyStackRef_AsPyObjectBorrow(rhs_st);
2418+
uint8_t specialized_op;
24182419

2419-
assert(ENABLE_SPECIALIZATION);
2420+
assert(ENABLE_SPECIALIZATION_FT);
24202421
assert(_PyOpcode_Caches[COMPARE_OP] == INLINE_CACHE_ENTRIES_COMPARE_OP);
24212422
// All of these specializations compute boolean values, so they're all valid
24222423
// regardless of the fifth-lowest oparg bit.
@@ -2426,12 +2427,12 @@ _Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *i
24262427
goto failure;
24272428
}
24282429
if (PyFloat_CheckExact(lhs)) {
2429-
instr->op.code = COMPARE_OP_FLOAT;
2430+
specialized_op = COMPARE_OP_FLOAT;
24302431
goto success;
24312432
}
24322433
if (PyLong_CheckExact(lhs)) {
24332434
if (_PyLong_IsCompact((PyLongObject *)lhs) && _PyLong_IsCompact((PyLongObject *)rhs)) {
2434-
instr->op.code = COMPARE_OP_INT;
2435+
specialized_op = COMPARE_OP_INT;
24352436
goto success;
24362437
}
24372438
else {
@@ -2446,19 +2447,16 @@ _Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *i
24462447
goto failure;
24472448
}
24482449
else {
2449-
instr->op.code = COMPARE_OP_STR;
2450+
specialized_op = COMPARE_OP_STR;
24502451
goto success;
24512452
}
24522453
}
24532454
SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
24542455
failure:
2455-
STAT_INC(COMPARE_OP, failure);
2456-
instr->op.code = COMPARE_OP;
2457-
cache->counter = adaptive_counter_backoff(cache->counter);
2456+
unspecialize(instr);
24582457
return;
24592458
success:
2460-
STAT_INC(COMPARE_OP, success);
2461-
cache->counter = adaptive_counter_cooldown();
2459+
specialize(instr, specialized_op);
24622460
}
24632461

24642462
#ifdef Py_STATS

0 commit comments

Comments
 (0)