mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Implement dom_get_doc_props_read_only()
I was surprised to see that getting the stricterror property showed in in the Callgrind profile of some tests. Turns out we sometimes allocate them. Fix this by returning the default in case no changes were made yet. Closes GH-11345.
This commit is contained in:
parent
d8102e6ba4
commit
c6655fb719
4 changed files with 43 additions and 43 deletions
|
@ -116,6 +116,11 @@ PHP 8.3 INTERNALS UPGRADE NOTES
|
||||||
- The PHPAPI spl_iterator_apply() function now returns zend_result instead of int.
|
- The PHPAPI spl_iterator_apply() function now returns zend_result instead of int.
|
||||||
There are no functional changes.
|
There are no functional changes.
|
||||||
|
|
||||||
|
f. ext/dom
|
||||||
|
- A new function dom_get_doc_props_read_only() is added to gather the document
|
||||||
|
properties in a read-only way. This function avoids allocation when there are
|
||||||
|
no document properties changed yet.
|
||||||
|
|
||||||
========================
|
========================
|
||||||
4. OpCode changes
|
4. OpCode changes
|
||||||
========================
|
========================
|
||||||
|
|
|
@ -297,7 +297,7 @@ readonly=no
|
||||||
int dom_document_format_output_read(dom_object *obj, zval *retval)
|
int dom_document_format_output_read(dom_object *obj, zval *retval)
|
||||||
{
|
{
|
||||||
if (obj->document) {
|
if (obj->document) {
|
||||||
dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
|
libxml_doc_props const* doc_prop = dom_get_doc_props_read_only(obj->document);
|
||||||
ZVAL_BOOL(retval, doc_prop->formatoutput);
|
ZVAL_BOOL(retval, doc_prop->formatoutput);
|
||||||
} else {
|
} else {
|
||||||
ZVAL_FALSE(retval);
|
ZVAL_FALSE(retval);
|
||||||
|
@ -322,7 +322,7 @@ readonly=no
|
||||||
int dom_document_validate_on_parse_read(dom_object *obj, zval *retval)
|
int dom_document_validate_on_parse_read(dom_object *obj, zval *retval)
|
||||||
{
|
{
|
||||||
if (obj->document) {
|
if (obj->document) {
|
||||||
dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
|
libxml_doc_props const* doc_prop = dom_get_doc_props_read_only(obj->document);
|
||||||
ZVAL_BOOL(retval, doc_prop->validateonparse);
|
ZVAL_BOOL(retval, doc_prop->validateonparse);
|
||||||
} else {
|
} else {
|
||||||
ZVAL_FALSE(retval);
|
ZVAL_FALSE(retval);
|
||||||
|
@ -347,7 +347,7 @@ readonly=no
|
||||||
int dom_document_resolve_externals_read(dom_object *obj, zval *retval)
|
int dom_document_resolve_externals_read(dom_object *obj, zval *retval)
|
||||||
{
|
{
|
||||||
if (obj->document) {
|
if (obj->document) {
|
||||||
dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
|
libxml_doc_props const* doc_prop = dom_get_doc_props_read_only(obj->document);
|
||||||
ZVAL_BOOL(retval, doc_prop->resolveexternals);
|
ZVAL_BOOL(retval, doc_prop->resolveexternals);
|
||||||
} else {
|
} else {
|
||||||
ZVAL_FALSE(retval);
|
ZVAL_FALSE(retval);
|
||||||
|
@ -372,7 +372,7 @@ readonly=no
|
||||||
int dom_document_preserve_whitespace_read(dom_object *obj, zval *retval)
|
int dom_document_preserve_whitespace_read(dom_object *obj, zval *retval)
|
||||||
{
|
{
|
||||||
if (obj->document) {
|
if (obj->document) {
|
||||||
dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
|
libxml_doc_props const* doc_prop = dom_get_doc_props_read_only(obj->document);
|
||||||
ZVAL_BOOL(retval, doc_prop->preservewhitespace);
|
ZVAL_BOOL(retval, doc_prop->preservewhitespace);
|
||||||
} else {
|
} else {
|
||||||
ZVAL_FALSE(retval);
|
ZVAL_FALSE(retval);
|
||||||
|
@ -397,7 +397,7 @@ readonly=no
|
||||||
int dom_document_recover_read(dom_object *obj, zval *retval)
|
int dom_document_recover_read(dom_object *obj, zval *retval)
|
||||||
{
|
{
|
||||||
if (obj->document) {
|
if (obj->document) {
|
||||||
dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
|
libxml_doc_props const* doc_prop = dom_get_doc_props_read_only(obj->document);
|
||||||
ZVAL_BOOL(retval, doc_prop->recover);
|
ZVAL_BOOL(retval, doc_prop->recover);
|
||||||
} else {
|
} else {
|
||||||
ZVAL_FALSE(retval);
|
ZVAL_FALSE(retval);
|
||||||
|
@ -422,7 +422,7 @@ readonly=no
|
||||||
int dom_document_substitue_entities_read(dom_object *obj, zval *retval)
|
int dom_document_substitue_entities_read(dom_object *obj, zval *retval)
|
||||||
{
|
{
|
||||||
if (obj->document) {
|
if (obj->document) {
|
||||||
dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
|
libxml_doc_props const* doc_prop = dom_get_doc_props_read_only(obj->document);
|
||||||
ZVAL_BOOL(retval, doc_prop->substituteentities);
|
ZVAL_BOOL(retval, doc_prop->substituteentities);
|
||||||
} else {
|
} else {
|
||||||
ZVAL_FALSE(retval);
|
ZVAL_FALSE(retval);
|
||||||
|
@ -1176,7 +1176,6 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t so
|
||||||
{
|
{
|
||||||
xmlDocPtr ret;
|
xmlDocPtr ret;
|
||||||
xmlParserCtxtPtr ctxt = NULL;
|
xmlParserCtxtPtr ctxt = NULL;
|
||||||
dom_doc_propsptr doc_props;
|
|
||||||
dom_object *intern;
|
dom_object *intern;
|
||||||
php_libxml_ref_obj *document = NULL;
|
php_libxml_ref_obj *document = NULL;
|
||||||
int validate, recover, resolve_externals, keep_blanks, substitute_ent;
|
int validate, recover, resolve_externals, keep_blanks, substitute_ent;
|
||||||
|
@ -1189,17 +1188,13 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t so
|
||||||
document = intern->document;
|
document = intern->document;
|
||||||
}
|
}
|
||||||
|
|
||||||
doc_props = dom_get_doc_props(document);
|
libxml_doc_props const* doc_props = dom_get_doc_props_read_only(document);
|
||||||
validate = doc_props->validateonparse;
|
validate = doc_props->validateonparse;
|
||||||
resolve_externals = doc_props->resolveexternals;
|
resolve_externals = doc_props->resolveexternals;
|
||||||
keep_blanks = doc_props->preservewhitespace;
|
keep_blanks = doc_props->preservewhitespace;
|
||||||
substitute_ent = doc_props->substituteentities;
|
substitute_ent = doc_props->substituteentities;
|
||||||
recover = doc_props->recover;
|
recover = doc_props->recover;
|
||||||
|
|
||||||
if (document == NULL) {
|
|
||||||
efree(doc_props);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlInitParser();
|
xmlInitParser();
|
||||||
|
|
||||||
if (mode == DOM_LOAD_FILE) {
|
if (mode == DOM_LOAD_FILE) {
|
||||||
|
@ -1387,7 +1382,6 @@ PHP_METHOD(DOMDocument, save)
|
||||||
size_t file_len = 0;
|
size_t file_len = 0;
|
||||||
int bytes, format, saveempty = 0;
|
int bytes, format, saveempty = 0;
|
||||||
dom_object *intern;
|
dom_object *intern;
|
||||||
dom_doc_propsptr doc_props;
|
|
||||||
char *file;
|
char *file;
|
||||||
zend_long options = 0;
|
zend_long options = 0;
|
||||||
|
|
||||||
|
@ -1405,7 +1399,7 @@ PHP_METHOD(DOMDocument, save)
|
||||||
|
|
||||||
/* encoding handled by property on doc */
|
/* encoding handled by property on doc */
|
||||||
|
|
||||||
doc_props = dom_get_doc_props(intern->document);
|
libxml_doc_props const* doc_props = dom_get_doc_props_read_only(intern->document);
|
||||||
format = doc_props->formatoutput;
|
format = doc_props->formatoutput;
|
||||||
if (options & LIBXML_SAVE_NOEMPTYTAG) {
|
if (options & LIBXML_SAVE_NOEMPTYTAG) {
|
||||||
saveempty = xmlSaveNoEmptyTags;
|
saveempty = xmlSaveNoEmptyTags;
|
||||||
|
@ -1433,7 +1427,6 @@ PHP_METHOD(DOMDocument, saveXML)
|
||||||
xmlBufferPtr buf;
|
xmlBufferPtr buf;
|
||||||
xmlChar *mem;
|
xmlChar *mem;
|
||||||
dom_object *intern, *nodeobj;
|
dom_object *intern, *nodeobj;
|
||||||
dom_doc_propsptr doc_props;
|
|
||||||
int size, format, saveempty = 0;
|
int size, format, saveempty = 0;
|
||||||
zend_long options = 0;
|
zend_long options = 0;
|
||||||
|
|
||||||
|
@ -1444,7 +1437,7 @@ PHP_METHOD(DOMDocument, saveXML)
|
||||||
|
|
||||||
DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
|
DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
|
||||||
|
|
||||||
doc_props = dom_get_doc_props(intern->document);
|
libxml_doc_props const* doc_props = dom_get_doc_props_read_only(intern->document);
|
||||||
format = doc_props->formatoutput;
|
format = doc_props->formatoutput;
|
||||||
|
|
||||||
if (nodep != NULL) {
|
if (nodep != NULL) {
|
||||||
|
@ -1928,7 +1921,6 @@ PHP_METHOD(DOMDocument, saveHTMLFile)
|
||||||
size_t file_len;
|
size_t file_len;
|
||||||
int bytes, format;
|
int bytes, format;
|
||||||
dom_object *intern;
|
dom_object *intern;
|
||||||
dom_doc_propsptr doc_props;
|
|
||||||
char *file;
|
char *file;
|
||||||
const char *encoding;
|
const char *encoding;
|
||||||
|
|
||||||
|
@ -1947,7 +1939,7 @@ PHP_METHOD(DOMDocument, saveHTMLFile)
|
||||||
|
|
||||||
encoding = (const char *) htmlGetMetaEncoding(docp);
|
encoding = (const char *) htmlGetMetaEncoding(docp);
|
||||||
|
|
||||||
doc_props = dom_get_doc_props(intern->document);
|
libxml_doc_props const* doc_props = dom_get_doc_props_read_only(intern->document);
|
||||||
format = doc_props->formatoutput;
|
format = doc_props->formatoutput;
|
||||||
bytes = htmlSaveFileFormat(file, docp, encoding, format);
|
bytes = htmlSaveFileFormat(file, docp, encoding, format);
|
||||||
|
|
||||||
|
@ -1969,7 +1961,6 @@ PHP_METHOD(DOMDocument, saveHTML)
|
||||||
dom_object *intern, *nodeobj;
|
dom_object *intern, *nodeobj;
|
||||||
xmlChar *mem = NULL;
|
xmlChar *mem = NULL;
|
||||||
int format;
|
int format;
|
||||||
dom_doc_propsptr doc_props;
|
|
||||||
|
|
||||||
id = ZEND_THIS;
|
id = ZEND_THIS;
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS(),
|
if (zend_parse_parameters(ZEND_NUM_ARGS(),
|
||||||
|
@ -1980,7 +1971,7 @@ PHP_METHOD(DOMDocument, saveHTML)
|
||||||
|
|
||||||
DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
|
DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
|
||||||
|
|
||||||
doc_props = dom_get_doc_props(intern->document);
|
libxml_doc_props const* doc_props = dom_get_doc_props(intern->document);
|
||||||
format = doc_props->formatoutput;
|
format = doc_props->formatoutput;
|
||||||
|
|
||||||
if (nodep != NULL) {
|
if (nodep != NULL) {
|
||||||
|
|
|
@ -140,6 +140,17 @@ int dom_node_children_valid(xmlNodePtr node) {
|
||||||
}
|
}
|
||||||
/* }}} end dom_node_children_valid */
|
/* }}} end dom_node_children_valid */
|
||||||
|
|
||||||
|
static const libxml_doc_props default_doc_props = {
|
||||||
|
.formatoutput = false,
|
||||||
|
.validateonparse = false,
|
||||||
|
.resolveexternals = false,
|
||||||
|
.preservewhitespace = true,
|
||||||
|
.substituteentities = false,
|
||||||
|
.stricterror = true,
|
||||||
|
.recover = false,
|
||||||
|
.classmap = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
/* {{{ dom_get_doc_props() */
|
/* {{{ dom_get_doc_props() */
|
||||||
dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document)
|
dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document)
|
||||||
{
|
{
|
||||||
|
@ -149,28 +160,31 @@ dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document)
|
||||||
return document->doc_props;
|
return document->doc_props;
|
||||||
} else {
|
} else {
|
||||||
doc_props = emalloc(sizeof(libxml_doc_props));
|
doc_props = emalloc(sizeof(libxml_doc_props));
|
||||||
doc_props->formatoutput = 0;
|
memcpy(doc_props, &default_doc_props, sizeof(libxml_doc_props));
|
||||||
doc_props->validateonparse = 0;
|
|
||||||
doc_props->resolveexternals = 0;
|
|
||||||
doc_props->preservewhitespace = 1;
|
|
||||||
doc_props->substituteentities = 0;
|
|
||||||
doc_props->stricterror = 1;
|
|
||||||
doc_props->recover = 0;
|
|
||||||
doc_props->classmap = NULL;
|
|
||||||
if (document) {
|
if (document) {
|
||||||
document->doc_props = doc_props;
|
document->doc_props = doc_props;
|
||||||
}
|
}
|
||||||
return doc_props;
|
return doc_props;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
libxml_doc_props const* dom_get_doc_props_read_only(const php_libxml_ref_obj *document)
|
||||||
|
{
|
||||||
|
if (document && document->doc_props) {
|
||||||
|
return document->doc_props;
|
||||||
|
} else {
|
||||||
|
return &default_doc_props;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void dom_copy_doc_props(php_libxml_ref_obj *source_doc, php_libxml_ref_obj *dest_doc)
|
static void dom_copy_doc_props(php_libxml_ref_obj *source_doc, php_libxml_ref_obj *dest_doc)
|
||||||
{
|
{
|
||||||
dom_doc_propsptr source, dest;
|
dom_doc_propsptr dest;
|
||||||
|
|
||||||
if (source_doc && dest_doc) {
|
if (source_doc && dest_doc) {
|
||||||
|
|
||||||
source = dom_get_doc_props(source_doc);
|
libxml_doc_props const* source = dom_get_doc_props_read_only(source_doc);
|
||||||
dest = dom_get_doc_props(dest_doc);
|
dest = dom_get_doc_props(dest_doc);
|
||||||
|
|
||||||
dest->formatoutput = source->formatoutput;
|
dest->formatoutput = source->formatoutput;
|
||||||
|
@ -212,10 +226,8 @@ void dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece
|
||||||
|
|
||||||
zend_class_entry *dom_get_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece)
|
zend_class_entry *dom_get_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece)
|
||||||
{
|
{
|
||||||
dom_doc_propsptr doc_props;
|
|
||||||
|
|
||||||
if (document) {
|
if (document) {
|
||||||
doc_props = dom_get_doc_props(document);
|
libxml_doc_props const* doc_props = dom_get_doc_props_read_only(document);
|
||||||
if (doc_props->classmap) {
|
if (doc_props->classmap) {
|
||||||
zend_class_entry *ce = zend_hash_find_ptr(doc_props->classmap, basece->name);
|
zend_class_entry *ce = zend_hash_find_ptr(doc_props->classmap, basece->name);
|
||||||
if (ce) {
|
if (ce) {
|
||||||
|
@ -230,16 +242,7 @@ zend_class_entry *dom_get_doc_classmap(php_libxml_ref_obj *document, zend_class_
|
||||||
|
|
||||||
/* {{{ dom_get_strict_error() */
|
/* {{{ dom_get_strict_error() */
|
||||||
int dom_get_strict_error(php_libxml_ref_obj *document) {
|
int dom_get_strict_error(php_libxml_ref_obj *document) {
|
||||||
int stricterror;
|
return dom_get_doc_props_read_only(document)->stricterror;
|
||||||
dom_doc_propsptr doc_props;
|
|
||||||
|
|
||||||
doc_props = dom_get_doc_props(document);
|
|
||||||
stricterror = doc_props->stricterror;
|
|
||||||
if (document == NULL) {
|
|
||||||
efree(doc_props);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stricterror;
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ typedef struct {
|
||||||
|
|
||||||
dom_object *dom_object_get_data(xmlNodePtr obj);
|
dom_object *dom_object_get_data(xmlNodePtr obj);
|
||||||
dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document);
|
dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document);
|
||||||
|
libxml_doc_props const* dom_get_doc_props_read_only(const php_libxml_ref_obj *document);
|
||||||
zend_object *dom_objects_new(zend_class_entry *class_type);
|
zend_object *dom_objects_new(zend_class_entry *class_type);
|
||||||
zend_object *dom_nnodemap_objects_new(zend_class_entry *class_type);
|
zend_object *dom_nnodemap_objects_new(zend_class_entry *class_type);
|
||||||
#ifdef LIBXML_XPATH_ENABLED
|
#ifdef LIBXML_XPATH_ENABLED
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue