summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorLarry Wall <lwall@scalpel.netlabs.com>1995-11-21 10:01:00 +1200
committerLarry <lwall@scalpel.netlabs.com>1995-11-21 10:01:00 +1200
commit4633a7c4bad06b471d9310620b7fe8ddd158cccd (patch)
tree37ebeb26a64f123784fd8fac6243b124767243b0 /hv.c
parent8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f (diff)
downloadperl-4633a7c4bad06b471d9310620b7fe8ddd158cccd.tar.gz
5.002 beta 1
If you're adventurous, have a look at ftp://ftp.sems.com/pub/outgoing/perl5.0/perl5.002beta1.tar.gz Many thanks to Andy for doing the integration. Obviously, if you consult the bugs database, you'll note there are still plenty of buglets that need fixing, and several enhancements that I've intended to put in still haven't made it in (Hi, Tim and Ilya). But I think it'll be pretty stable. And you can start to fiddle around with prototypes (which are, of course, still totally undocumented). Packrats, don't worry too much about readvertising this widely. Nowadays we're on a T1 here, so our bandwidth is okay. Have the appropriate amount of jollity. Larry
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c85
1 files changed, 77 insertions, 8 deletions
diff --git a/hv.c b/hv.c
index 27833f91d2..852ee165a5 100644
--- a/hv.c
+++ b/hv.c
@@ -17,6 +17,44 @@
static void hsplit _((HV *hv));
static void hfreeentries _((HV *hv));
+static HE* more_he();
+
+static HE*
+new_he()
+{
+ HE* he;
+ if (he_root) {
+ he = he_root;
+ he_root = (HE*)he->hent_next;
+ return he;
+ }
+ return more_he();
+}
+
+static void
+del_he(p)
+HE* p;
+{
+ p->hent_next = (HE*)he_root;
+ he_root = p;
+}
+
+static HE*
+more_he()
+{
+ register HE* he;
+ register HE* heend;
+ he_root = (HE*)safemalloc(1008);
+ he = he_root;
+ heend = &he[1008 / sizeof(HE) - 1];
+ while (he < heend) {
+ he->hent_next = (HE*)(he + 1);
+ he++;
+ }
+ he->hent_next = 0;
+ return new_he();
+}
+
SV**
hv_fetch(hv,key,klen,lval)
HV *hv;
@@ -142,8 +180,8 @@ register U32 hash;
entry->hent_val = val;
return &entry->hent_val;
}
- New(501,entry, 1, HE);
+ entry = new_he();
entry->hent_klen = klen;
entry->hent_key = savepvn(key,klen);
entry->hent_val = val;
@@ -282,10 +320,33 @@ HV *hv;
register HE **b;
register HE *entry;
register HE **oentry;
+ I32 tmp;
a = (HE**)xhv->xhv_array;
nomemok = TRUE;
+#ifdef STRANGE_MALLOC
Renew(a, newsize, HE*);
+#else
+ i = newsize * sizeof(HE*);
+#define MALLOC_OVERHEAD 16
+ tmp = MALLOC_OVERHEAD;
+ while (tmp - MALLOC_OVERHEAD < i)
+ tmp += tmp;
+ tmp -= MALLOC_OVERHEAD;
+ tmp /= sizeof(HE*);
+ assert(tmp >= newsize);
+ New(2,a, tmp, HE*);
+ Copy(xhv->xhv_array, a, oldsize, HE*);
+ if (oldsize >= 64 && *(char*)&xhv->xnv_nv == 0) {
+ sv_add_arena((char*)xhv->xhv_array, oldsize * sizeof(HE*), 0);
+ sv_add_arena(((char*)a) + newsize * sizeof(HE*),
+ newsize * sizeof(HE*) - MALLOC_OVERHEAD,
+ SVf_FAKE);
+ }
+ else
+ Safefree(xhv->xhv_array);
+#endif
+
nomemok = FALSE;
Zero(&a[oldsize], oldsize, HE*); /* zero 2nd half*/
xhv->xhv_max = --newsize;
@@ -326,6 +387,7 @@ newHV()
xhv->xhv_max = 7; /* start with 8 buckets */
xhv->xhv_fill = 0;
xhv->xhv_pmroot = 0;
+ *(char*)&xhv->xnv_nv = 0;
(void)hv_iterinit(hv); /* so each() will start off right */
return hv;
}
@@ -338,7 +400,7 @@ register HE *hent;
return;
SvREFCNT_dec(hent->hent_val);
Safefree(hent->hent_key);
- Safefree(hent);
+ del_he(hent);
}
void
@@ -349,7 +411,7 @@ register HE *hent;
return;
sv_2mortal(hent->hent_val); /* free between statements */
Safefree(hent->hent_key);
- Safefree(hent);
+ del_he(hent);
}
void
@@ -413,7 +475,14 @@ HV *hv;
return;
xhv = (XPVHV*)SvANY(hv);
hfreeentries(hv);
+#ifdef STRANGE_MALLOC
Safefree(xhv->xhv_array);
+#else
+ if (xhv->xhv_max < 127 || *(char*)&xhv->xnv_nv)
+ Safefree(xhv->xhv_array);
+ else /* We used last half, so use first half for SV arena too. */
+ sv_add_arena((char*)xhv->xhv_array, (xhv->xhv_max + 1) * sizeof(HE*),0);
+#endif
if (HvNAME(hv)) {
Safefree(HvNAME(hv));
HvNAME(hv) = 0;
@@ -422,6 +491,7 @@ HV *hv;
xhv->xhv_max = 7; /* it's a normal associative array */
xhv->xhv_fill = 0;
xhv->xhv_keys = 0;
+ *(char*)&xhv->xnv_nv = 1;
if (SvRMAGICAL(hv))
mg_clear((SV*)hv);
@@ -461,8 +531,8 @@ HV *hv;
entry->hent_key = 0;
}
else {
- Newz(504,entry, 1, HE);
- xhv->xhv_eiter = entry;
+ xhv->xhv_eiter = entry = new_he();
+ Zero(entry, 1, HE);
}
magic_nextpack((SV*) hv,mg,key);
if (SvOK(key)) {
@@ -475,14 +545,13 @@ HV *hv;
}
if (entry->hent_val)
SvREFCNT_dec(entry->hent_val);
- Safefree(entry);
+ del_he(entry);
xhv->xhv_eiter = Null(HE*);
return Null(HE*);
}
if (!xhv->xhv_array)
- entry = Null(HE*);
- else
+ Newz(506,xhv->xhv_array, sizeof(HE*) * (xhv->xhv_max + 1), char);
do {
if (entry)
entry = entry->hent_next;