uops = get_opnames(ex)
self.assertNotIn("_CHECK_IS_NOT_PY_CALLABLE_KW", uops)
- def test_call_len_string(self):
+ def test_call_len_string_frozen_set_dict(self):
def testfunc(n):
for _ in range(n):
_ = len("abc")
_ = len(d)
_ = len(b"def")
_ = len(b"")
+ _ = len(FROZEN_SET_CONST)
+ _ = len(FROZEN_DICT_CONST)
_, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertNotIn("_CALL_LEN", uops)
- self.assertGreaterEqual(count_ops(ex, "_LOAD_CONST_INLINE_BORROW"), 8)
+ self.assertGreaterEqual(count_ops(ex, "_LOAD_CONST_INLINE_BORROW"), 10)
def test_call_len_known_length_small_int(self):
# Make sure that len(t) is optimized for a tuple of length 5.
res = sym_new_type(ctx, &PyLong_Type);
Py_ssize_t length = sym_tuple_length(arg);
- // Not a tuple, check if it's a const string
+ // Not a tuple, check if it's another immutable const with known length
if (length < 0 && sym_is_const(ctx, arg)) {
PyObject *const_val = sym_get_const(ctx, arg);
if (const_val != NULL) {
else if (PyBytes_CheckExact(const_val)) {
length = PyBytes_GET_SIZE(const_val);
}
+ else if (PyFrozenDict_CheckExact(const_val)) {
+ length = PyDict_GET_SIZE(const_val);
+ }
+ else if (PyFrozenSet_CheckExact(const_val)) {
+ length = PySet_GET_SIZE(const_val);
+ }
}
}
length = PyUnicode_GET_LENGTH(const_val);
}
else if (PyBytes_CheckExact(const_val)) {
- CHECK_STACK_BOUNDS(-2);
- stack_pointer[-3] = res;
- stack_pointer += -2;
- ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
length = PyBytes_GET_SIZE(const_val);
- stack_pointer += 2;
+ }
+ else if (PyFrozenDict_CheckExact(const_val)) {
+ length = PyDict_GET_SIZE(const_val);
+ }
+ else if (PyFrozenSet_CheckExact(const_val)) {
+ length = PySet_GET_SIZE(const_val);
}
}
}
"PyStackRef_RefcountOnObject",
"PyStackRef_TYPE",
"PyStackRef_True",
+ "PyBytes_GET_SIZE",
+ "PyDict_GET_SIZE",
+ "PySet_GET_SIZE",
"PyTuple_GET_ITEM",
"PyTuple_GET_SIZE",
"PyType_HasFeature",