Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d480c04

Browse files
Implement cache slot optimization for XMLReader (#17232)
1 parent 26244c7 commit d480c04

File tree

3 files changed

+80
-4
lines changed

3 files changed

+80
-4
lines changed

‎UPGRADING‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,5 +236,8 @@ PHP 8.5 UPGRADE NOTES
236236
14. Performance Improvements
237237
========================================
238238

239+
- XMLReader:
240+
. Improved property access performance.
241+
239242
- XMLWriter:
240243
. Improved performance and reduce memory consumption.

‎ext/xmlreader/php_xmlreader.c‎

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,25 @@ static zval *xmlreader_get_property_ptr_ptr(zend_object *object, zend_string *na
123123
}
124124
/* }}} */
125125

126+
static xmlreader_prop_handler *xmlreader_get_prop_handler(zend_string *name, void **cache_slot)
127+
{
128+
/* We don't store the `ce` as that may match with how the std cache slot code works in the fallback,
129+
* instead use the prop handlers table as `ce`. */
130+
if (cache_slot && cache_slot[0] == &xmlreader_prop_handlers) {
131+
return cache_slot[1];
132+
} else {
133+
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
134+
if (hnd != NULL && cache_slot) {
135+
CACHE_POLYMORPHIC_PTR_EX(cache_slot, &xmlreader_prop_handlers, hnd);
136+
}
137+
return hnd;
138+
}
139+
}
140+
126141
static int xmlreader_has_property(zend_object *object, zend_string *name, int type, void **cache_slot)
127142
{
128143
xmlreader_object *obj = php_xmlreader_fetch_object(object);
129-
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
144+
xmlreader_prop_handler *hnd = xmlreader_get_prop_handler(name, cache_slot);
130145

131146
if (hnd != NULL) {
132147
if (type == ZEND_PROPERTY_EXISTS) {
@@ -162,7 +177,7 @@ static zval *xmlreader_read_property(zend_object *object, zend_string *name, int
162177
{
163178
zval *retval = NULL;
164179
xmlreader_object *obj = php_xmlreader_fetch_object(object);
165-
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
180+
xmlreader_prop_handler *hnd = xmlreader_get_prop_handler(name, cache_slot);
166181

167182
if (hnd != NULL) {
168183
if (xmlreader_property_reader(obj, hnd, rv) == FAILURE) {
@@ -181,7 +196,7 @@ static zval *xmlreader_read_property(zend_object *object, zend_string *name, int
181196
/* {{{ xmlreader_write_property */
182197
static zval *xmlreader_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
183198
{
184-
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
199+
xmlreader_prop_handler *hnd = xmlreader_get_prop_handler(name, cache_slot);
185200

186201
if (hnd != NULL) {
187202
zend_readonly_property_modification_error_ex(ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
@@ -195,7 +210,7 @@ static zval *xmlreader_write_property(zend_object *object, zend_string *name, zv
195210

196211
void xmlreader_unset_property(zend_object *object, zend_string *name, void **cache_slot)
197212
{
198-
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
213+
xmlreader_prop_handler *hnd = xmlreader_get_prop_handler(name, cache_slot);
199214

200215
if (hnd != NULL) {
201216
zend_throw_error(NULL, "Cannot unset %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));

‎ext/xmlreader/tests/cache_slot.phpt‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
Cache slot test
3+
--EXTENSIONS--
4+
xmlreader
5+
--FILE--
6+
<?php
7+
8+
class Test1 {
9+
function __construct(public string $localName) {}
10+
}
11+
12+
#[AllowDynamicProperties]
13+
class Test2 extends XMLReader {
14+
}
15+
16+
function readLocalName($obj) {
17+
for ($i = 0; $i < 2; $i++)
18+
var_dump($obj->localName);
19+
}
20+
21+
function readTestProp($obj) {
22+
for ($i = 0; $i < 2; $i++)
23+
var_dump($obj->testProp);
24+
}
25+
26+
$reader = XMLReader::fromString("<root/>");
27+
$reader->read();
28+
$test1 = new Test1("hello");
29+
30+
readLocalName($reader);
31+
readLocalName($test1);
32+
readLocalName($reader);
33+
34+
$test2 = new Test2;
35+
$test2->testProp = 1;
36+
37+
readTestProp($test2);
38+
readTestProp($reader);
39+
readTestProp($test2);
40+
41+
?>
42+
--EXPECTF--
43+
string(4) "root"
44+
string(4) "root"
45+
string(5) "hello"
46+
string(5) "hello"
47+
string(4) "root"
48+
string(4) "root"
49+
int(1)
50+
int(1)
51+
52+
Warning: Undefined property: XMLReader::$testProp in %s on line %d
53+
NULL
54+
55+
Warning: Undefined property: XMLReader::$testProp in %s on line %d
56+
NULL
57+
int(1)
58+
int(1)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /