Skip to content

Commit d90fb23

Browse files
committed
Refactor match_data() to always use the heap instead of having an initial frames vector on the stack; some consequential adjustmentsneeded.
1 parent e47fc51 commit d90fb23

15 files changed

+334
-258
lines changed

ChangeLog

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ tidied up an untidy #ifdef arrangement in pcre2test.
3232
8. Fixed an issue in the backtracking optimization of character repeats in
3333
JIT. Furthermore optimize star repetitions, not just plus repetitions.
3434

35+
9. Removed the use of an initial backtracking frames vector on the system stack
36+
in pcre2_match() so that it now always uses the heap. (In a multi-thread
37+
environment with very small stacks there had been an issue.) This also is
38+
tidier for JIT matching, which didn't need that vector. The heap vector is now
39+
remembered in the match data block and re-used if that block itself is re-used.
40+
It is freed with the match data block.
41+
42+
10. Adjusted the find_limits code in pcre2test to work with change 9 above.
43+
44+
11. Added find_limits_noheap to pcre2test, because the heap limits are now
45+
different in different environments and so cannot be included in the standard
46+
tests.
47+
3548

3649
Version 10.40 15-April-2022
3750
---------------------------

doc/pcre2api.3

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH PCRE2API 3 "22 April 2022" "PCRE2 10.41"
1+
.TH PCRE2API 3 "27 July 2022" "PCRE2 10.41"
22
.SH NAME
33
PCRE2 - Perl-compatible regular expressions (revised API)
44
.sp
@@ -953,7 +953,7 @@ has its own memory control arrangements (see the
953953
documentation for more details). If the limit is reached, the negative error
954954
code PCRE2_ERROR_HEAPLIMIT is returned. The default limit can be set when PCRE2
955955
is built; if it is not, the default is set very large and is essentially
956-
"unlimited".
956+
unlimited.
957957
.P
958958
A value for the heap limit may also be supplied by an item at the start of a
959959
pattern of the form
@@ -964,18 +964,18 @@ where ddd is a decimal number. However, such a setting is ignored unless ddd is
964964
less than the limit set by the caller of \fBpcre2_match()\fP or, if no such
965965
limit is set, less than the default.
966966
.P
967-
The \fBpcre2_match()\fP function starts out using a 20KiB vector on the system
968-
stack for recording backtracking points. The more nested backtracking points
969-
there are (that is, the deeper the search tree), the more memory is needed.
970-
Heap memory is used only if the initial vector is too small. If the heap limit
971-
is set to a value less than 21 (in particular, zero) no heap memory will be
972-
used. In this case, only patterns that do not have a lot of nested backtracking
973-
can be successfully processed.
967+
The \fBpcre2_match()\fP function always needs some heap memory, so setting a
968+
value of zero guarantees a "heap limit exceeded" error. Details of how
969+
\fBpcre2_match()\fP uses the heap are given in the
970+
.\" HREF
971+
\fBpcre2perform\fP
972+
.\"
973+
documentation.
974974
.P
975-
Similarly, for \fBpcre2_dfa_match()\fP, a vector on the system stack is used
976-
when processing pattern recursions, lookarounds, or atomic groups, and only if
977-
this is not big enough is heap memory used. In this case, too, setting a value
978-
of zero disables the use of the heap.
975+
For \fBpcre2_dfa_match()\fP, a vector on the system stack is used when
976+
processing pattern recursions, lookarounds, or atomic groups, and only if this
977+
is not big enough is heap memory used. In this case, setting a value of zero
978+
disables the use of the heap.
979979
.sp
980980
.nf
981981
.B int pcre2_set_match_limit(pcre2_match_context *\fImcontext\fP,
@@ -1019,10 +1019,10 @@ less than the limit set by the caller of \fBpcre2_match()\fP or
10191019
.fi
10201020
.sp
10211021
This parameter limits the depth of nested backtracking in \fBpcre2_match()\fP.
1022-
Each time a nested backtracking point is passed, a new memory "frame" is used
1022+
Each time a nested backtracking point is passed, a new memory frame is used
10231023
to remember the state of matching at that point. Thus, this parameter
10241024
indirectly limits the amount of memory that is used in a match. However,
1025-
because the size of each memory "frame" depends on the number of capturing
1025+
because the size of each memory frame depends on the number of capturing
10261026
parentheses, the actual memory limit varies from pattern to pattern. This limit
10271027
was more useful in versions before 10.30, where function recursion was used for
10281028
backtracking.
@@ -3162,11 +3162,11 @@ The backtracking match limit was reached.
31623162
.sp
31633163
PCRE2_ERROR_NOMEMORY
31643164
.sp
3165-
If a pattern contains many nested backtracking points, heap memory is used to
3166-
remember them. This error is given when the memory allocation function (default
3167-
or custom) fails. Note that a different error, PCRE2_ERROR_HEAPLIMIT, is given
3168-
if the amount of memory needed exceeds the heap limit. PCRE2_ERROR_NOMEMORY is
3169-
also returned if PCRE2_COPY_MATCHED_SUBJECT is set and memory allocation fails.
3165+
Heap memory is used to remember backgracking points. This error is given when
3166+
the memory allocation function (default or custom) fails. Note that a different
3167+
error, PCRE2_ERROR_HEAPLIMIT, is given if the amount of memory needed exceeds
3168+
the heap limit. PCRE2_ERROR_NOMEMORY is also returned if
3169+
PCRE2_COPY_MATCHED_SUBJECT is set and memory allocation fails.
31703170
.sp
31713171
PCRE2_ERROR_NULL
31723172
.sp
@@ -4027,6 +4027,6 @@ Cambridge, England.
40274027
.rs
40284028
.sp
40294029
.nf
4030-
Last updated: 14 December 2021
4031-
Copyright (c) 1997-2021 University of Cambridge.
4030+
Last updated: 27 July 2022
4031+
Copyright (c) 1997-2022 University of Cambridge.
40324032
.fi

doc/pcre2build.3

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH PCRE2BUILD 3 "08 December 2021" "PCRE2 10.40"
1+
.TH PCRE2BUILD 3 "27 July 2022" "PCRE2 10.41"
22
.SH NAME
33
PCRE2 - Perl-compatible regular expressions (revised API)
44
.
@@ -278,12 +278,11 @@ to the \fBconfigure\fP command. This setting also applies to the
278278
\fBpcre2_dfa_match()\fP matching function, and to JIT matching (though the
279279
counting is done differently).
280280
.P
281-
The \fBpcre2_match()\fP function starts out using a 20KiB vector on the system
282-
stack to record backtracking points. The more nested backtracking points there
283-
are (that is, the deeper the search tree), the more memory is needed. If the
284-
initial vector is not large enough, heap memory is used, up to a certain limit,
285-
which is specified in kibibytes (units of 1024 bytes). The limit can be changed
286-
at run time, as described in the
281+
The \fBpcre2_match()\fP function uses heap memory to record backtracking
282+
points. The more nested backtracking points there are (that is, the deeper the
283+
search tree), the more memory is needed. There is an upper limit, specified in
284+
kibibytes (units of 1024 bytes). This limit can be changed at run time, as
285+
described in the
287286
.\" HREF
288287
\fBpcre2api\fP
289288
.\"
@@ -625,7 +624,7 @@ give a warning.
625624
.sp
626625
.nf
627626
Philip Hazel
628-
University Computing Service
627+
Retired from University Computing Service
629628
Cambridge, England.
630629
.fi
631630
.
@@ -634,6 +633,6 @@ Cambridge, England.
634633
.rs
635634
.sp
636635
.nf
637-
Last updated: 08 December 2021
638-
Copyright (c) 1997-2021 University of Cambridge.
636+
Last updated: 27 July 2022
637+
Copyright (c) 1997-2022 University of Cambridge.
639638
.fi

doc/pcre2grep.1

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH PCRE2GREP 1 "31 August 2021" "PCRE2 10.38"
1+
.TH PCRE2GREP 1 "27 July 2022" "PCRE2 10.41"
22
.SH NAME
33
pcre2grep - a grep with Perl-compatible regular expressions.
44
.SH SYNOPSIS
@@ -516,10 +516,7 @@ counter that is incremented each time around its main processing loop. If the
516516
value set by \fB--match-limit\fP is reached, an error occurs.
517517
.sp
518518
The \fB--heap-limit\fP option specifies, as a number of kibibytes (units of
519-
1024 bytes), the amount of heap memory that may be used for matching. Heap
520-
memory is needed only if matching the pattern requires a significant number of
521-
nested backtracking points to be remembered. This parameter can be set to zero
522-
to forbid the use of heap memory altogether.
519+
1024 bytes), the maximum amount of heap memory that may be used for matching.
523520
.sp
524521
The \fB--depth-limit\fP option limits the depth of nested backtracking points,
525522
which indirectly limits the amount of memory that is used. The amount of memory
@@ -960,6 +957,6 @@ Cambridge, England.
960957
.rs
961958
.sp
962959
.nf
963-
Last updated: 31 August 2021
964-
Copyright (c) 1997-2021 University of Cambridge.
960+
Last updated: 27 July 2022
961+
Copyright (c) 1997-2022 University of Cambridge.
965962
.fi

doc/pcre2limits.3

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH PCRE2LIMITS 3 "03 February 2019" "PCRE2 10.33"
1+
.TH PCRE2LIMITS 3 "26 July 2022" "PCRE2 10.41"
22
.SH NAME
33
PCRE2 - Perl-compatible regular expressions (revised API)
44
.SH "SIZE AND OTHER LIMITATIONS"
@@ -51,14 +51,18 @@ is 255 code units for the 8-bit library and 65535 code units for the 16-bit and
5151
.P
5252
The maximum length of a string argument to a callout is the largest number a
5353
32-bit unsigned integer can hold.
54+
.P
55+
The maximum amount of heap memory used for matching is controlled by the heap
56+
limit, which can be set in a pattern or in a match context. The default is a
57+
very large number, effectively unlimited.
5458
.
5559
.
5660
.SH AUTHOR
5761
.rs
5862
.sp
5963
.nf
6064
Philip Hazel
61-
University Computing Service
65+
Retired from University Computing Service
6266
Cambridge, England.
6367
.fi
6468
.
@@ -67,6 +71,6 @@ Cambridge, England.
6771
.rs
6872
.sp
6973
.nf
70-
Last updated: 02 February 2019
71-
Copyright (c) 1997-2019 University of Cambridge.
74+
Last updated: 26 July 2022
75+
Copyright (c) 1997-2022 University of Cambridge.
7276
.fi

