mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-08-07 06:43:02 +03:00
more performance hunting reducing memory allocation and free and avoiding
* SAX2.c xmlreader.c include/libxml/parser.h: more performance hunting reducing memory allocation and free and avoiding expensive routines Daniel
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
Wed Sep 17 15:57:44 CEST 2003 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
|
* SAX2.c xmlreader.c include/libxml/parser.h: more performance hunting
|
||||||
|
reducing memory allocation and free and avoiding expensive routines
|
||||||
|
|
||||||
Wed Sep 17 12:23:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
|
Wed Sep 17 12:23:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
* SAX2.c parser.c parserInternals.c xmlreader.c: started messing
|
* SAX2.c parser.c parserInternals.c xmlreader.c: started messing
|
||||||
|
110
SAX2.c
110
SAX2.c
@@ -1564,6 +1564,47 @@ xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
|
|||||||
nodePop(ctxt);
|
nodePop(ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xmlSAX2TextNode:
|
||||||
|
* @ctxt: the parser context
|
||||||
|
* @str: the input string
|
||||||
|
* @len: the string length
|
||||||
|
*
|
||||||
|
* Remove the entities from an attribute value
|
||||||
|
*
|
||||||
|
* Returns the newly allocated string or NULL if not needed or error
|
||||||
|
*/
|
||||||
|
static xmlNodePtr
|
||||||
|
xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
|
||||||
|
xmlNodePtr ret;
|
||||||
|
|
||||||
|
if (ctxt->freeElems != NULL) {
|
||||||
|
ret = ctxt->freeElems;
|
||||||
|
ctxt->freeElems = ret->next;
|
||||||
|
ctxt->freeElemsNr--;
|
||||||
|
memset(ret, 0, sizeof(xmlNode));
|
||||||
|
ret->type = XML_TEXT_NODE;
|
||||||
|
|
||||||
|
ret->name = xmlStringText;
|
||||||
|
ret->content = xmlStrndup(str, len);
|
||||||
|
|
||||||
|
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
|
||||||
|
xmlRegisterNodeDefaultValue(ret);
|
||||||
|
} else {
|
||||||
|
ret = xmlNewTextLen(str, len);
|
||||||
|
}
|
||||||
|
if (ret == NULL) {
|
||||||
|
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
|
||||||
|
ctxt->sax->error(ctxt->userData,
|
||||||
|
"SAX.xmlSAX2Characters(): out of memory\n");
|
||||||
|
ctxt->errNo = XML_ERR_NO_MEMORY;
|
||||||
|
ctxt->instate = XML_PARSER_EOF;
|
||||||
|
ctxt->disableSAX = 1;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xmlSAX2DecodeAttrEntities:
|
* xmlSAX2DecodeAttrEntities:
|
||||||
* @ctxt: the parser context
|
* @ctxt: the parser context
|
||||||
@@ -1630,6 +1671,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
|||||||
if (ctxt->freeAttrs != NULL) {
|
if (ctxt->freeAttrs != NULL) {
|
||||||
ret = ctxt->freeAttrs;
|
ret = ctxt->freeAttrs;
|
||||||
ctxt->freeAttrs = ret->next;
|
ctxt->freeAttrs = ret->next;
|
||||||
|
ctxt->freeAttrsNr--;
|
||||||
memset(ret, 0, sizeof(xmlAttr));
|
memset(ret, 0, sizeof(xmlAttr));
|
||||||
ret->type = XML_ATTRIBUTE_NODE;
|
ret->type = XML_ATTRIBUTE_NODE;
|
||||||
|
|
||||||
@@ -1672,21 +1714,40 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
|||||||
if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
|
if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
|
||||||
xmlNodePtr tmp;
|
xmlNodePtr tmp;
|
||||||
|
|
||||||
ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
|
/*
|
||||||
valueend - value);
|
* We know that if there is an entity reference, then
|
||||||
tmp = ret->children;
|
* the string has been dup'ed and terminates with 0
|
||||||
while (tmp != NULL) {
|
* otherwise with ' or "
|
||||||
tmp->parent = (xmlNodePtr) ret;
|
*/
|
||||||
if (tmp->next == NULL)
|
if (*valueend != 0) {
|
||||||
ret->last = tmp;
|
tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
|
||||||
tmp = tmp->next;
|
ret->children = tmp;
|
||||||
|
ret->last = tmp;
|
||||||
|
if (tmp != NULL) {
|
||||||
|
tmp->doc = ret->doc;
|
||||||
|
tmp->parent = (xmlNodePtr) ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
|
||||||
|
valueend - value);
|
||||||
|
tmp = ret->children;
|
||||||
|
while (tmp != NULL) {
|
||||||
|
tmp->parent = (xmlNodePtr) ret;
|
||||||
|
if (tmp->next == NULL)
|
||||||
|
ret->last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (value != NULL) {
|
} else if (value != NULL) {
|
||||||
ret->children = xmlNewDocTextLen(ctxt->myDoc, value,
|
xmlNodePtr tmp;
|
||||||
valueend - value);
|
|
||||||
ret->last = ret->children;
|
tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
|
||||||
if (ret->children != NULL)
|
ret->children = tmp;
|
||||||
ret->children->parent = (xmlNodePtr) ret;
|
ret->last = tmp;
|
||||||
|
if (tmp != NULL) {
|
||||||
|
tmp->doc = ret->doc;
|
||||||
|
tmp->parent = (xmlNodePtr) ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
|
if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
|
||||||
@@ -1837,6 +1898,7 @@ xmlSAX2StartElementNs(void *ctx,
|
|||||||
if (ctxt->freeElems != NULL) {
|
if (ctxt->freeElems != NULL) {
|
||||||
ret = ctxt->freeElems;
|
ret = ctxt->freeElems;
|
||||||
ctxt->freeElems = ret->next;
|
ctxt->freeElems = ret->next;
|
||||||
|
ctxt->freeElemsNr--;
|
||||||
memset(ret, 0, sizeof(xmlNode));
|
memset(ret, 0, sizeof(xmlNode));
|
||||||
ret->type = XML_ELEMENT_NODE;
|
ret->type = XML_ELEMENT_NODE;
|
||||||
|
|
||||||
@@ -2056,7 +2118,7 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastChild = xmlGetLastChild(ctxt->node);
|
lastChild = ctxt->node->last;
|
||||||
#ifdef DEBUG_SAX_TREE
|
#ifdef DEBUG_SAX_TREE
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
"add chars to %s \n", ctxt->node->name);
|
"add chars to %s \n", ctxt->node->name);
|
||||||
@@ -2067,9 +2129,12 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
|
|||||||
* elements. Use an attribute in the structure !!!
|
* elements. Use an attribute in the structure !!!
|
||||||
*/
|
*/
|
||||||
if (lastChild == NULL) {
|
if (lastChild == NULL) {
|
||||||
/* first node, first time */
|
lastChild = xmlSAX2TextNode(ctxt, ch, len);
|
||||||
xmlNodeAddContentLen(ctxt->node, ch, len);
|
if (lastChild != NULL) {
|
||||||
if (ctxt->node->children != NULL) {
|
ctxt->node->children = lastChild;
|
||||||
|
ctxt->node->last = lastChild;
|
||||||
|
lastChild->parent = ctxt->node;
|
||||||
|
lastChild->doc = ctxt->node->doc;
|
||||||
ctxt->nodelen = len;
|
ctxt->nodelen = len;
|
||||||
ctxt->nodemem = len + 1;
|
ctxt->nodemem = len + 1;
|
||||||
}
|
}
|
||||||
@@ -2122,15 +2187,8 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Mixed content, first time */
|
/* Mixed content, first time */
|
||||||
lastChild = xmlNewTextLen(ch, len);
|
lastChild = xmlSAX2TextNode(ctxt, ch, len);
|
||||||
if (lastChild == NULL) {
|
if (lastChild != NULL) {
|
||||||
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
|
|
||||||
ctxt->sax->error(ctxt->userData,
|
|
||||||
"SAX.xmlSAX2Characters(): out of memory\n");
|
|
||||||
ctxt->errNo = XML_ERR_NO_MEMORY;
|
|
||||||
ctxt->instate = XML_PARSER_EOF;
|
|
||||||
ctxt->disableSAX = 1;
|
|
||||||
} else {
|
|
||||||
xmlAddChild(ctxt->node, lastChild);
|
xmlAddChild(ctxt->node, lastChild);
|
||||||
if (ctxt->node->children != NULL) {
|
if (ctxt->node->children != NULL) {
|
||||||
ctxt->nodelen = len;
|
ctxt->nodelen = len;
|
||||||
|
@@ -267,7 +267,9 @@ struct _xmlParserCtxt {
|
|||||||
* Those fields are needed only for treaming parsing so far
|
* Those fields are needed only for treaming parsing so far
|
||||||
*/
|
*/
|
||||||
int dictNames; /* Use dictionary names for the tree */
|
int dictNames; /* Use dictionary names for the tree */
|
||||||
|
int freeElemsNr; /* number of freed element nodes */
|
||||||
xmlNodePtr freeElems; /* List of freed element nodes */
|
xmlNodePtr freeElems; /* List of freed element nodes */
|
||||||
|
int freeAttrsNr; /* number of freed attributes nodes */
|
||||||
xmlAttrPtr freeAttrs; /* List of freed attributes nodes */
|
xmlAttrPtr freeAttrs; /* List of freed attributes nodes */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
18
xmlreader.c
18
xmlreader.c
@@ -263,9 +263,11 @@ xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
|
|||||||
(xmlDictOwns(reader->ctxt->dict, cur->name) != 1) &&
|
(xmlDictOwns(reader->ctxt->dict, cur->name) != 1) &&
|
||||||
(cur->name != NULL))
|
(cur->name != NULL))
|
||||||
xmlFree((xmlChar *)cur->name);
|
xmlFree((xmlChar *)cur->name);
|
||||||
if ((reader != NULL) && (reader->ctxt != NULL)) {
|
if ((reader != NULL) && (reader->ctxt != NULL) &&
|
||||||
|
(reader->ctxt->freeAttrsNr < 100)) {
|
||||||
cur->next = reader->ctxt->freeAttrs;
|
cur->next = reader->ctxt->freeAttrs;
|
||||||
reader->ctxt->freeAttrs = cur;
|
reader->ctxt->freeAttrs = cur;
|
||||||
|
reader->ctxt->freeAttrsNr++;
|
||||||
} else {
|
} else {
|
||||||
xmlFree(cur);
|
xmlFree(cur);
|
||||||
}
|
}
|
||||||
@@ -347,10 +349,13 @@ xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
|
|||||||
(cur->type != XML_COMMENT_NODE) &&
|
(cur->type != XML_COMMENT_NODE) &&
|
||||||
(cur->name != NULL))
|
(cur->name != NULL))
|
||||||
xmlFree((xmlChar *)cur->name);
|
xmlFree((xmlChar *)cur->name);
|
||||||
if ((cur->type == XML_ELEMENT_NODE) &&
|
if (((cur->type == XML_ELEMENT_NODE) ||
|
||||||
(reader != NULL) && (reader->ctxt != NULL)) {
|
(cur->type == XML_TEXT_NODE)) &&
|
||||||
|
(reader != NULL) && (reader->ctxt != NULL) &&
|
||||||
|
(reader->ctxt->freeElemsNr < 100)) {
|
||||||
cur->next = reader->ctxt->freeElems;
|
cur->next = reader->ctxt->freeElems;
|
||||||
reader->ctxt->freeElems = cur;
|
reader->ctxt->freeElems = cur;
|
||||||
|
reader->ctxt->freeElemsNr++;
|
||||||
} else {
|
} else {
|
||||||
xmlFree(cur);
|
xmlFree(cur);
|
||||||
}
|
}
|
||||||
@@ -414,10 +419,13 @@ xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
|
|||||||
(cur->type != XML_COMMENT_NODE) &&
|
(cur->type != XML_COMMENT_NODE) &&
|
||||||
(cur->name != NULL))
|
(cur->name != NULL))
|
||||||
xmlFree((xmlChar *)cur->name);
|
xmlFree((xmlChar *)cur->name);
|
||||||
if ((cur->type == XML_ELEMENT_NODE) &&
|
if (((cur->type == XML_ELEMENT_NODE) ||
|
||||||
(reader != NULL) && (reader->ctxt != NULL)) {
|
(cur->type == XML_TEXT_NODE)) &&
|
||||||
|
(reader != NULL) && (reader->ctxt != NULL) &&
|
||||||
|
(reader->ctxt->freeElemsNr < 100)) {
|
||||||
cur->next = reader->ctxt->freeElems;
|
cur->next = reader->ctxt->freeElems;
|
||||||
reader->ctxt->freeElems = cur;
|
reader->ctxt->freeElems = cur;
|
||||||
|
reader->ctxt->freeElemsNr++;
|
||||||
} else {
|
} else {
|
||||||
xmlFree(cur);
|
xmlFree(cur);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user