summaryrefslogtreecommitdiff
path: root/regexec.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2011-06-28 15:20:56 +0200
committerNicholas Clark <nick@ccl4.org>2011-07-01 14:05:41 +0200
commit72de20cdcc84ae35e0d8a55c7a92950fece19347 (patch)
treefde310b665c99a781df72f0aeab31f0e8ba8225e /regexec.c
parentb606cf7f37b8b46206c7f521b29167e037397a62 (diff)
downloadperl-72de20cdcc84ae35e0d8a55c7a92950fece19347.tar.gz
For shorter strings, store C<study>'s data as U8s or U16s, instead of U32s.
The assumption is that most studied strings are fairly short, hence the pain of the extra code is worth it, given the memory savings. 80 character string, 336 bytes as U8, down from 1344 as U32 800 character string, 2112 bytes as U16, down from 4224 as U32
Diffstat (limited to 'regexec.c')
-rw-r--r--regexec.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/regexec.c b/regexec.c
index 516bf9556c..99ac5b381c 100644
--- a/regexec.c
+++ b/regexec.c
@@ -696,12 +696,22 @@ Perl_re_intuit_start(pTHX_ REGEXP * const rx, SV *sv, char *strpos,
I32 p = -1; /* Internal iterator of scream. */
I32 * const pp = data ? data->scream_pos : &p;
const MAGIC *mg;
+ bool found = FALSE;
assert(SvMAGICAL(sv));
mg = mg_find(sv, PERL_MAGIC_study);
assert(mg);
- if (((U32 *)mg->mg_ptr)[BmRARE(check)] != (U32)~0
+ if (mg->mg_private == 1) {
+ found = ((U8 *)mg->mg_ptr)[BmRARE(check)] != (U8)~0;
+ } else if (mg->mg_private == 2) {
+ found = ((U16 *)mg->mg_ptr)[BmRARE(check)] != (U16)~0;
+ } else {
+ assert (mg->mg_private == 4);
+ found = ((U32 *)mg->mg_ptr)[BmRARE(check)] != (U32)~0;
+ }
+
+ if (found
|| ( BmRARE(check) == '\n'
&& (BmPREVIOUS(check) == SvCUR(check) - 1)
&& SvTAIL(check) ))