summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2011-05-18 11:45:22 +0100
committerNicholas Clark <nick@ccl4.org>2011-06-11 09:40:03 +0200
commit2bda37bab5fb768caff2b228fda376b75df4815c (patch)
tree8dada944c2255f5bf9415e0872b879137c331b59 /util.c
parent9402563ac1ee6a7649763b93342cb2940addf915 (diff)
downloadperl-2bda37bab5fb768caff2b228fda376b75df4815c.tar.gz
Store the BM table in mg_ptr instead of after SvCUR().
Previously the 256 byte Boyer-Moore table was stored in the buffer of SvPVX() after the raw string by extending the buffer. Given that the scalar is alway upgraded to add PERL_MAGIC_bm magic, to clear the table and other flags, there's no extra memory cost in using mg_ptr in the MAGIC struct to point directly to the table. I believe that this removes the last place in the core that stores data beyond SvCUR().
Diffstat (limited to 'util.c')
-rw-r--r--util.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/util.c b/util.c
index 165e61a918..8c836c2faf 100644
--- a/util.c
+++ b/util.c
@@ -549,6 +549,7 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
STRLEN len;
STRLEN rarest = 0;
U32 frequency = 256;
+ MAGIC *mg;
PERL_ARGS_ASSERT_FBM_COMPILE;
@@ -575,29 +576,45 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
SvIOK_off(sv);
SvNOK_off(sv);
SvVALID_on(sv);
+
+ /* "deep magic", the comment used to add. The use of MAGIC itself isn't
+ really. MAGIC was originally added in 79072805bf63abe5 (perl 5.0 alpha 2)
+ to call SvVALID_off() if the scalar was assigned to.
+
+ The comment itself (and "deeper magic" below) date back to
+ 378cc40b38293ffc (perl 2.0). "deep magic" was an annotation on
+ str->str_pok |= 2;
+ where the magic (presumably) was that the scalar had a BM table hidden
+ inside itself.
+
+ As MAGIC is always present on BMs [in Perl 5 :-)], we can use it to store
+ the table instead of the previous (somewhat hacky) approach of co-opting
+ the string buffer and storing it after the string. */
+
+ assert(!mg_find(sv, PERL_MAGIC_bm));
+ mg = sv_magicext(sv, NULL, PERL_MAGIC_bm, &PL_vtbl_bm, NULL, 0);
+ assert(mg);
+
if (len > 2) {
/* Shorter strings are special-cased in Perl_fbm_instr(), and don't use
the BM table. */
- const unsigned char *sb;
const U8 mlen = (len>255) ? 255 : (U8)len;
+ const unsigned char *const sb = s + len - mlen; /* first char (maybe) */
register U8 *table;
- Sv_Grow(sv, len + 256 + PERL_FBM_TABLE_OFFSET);
- table
- = (unsigned char*)(SvPVX_mutable(sv) + len + PERL_FBM_TABLE_OFFSET);
- s = table - 1 - PERL_FBM_TABLE_OFFSET; /* last char */
+ Newx(table, 256, U8);
memset((void*)table, mlen, 256);
+ mg->mg_ptr = (char *)table;
+ mg->mg_len = 256;
+
+ s += len - 1; /* last char */
i = 0;
- sb = s - mlen + 1; /* first char (maybe) */
while (s >= sb) {
if (table[*s] == mlen)
table[*s] = (U8)i;
s--, i++;
}
- } else {
- Sv_Grow(sv, len + PERL_FBM_TABLE_OFFSET);
}
- sv_magic(sv, NULL, PERL_MAGIC_bm, NULL, 0); /* deep magic */
s = (const unsigned char*)(SvPVX_const(sv)); /* deeper magic */
for (i = 0; i < len; i++) {
@@ -772,8 +789,8 @@ Perl_fbm_instr(pTHX_ unsigned char *big, register unsigned char *bigend, SV *lit
return NULL;
{
- register const unsigned char * const table
- = little + littlelen + PERL_FBM_TABLE_OFFSET;
+ const MAGIC *const mg = mg_find(littlestr, PERL_MAGIC_bm);
+ const unsigned char * const table = (const unsigned char *) mg->mg_ptr;
register const unsigned char *oldlittle;
--littlelen; /* Last char found by table lookup */