mirror of
https://github.com/python/cpython.git
synced 2026-03-20 20:01:16 +00:00
gh-87729: specialize LOAD_SUPER_ATTR_METHOD (#103809)
This commit is contained in:
parent
cef542ca57
commit
ef25febcf2
14 changed files with 539 additions and 357 deletions
|
|
@ -440,7 +440,8 @@ def _write_atomic(path, data, mode=0o666):
|
|||
# Python 3.12a7 3524 (Shrink the BINARY_SUBSCR caches)
|
||||
# Python 3.12b1 3525 (Shrink the CALL caches)
|
||||
# Python 3.12b1 3526 (Add instrumentation support)
|
||||
# Python 3.12b1 3527 (Optimize super() calls)
|
||||
# Python 3.12b1 3527 (Add LOAD_SUPER_ATTR)
|
||||
# Python 3.12b1 3528 (Add LOAD_SUPER_ATTR_METHOD specialization)
|
||||
|
||||
# Python 3.13 will start with 3550
|
||||
|
||||
|
|
@ -457,7 +458,7 @@ def _write_atomic(path, data, mode=0o666):
|
|||
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||
# in PC/launcher.c must also be updated.
|
||||
|
||||
MAGIC_NUMBER = (3527).to_bytes(2, 'little') + b'\r\n'
|
||||
MAGIC_NUMBER = (3528).to_bytes(2, 'little') + b'\r\n'
|
||||
|
||||
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||
|
||||
|
|
|
|||
|
|
@ -353,6 +353,9 @@ def pseudo_op(name, op, real_ops):
|
|||
"FOR_ITER_RANGE",
|
||||
"FOR_ITER_GEN",
|
||||
],
|
||||
"LOAD_SUPER_ATTR": [
|
||||
"LOAD_SUPER_ATTR_METHOD",
|
||||
],
|
||||
"LOAD_ATTR": [
|
||||
# These potentially push [NULL, bound method] onto the stack.
|
||||
"LOAD_ATTR_CLASS",
|
||||
|
|
@ -426,6 +429,12 @@ def pseudo_op(name, op, real_ops):
|
|||
"FOR_ITER": {
|
||||
"counter": 1,
|
||||
},
|
||||
"LOAD_SUPER_ATTR": {
|
||||
"counter": 1,
|
||||
"class_version": 2,
|
||||
"self_type_version": 2,
|
||||
"method": 4,
|
||||
},
|
||||
"LOAD_ATTR": {
|
||||
"counter": 1,
|
||||
"version": 2,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,29 @@
|
|||
import unittest
|
||||
|
||||
|
||||
class TestLoadSuperAttrCache(unittest.TestCase):
|
||||
def test_descriptor_not_double_executed_on_spec_fail(self):
|
||||
calls = []
|
||||
class Descriptor:
|
||||
def __get__(self, instance, owner):
|
||||
calls.append((instance, owner))
|
||||
return lambda: 1
|
||||
|
||||
class C:
|
||||
d = Descriptor()
|
||||
|
||||
class D(C):
|
||||
def f(self):
|
||||
return super().d()
|
||||
|
||||
d = D()
|
||||
|
||||
self.assertEqual(d.f(), 1) # warmup
|
||||
calls.clear()
|
||||
self.assertEqual(d.f(), 1) # try to specialize
|
||||
self.assertEqual(calls, [(d, D)])
|
||||
|
||||
|
||||
class TestLoadAttrCache(unittest.TestCase):
|
||||
def test_descriptor_added_after_optimization(self):
|
||||
class Descriptor:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue