[libxslt] Fix performance regression with xsl:number
- From: Nick Wellnhofer <nwellnhof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxslt] Fix performance regression with xsl:number
- Date: Wed, 19 Jun 2019 12:37:41 +0000 (UTC)
commit 9216d4e5102d257513c39a7f816d2bfbaa5a89e4
Author: Nick Wellnhofer <wellnhofer aevum de>
Date: Wed Jun 19 14:00:26 2019 +0200
Fix performance regression with xsl:number
Commit a846514a disabled the pattern matching cache completely for
`count` and `from` patterns of xsl:number instructions. This caused a
huge performance regression for large documents.
Revert the commit and clear the cache after evaluating an xsl:number.
Closes #16.
doc/symbols.xml | 1 +
libxslt/libxslt.syms | 3 +++
libxslt/numbers.c | 10 ++++++++++
libxslt/pattern.c | 26 ++++++++++++++++++++++----
libxslt/pattern.h | 3 +++
5 files changed, 39 insertions(+), 4 deletions(-)
---
diff --git a/doc/symbols.xml b/doc/symbols.xml
index 502a966d..860b2bbd 100644
--- a/doc/symbols.xml
+++ b/doc/symbols.xml
@@ -321,5 +321,6 @@
</release>
<release version="1.1.34">
<symbol file="xsltInternals">xsltParseStylesheetUser</symbol>
+ <symbol file="pattern">xsltCompMatchClearCache</symbol>
</release>
</symbols>
diff --git a/libxslt/libxslt.syms b/libxslt/libxslt.syms
index 07c0a660..94b1d8aa 100644
--- a/libxslt/libxslt.syms
+++ b/libxslt/libxslt.syms
@@ -504,5 +504,8 @@ LIBXML2_1.1.34 {
# xsltInternals
xsltParseStylesheetUser;
+
+# pattern
+ xsltCompMatchClearCache;
} LIBXML2_1.1.30;
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
index 0a2a51cb..f1ed8846 100644
--- a/libxslt/numbers.c
+++ b/libxslt/numbers.c
@@ -829,6 +829,16 @@ xsltNumberFormat(xsltTransformContextPtr ctxt,
output);
}
}
+
+ /*
+ * Unlike `match` patterns, `count` and `from` patterns can contain
+ * variable references, so we have to clear the pattern match
+ * cache if the "direct" matching algorithm was used.
+ */
+ if (data->countPat != NULL)
+ xsltCompMatchClearCache(ctxt, data->countPat);
+ if (data->fromPat != NULL)
+ xsltCompMatchClearCache(ctxt, data->fromPat);
}
/* Insert number as text node */
xsltCopyTextString(ctxt, ctxt->insert, xmlBufferContent(output), 0);
diff --git a/libxslt/pattern.c b/libxslt/pattern.c
index 32de1b48..fc52b88c 100644
--- a/libxslt/pattern.c
+++ b/libxslt/pattern.c
@@ -113,7 +113,6 @@ struct _xsltCompMatch {
xmlNsPtr *nsList; /* the namespaces in scope */
int nsNr; /* the number of namespaces in scope */
xsltStepOpPtr steps; /* ops for computation */
- int novar; /* doesn't contain variables */
};
typedef struct _xsltParserContext xsltParserContext;
@@ -589,8 +588,7 @@ xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
}
ix = 0;
- if ((parent == NULL) || (node->doc == NULL) || isRVT ||
- (comp->novar == 0))
+ if ((parent == NULL) || (node->doc == NULL) || isRVT)
nocache = 1;
if (nocache == 0) {
@@ -1245,6 +1243,27 @@ xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node,
return(0);
}
+void
+xsltCompMatchClearCache(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp) {
+ xsltStepOpPtr sel;
+ xmlXPathObjectPtr list;
+
+ if ((ctxt == NULL) || (comp == NULL))
+ return;
+
+ sel = &comp->steps[0];
+ list = (xmlXPathObjectPtr) XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra);
+
+ if (list != NULL) {
+ xmlXPathFreeObject(list);
+
+ XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra) = NULL;
+ XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = NULL;
+ XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = 0;
+ XSLT_RUNTIME_EXTRA_FREE(ctxt, sel->lenExtra) = NULL;
+ }
+}
+
/************************************************************************
* *
* Dedicated parser for templates *
@@ -1966,7 +1985,6 @@ xsltCompilePatternInternal(const xmlChar *pattern, xmlDocPtr doc,
j++;
}
element->nsNr = j;
- element->novar = novar;
#ifdef WITH_XSLT_DEBUG_PATTERN
diff --git a/libxslt/pattern.h b/libxslt/pattern.h
index eb21be32..a0991c0c 100644
--- a/libxslt/pattern.h
+++ b/libxslt/pattern.h
@@ -44,6 +44,9 @@ XSLTPUBFUN int XSLTCALL
xsltTestCompMatchList (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xsltCompMatchPtr comp);
+XSLTPUBFUN void XSLTCALL
+ xsltCompMatchClearCache (xsltTransformContextPtr ctxt,
+ xsltCompMatchPtr comp);
XSLTPUBFUN void XSLTCALL
xsltNormalizeCompSteps (void *payload,
void *data,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]