From 8d87f6a346eb2e3e44ee624c22044ccd7e504f4b Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 19 Oct 2023 00:27:13 +0200 Subject: [PATCH 1/2] Avoid refcounted copy in _object_properties_init() for internal classes This currently uses ZVAL_COPY_OR_DUP, which copies the value and handles refcounting. However, internal classes cannot have refcounted default properties because of constraints imposed by zend_declare_typed_property(). So copying the value is sufficient. While this doesn't really improve the performance for our benchmarks, it improves performance for cases where a lot of temporary internal objects are instantiated. For example, when instantiating DOM classes: DOM objects are transient, so lots of temporary objects are created. --- Zend/zend_API.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 82a56f5b6abc6..781666fddb1f4 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1610,8 +1610,11 @@ static zend_always_inline void _object_properties_init(zend_object *object, zend zval *end = src + class_type->default_properties_count; if (UNEXPECTED(class_type->type == ZEND_INTERNAL_CLASS)) { + /* We don't have to account for refcounting because + * zend_declare_typed_property() disallows refcounted defaults for internal classes. */ do { - ZVAL_COPY_OR_DUP_PROP(dst, src); + ZEND_ASSERT(!Z_REFCOUNTED_P(src)); + ZVAL_COPY_VALUE_PROP(dst, src); src++; dst++; } while (src != end); From 6b5609330d9a3fad5baec2dce5bd4c7f74f63fd2 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 19 Oct 2023 11:43:33 +0200 Subject: [PATCH 2/2] Also in zend_do_inheritance_ex --- Zend/zend_inheritance.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index d1c66b310a6b4..7d605fc38c8c0 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1547,7 +1547,10 @@ ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *par do { dst--; src--; - ZVAL_COPY_OR_DUP_PROP(dst, src); + /* We don't have to account for refcounting because + * zend_declare_typed_property() disallows refcounted defaults for internal classes. */ + ZEND_ASSERT(!Z_REFCOUNTED_P(src)); + ZVAL_COPY_VALUE_PROP(dst, src); if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; ce->ce_flags |= ZEND_ACC_HAS_AST_PROPERTIES;