doc/pcre2perform.3

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH PCRE2PERFORM 3 "03 February 2019" "PCRE2 10.33"
1+
.TH PCRE2PERFORM 3 "27 July 2022" "PCRE2 10.41"
22
.SH NAME
33
PCRE2 - Perl-compatible regular expressions (revised API)
44
.SH "PCRE2 PERFORMANCE"
@@ -69,12 +69,28 @@ From release 10.30, the interpretive (non-JIT) version of \fBpcre2_match()\fP
6969
uses very little system stack at run time. In earlier releases recursive
7070
function calls could use a great deal of stack, and this could cause problems,
7171
but this usage has been eliminated. Backtracking positions are now explicitly
72-
remembered in memory frames controlled by the code. An initial 20KiB vector of
73-
frames is allocated on the system stack (enough for about 100 frames for small
74-
patterns), but if this is insufficient, heap memory is used. The amount of heap
75-
memory can be limited; if the limit is set to zero, only the initial stack
76-
vector is used. Rewriting patterns to be time-efficient, as described below,
77-
may also reduce the memory requirements.
72+
remembered in memory frames controlled by the code.
73+
.P
74+
The size of each frame depends on the size of pointer variables and the number
75+
of capturing parenthesized groups in the pattern being matched. On a 64-bit
76+
system the frame size for a pattern with no captures is 128 bytes. For each
77+
capturing group the size increases by 16 bytes.
78+
.P
79+
Until release 10.41, an initial 20KiB frames vector was allocated on the system
80+
stack, but this still caused some issues for multi-thread applications where
81+
each thread has a very small stack. From release 10.41 backtracking memory
82+
frames are always held in heap memory. An initial heap allocation is obtained
83+
the first time any match data block is passed to \fBpcre2_match()\fP. This is
84+
remembered with the match data block and re-used if that block is used for
85+
another match. It is freed when the match data block itself is freed.
86+
.P
87+
The size of the initial block is the larger of 20KiB or ten times the pattern's
88+
frame size, unless the heap limit is less than this, in which case the heap
89+
limit is used. If the initial block proves to be too small during matching, it
90+
is replaced by a larger block, subject to the heap limit. The heap limit is
91+
checked only when a new block is to be allocated. Reducing the heap limit
92+
between calls to \fBpcre2_match()\fP with the same match data block does not
93+
affect the saved block.
7894
.P
7995
In contrast to \fBpcre2_match()\fP, \fBpcre2_dfa_match()\fP does use recursive
8096
function calls, but only for processing atomic groups, lookaround assertions,
@@ -230,7 +246,7 @@ pattern to match. This is done by repeatedly matching with different limits.
230246
.sp
231247
.nf
232248
Philip Hazel
233-
University Computing Service
249+
Retired from University Computing Service
234250
Cambridge, England.
235251
.fi
236252
.
@@ -239,6 +255,6 @@ Cambridge, England.
239255
.rs
240256
.sp
241257
.nf
242-
Last updated: 03 February 2019
243-
Copyright (c) 1997-2019 University of Cambridge.
258+
Last updated: 27 July 2022
259+
Copyright (c) 1997-2022 University of Cambridge.
244260
.fi

doc/pcre2test.1

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH PCRE2TEST 1 "12 January 2022" "PCRE 10.40"
1+
.TH PCRE2TEST 1 "27 July 2022" "PCRE 10.41"
22
.SH NAME
33
pcre2test - a program for testing Perl-compatible regular expressions.
44
.SH SYNOPSIS
@@ -1206,7 +1206,8 @@ pattern, but can be overridden by modifiers on the subject.
12061206
copy=<number or name> copy captured substring
12071207
depth_limit=<n> set a depth limit
12081208
dfa use \fBpcre2_dfa_match()\fP
1209-
find_limits find match and depth limits
1209+
find_limits find heap, match and depth limits
1210+
find_limits_noheap find match and depth limits
12101211
get=<number or name> extract captured substring
12111212
getall extract all captured substrings
12121213
/g global global matching
@@ -1528,7 +1529,7 @@ value that was set on the pattern.
15281529
.sp
15291530
The \fBheap_limit\fP, \fBmatch_limit\fP, and \fBdepth_limit\fP modifiers set
15301531
the appropriate limits in the match context. These values are ignored when the
1531-
\fBfind_limits\fP modifier is specified.
1532+
\fBfind_limits\fP or \fBfind_limits_noheap\fP modifier is specified.
15321533
.
15331534
.
15341535
.SS "Finding minimum limits"
@@ -1538,8 +1539,12 @@ If the \fBfind_limits\fP modifier is present on a subject line, \fBpcre2test\fP
15381539
calls the relevant matching function several times, setting different values in
15391540
the match context via \fBpcre2_set_heap_limit()\fP,
15401541
\fBpcre2_set_match_limit()\fP, or \fBpcre2_set_depth_limit()\fP until it finds
1541-
the minimum values for each parameter that allows the match to complete without
1542-
error. If JIT is being used, only the match limit is relevant.
1542+
the smallest value for each parameter that allows the match to complete without
1543+
a "limit exceeded" error. The match itself may succeed or fail. An alternative
1544+
modifier, \fBfind_limits_noheap\fP, omits the heap limit. This is used in the
1545+
standard tests, because the minimum heap limit varies between systems. If JIT
1546+
is being used, only the match limit is relevant, and the other two are
1547+
automatically omitted.
15431548
.P
15441549
When using this modifier, the pattern should not contain any limit settings
15451550
such as (*LIMIT_MATCH=...) within it. If such a setting is present and is
@@ -1563,9 +1568,7 @@ and non-recursive, to the internal matching function, thus controlling the
15631568
overall amount of computing resource that is used.
15641569
.P
15651570
For both kinds of matching, the \fIheap_limit\fP number, which is in kibibytes
1566-
(units of 1024 bytes), limits the amount of heap memory used for matching. A
1567-
value of zero disables the use of any heap memory; many simple pattern matches
1568-
can be done without using the heap, so zero is not an unreasonable setting.
1571+
(units of 1024 bytes), limits the amount of heap memory used for matching.
15691572
.
15701573
.
15711574
.SS "Showing MARK names"
@@ -1584,12 +1587,10 @@ is added to the non-match message.
15841587
.sp
15851588
The \fBmemory\fP modifier causes \fBpcre2test\fP to log the sizes of all heap
15861589
memory allocation and freeing calls that occur during a call to
1587-
\fBpcre2_match()\fP or \fBpcre2_dfa_match()\fP. These occur only when a match
1588-
requires a bigger vector than the default for remembering backtracking points
1589-
(\fBpcre2_match()\fP) or for internal workspace (\fBpcre2_dfa_match()\fP). In
1590-
many cases there will be no heap memory used and therefore no additional
1591-
output. No heap memory is allocated during matching with JIT, so in that case
1592-
the \fBmemory\fP modifier never has any effect. For this modifier to work, the
1590+
\fBpcre2_match()\fP or \fBpcre2_dfa_match()\fP. In the latter case, heap memory
1591+
is used only when a match requires more internal workspace that the default
1592+
allocation on the stack, so in many cases there will be no output. No heap
1593+
memory is allocated during matching with JIT. For this modifier to work, the
15931594
\fBnull_context\fP modifier must not be set on both the pattern and the
15941595
subject, though it can be set on one or the other.
15951596
.
@@ -1649,7 +1650,8 @@ Normally, \fBpcre2test\fP passes a context block to \fBpcre2_match()\fP,
16491650
If the \fBnull_context\fP modifier is set, however, NULL is passed. This is for
16501651
testing that the matching and substitution functions behave correctly in this
16511652
case (they use default values). This modifier cannot be used with the
1652-
\fBfind_limits\fP or \fBsubstitute_callout\fP modifiers.
1653+
\fBfind_limits\fP, \fBfind_limits_noheap\fP, or \fBsubstitute_callout\fP
1654+
modifiers.
16531655
.P
16541656
Similarly, for testing purposes, if the \fBnull_subject\fP or
16551657
\fBnull_replacement\fP modifier is set, the subject or replacement string
@@ -2119,6 +2121,6 @@ Cambridge, England.
21192121
.rs
21202122
.sp
21212123
.nf
2122-
Last updated: 12 January 2022
2124+
Last updated: 27 July 2022
21232125
Copyright (c) 1997-2022 University of Cambridge.
21242126
.fi

