diff options
author | Nicholas Clark <nick@ccl4.org> | 2011-05-18 11:45:22 +0100 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2011-06-11 09:40:03 +0200 |
commit | 2bda37bab5fb768caff2b228fda376b75df4815c (patch) | |
tree | 8dada944c2255f5bf9415e0872b879137c331b59 /util.c | |
parent | 9402563ac1ee6a7649763b93342cb2940addf915 (diff) | |
download | perl-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.c | 39 |
1 files changed, 28 insertions, 11 deletions
@@ -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 */ |