summaryrefslogtreecommitdiffstats
path: root/patches/source/perl/hv.c
diff options
context:
space:
mode:
Diffstat (limited to 'patches/source/perl/hv.c')
-rw-r--r--patches/source/perl/hv.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/patches/source/perl/hv.c b/patches/source/perl/hv.c
new file mode 100644
index 000000000..71819e9bd
--- /dev/null
+++ b/patches/source/perl/hv.c
@@ -0,0 +1,61 @@
+X-Git-Url: http://perl5.git.perl.org/perl.git/blobdiff_plain/ca8de220718ba91d5a5fdd9779497cd5b0250258..f14269908e5f8b4cab4b55643d7dd9de577e7918:/hv.c
+
+diff --git a/hv.c b/hv.c
+index 5d0f2f8..6bfedd5 100644
+--- a/hv.c
++++ b/hv.c
+@@ -35,7 +35,8 @@ holds the key and hash value.
+ #define PERL_HASH_INTERNAL_ACCESS
+ #include "perl.h"
+
+-#define HV_MAX_LENGTH_BEFORE_SPLIT 14
++#define HV_MAX_LENGTH_BEFORE_REHASH 14
++#define SHOULD_DO_HSPLIT(xhv) ((xhv)->xhv_keys > (xhv)->xhv_max) /* HvTOTALKEYS(hv) > HvMAX(hv) */
+
+ static const char S_strtab_error[]
+ = "Cannot modify shared string table in hv_%s";
+@@ -818,23 +819,8 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
+ xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */
+ if (!counter) { /* initial entry? */
+ xhv->xhv_fill++; /* HvFILL(hv)++ */
+- } else if (xhv->xhv_keys > (IV)xhv->xhv_max) {
++ } else if ( SHOULD_DO_HSPLIT(xhv) ) {
+ hsplit(hv);
+- } else if(!HvREHASH(hv)) {
+- U32 n_links = 1;
+-
+- while ((counter = HeNEXT(counter)))
+- n_links++;
+-
+- if (n_links > HV_MAX_LENGTH_BEFORE_SPLIT) {
+- /* Use only the old HvKEYS(hv) > HvMAX(hv) condition to limit
+- bucket splits on a rehashed hash, as we're not going to
+- split it again, and if someone is lucky (evil) enough to
+- get all the keys in one list they could exhaust our memory
+- as we repeatedly double the number of buckets on every
+- entry. Linear search feels a less worse thing to do. */
+- hsplit(hv);
+- }
+ }
+ }
+
+@@ -1180,7 +1166,7 @@ S_hsplit(pTHX_ HV *hv)
+
+
+ /* Pick your policy for "hashing isn't working" here: */
+- if (longest_chain <= HV_MAX_LENGTH_BEFORE_SPLIT /* split worked? */
++ if (longest_chain <= HV_MAX_LENGTH_BEFORE_REHASH /* split worked? */
+ || HvREHASH(hv)) {
+ return;
+ }
+@@ -2506,8 +2492,8 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags)
+ xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */
+ if (!next) { /* initial entry? */
+ xhv->xhv_fill++; /* HvFILL(hv)++ */
+- } else if (xhv->xhv_keys > (IV)xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */) {
+- hsplit(PL_strtab);
++ } else if ( SHOULD_DO_HSPLIT(xhv) ) {
++ hsplit(PL_strtab);
+ }
+ }
+