src/pcre2_internal.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -220,18 +220,17 @@ not rely on this. */
220220

221221
#define COMPILE_ERROR_BASE 100
222222

223-
/* The initial frames vector for remembering backtracking points in
224-
pcre2_match() is allocated on the system stack, of this size (bytes). The size
225-
must be a multiple of sizeof(PCRE2_SPTR) in all environments, so making it a
226-
multiple of 8 is best. Typical frame sizes are a few hundred bytes (it depends
227-
on the number of capturing parentheses) so 20KiB handles quite a few frames. A
228-
larger vector on the heap is obtained for patterns that need more frames. The
229-
maximum size of this can be limited. */
223+
/* The initial frames vector for remembering pcre2_match() backtracking points
224+
is allocated on the heap, of this size (bytes) or ten times the frame size if
225+
larger, unless the heap limit is smaller. Typical frame sizes are a few hundred
226+
bytes (it depends on the number of capturing parentheses) so 20KiB handles
227+
quite a few frames. A larger vector on the heap is obtained for matches that
228+
need more frames, subject to the heap limit. */
230229

231230
#define START_FRAMES_SIZE 20480
232231

233-
/* Similarly, for DFA matching, an initial internal workspace vector is
234-
allocated on the stack. */
232+
/* For DFA matching, an initial internal workspace vector is allocated on the
233+
stack. The heap is used only if this turns out to be too small. */
235234

236235
#define DFA_START_RWS_SIZE 30720
237236

0 commit comments

Comments
 (0)