mirror of
https://github.com/python/cpython.git
synced 2025-12-22 08:29:12 +00:00
GH-131798: Optimize cached class attributes and methods in the JIT (GH-134403)
This commit is contained in:
parent
09e72cf091
commit
ec736e7dae
12 changed files with 365 additions and 130 deletions
|
|
@ -1280,8 +1280,8 @@ class TestUopsOptimization(unittest.TestCase):
|
|||
self.assertIsNotNone(ex)
|
||||
self.assertEqual(res, TIER2_THRESHOLD * 6 + 1)
|
||||
call = opnames.index("_CALL_BUILTIN_FAST")
|
||||
load_attr_top = opnames.index("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", 0, call)
|
||||
load_attr_bottom = opnames.index("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", call)
|
||||
load_attr_top = opnames.index("_POP_TOP_LOAD_CONST_INLINE_BORROW", 0, call)
|
||||
load_attr_bottom = opnames.index("_POP_TOP_LOAD_CONST_INLINE_BORROW", call)
|
||||
self.assertEqual(opnames[:load_attr_top].count("_GUARD_TYPE_VERSION"), 1)
|
||||
self.assertEqual(opnames[call:load_attr_bottom].count("_CHECK_VALIDITY"), 2)
|
||||
|
||||
|
|
@ -1303,8 +1303,8 @@ class TestUopsOptimization(unittest.TestCase):
|
|||
self.assertIsNotNone(ex)
|
||||
self.assertEqual(res, TIER2_THRESHOLD * 2)
|
||||
call = opnames.index("_CALL_BUILTIN_FAST_WITH_KEYWORDS")
|
||||
load_attr_top = opnames.index("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", 0, call)
|
||||
load_attr_bottom = opnames.index("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", call)
|
||||
load_attr_top = opnames.index("_POP_TOP_LOAD_CONST_INLINE_BORROW", 0, call)
|
||||
load_attr_bottom = opnames.index("_POP_TOP_LOAD_CONST_INLINE_BORROW", call)
|
||||
self.assertEqual(opnames[:load_attr_top].count("_GUARD_TYPE_VERSION"), 1)
|
||||
self.assertEqual(opnames[call:load_attr_bottom].count("_CHECK_VALIDITY"), 2)
|
||||
|
||||
|
|
@ -2169,6 +2169,45 @@ class TestUopsOptimization(unittest.TestCase):
|
|||
self.assertNotIn("_LOAD_SMALL_INT", uops)
|
||||
self.assertIn("_LOAD_CONST_INLINE_BORROW", uops)
|
||||
|
||||
def test_cached_attributes(self):
|
||||
class C:
|
||||
A = 1
|
||||
def m(self):
|
||||
return 1
|
||||
class D:
|
||||
__slots__ = ()
|
||||
A = 1
|
||||
def m(self):
|
||||
return 1
|
||||
class E(Exception):
|
||||
def m(self):
|
||||
return 1
|
||||
def f(n):
|
||||
x = 0
|
||||
c = C()
|
||||
d = D()
|
||||
e = E()
|
||||
for _ in range(n):
|
||||
x += C.A # _LOAD_ATTR_CLASS
|
||||
x += c.A # _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES
|
||||
x += d.A # _LOAD_ATTR_NONDESCRIPTOR_NO_DICT
|
||||
x += c.m() # _LOAD_ATTR_METHOD_WITH_VALUES
|
||||
x += d.m() # _LOAD_ATTR_METHOD_NO_DICT
|
||||
x += e.m() # _LOAD_ATTR_METHOD_LAZY_DICT
|
||||
return x
|
||||
|
||||
res, ex = self._run_with_optimizer(f, TIER2_THRESHOLD)
|
||||
self.assertEqual(res, 6 * TIER2_THRESHOLD)
|
||||
self.assertIsNotNone(ex)
|
||||
uops = get_opnames(ex)
|
||||
self.assertNotIn("_LOAD_ATTR_CLASS", uops)
|
||||
self.assertNotIn("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", uops)
|
||||
self.assertNotIn("_LOAD_ATTR_NONDESCRIPTOR_NO_DICT", uops)
|
||||
self.assertNotIn("_LOAD_ATTR_METHOD_WITH_VALUES", uops)
|
||||
self.assertNotIn("_LOAD_ATTR_METHOD_NO_DICT", uops)
|
||||
self.assertNotIn("_LOAD_ATTR_METHOD_LAZY_DICT", uops)
|
||||
|
||||
|
||||
def global_identity(x):
|
||||
return x
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue