summaryrefslogtreecommitdiff
path: root/av.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-08-16 16:46:20 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-08-21 16:51:14 -0700
commit7261499db89d7afd6c64079406dc32f10acfe512 (patch)
treed28b4da71ab3604a3a0b1258a85fe498d1615cef /av.c
parentb70d55581aad461af858eb07a2e80ed5fcc653c1 (diff)
downloadperl-7261499db89d7afd6c64079406dc32f10acfe512.tar.gz
Stop padlists from being AVs
In order to fix a bug, I need to add new fields to padlists. But I cannot easily do that as long as they are AVs. So I have created a new padlist struct. This not only allows me to extend the padlist struct with new members as necessary, but also saves memory, as we now have a three-pointer struct where before we had a whole SV head (3-4 pointers) + XPVAV (5 pointers). This will unfortunately break half of CPAN, but the pad API docs clearly say this: NOTE: this function is experimental and may change or be removed without notice. This would have broken B::Debug, but a patch sent upstream has already been integrated into blead with commit 9d2d23d981.
Diffstat (limited to 'av.c')
-rw-r--r--av.c66
1 files changed, 39 insertions, 27 deletions
diff --git a/av.c b/av.c
index f8f123a04e..e9215f960e 100644
--- a/av.c
+++ b/av.c
@@ -80,23 +80,35 @@ Perl_av_extend(pTHX_ AV *av, I32 key)
arg1);
return;
}
- if (key > AvMAX(av)) {
+ av_extend_guts(av,key,&AvMAX(av),&AvALLOC(av),&AvARRAY(av));
+}
+
+/* The guts of av_extend. *Not* for general use! */
+void
+Perl_av_extend_guts(pTHX_ AV *av, I32 key, SSize_t *maxp, SV ***allocp,
+ SV ***arrayp)
+{
+ dVAR;
+
+ PERL_ARGS_ASSERT_AV_EXTEND_GUTS;
+
+ if (key > *maxp) {
SV** ary;
I32 tmp;
I32 newmax;
- if (AvALLOC(av) != AvARRAY(av)) {
- ary = AvALLOC(av) + AvFILLp(av) + 1;
- tmp = AvARRAY(av) - AvALLOC(av);
- Move(AvARRAY(av), AvALLOC(av), AvFILLp(av)+1, SV*);
- AvMAX(av) += tmp;
- AvARRAY(av) = AvALLOC(av);
+ if (av && *allocp != *arrayp) {
+ ary = *allocp + AvFILLp(av) + 1;
+ tmp = *arrayp - *allocp;
+ Move(*arrayp, *allocp, AvFILLp(av)+1, SV*);
+ *maxp += tmp;
+ *arrayp = *allocp;
if (AvREAL(av)) {
while (tmp)
ary[--tmp] = &PL_sv_undef;
}
- if (key > AvMAX(av) - 10) {
- newmax = key + AvMAX(av);
+ if (key > *maxp - 10) {
+ newmax = key + *maxp;
goto resize;
}
}
@@ -106,7 +118,7 @@ Perl_av_extend(pTHX_ AV *av, I32 key)
"Out of memory during array extend"; /* Duplicated in pp_hot.c */
#endif
- if (AvALLOC(av)) {
+ if (*allocp) {
#if !defined(STRANGE_MALLOC) && !defined(MYMALLOC)
MEM_SIZE bytes;
IV itmp;
@@ -126,17 +138,17 @@ Perl_av_extend(pTHX_ AV *av, I32 key)
memory that might never be read. So, I feel, better to keep
the current lazy system of only writing to it if our caller
has a need for more space. NWC */
- newmax = Perl_safesysmalloc_size((void*)AvALLOC(av)) /
+ newmax = Perl_safesysmalloc_size((void*)*allocp) /
sizeof(const SV *) - 1;
if (key <= newmax)
goto resized;
#endif
- newmax = key + AvMAX(av) / 5;
+ newmax = key + *maxp / 5;
resize:
MEM_WRAP_CHECK_1(newmax+1, SV*, oom_array_extend);
#if defined(STRANGE_MALLOC) || defined(MYMALLOC)
- Renew(AvALLOC(av),newmax+1, SV*);
+ Renew(*allocp,newmax+1, SV*);
#else
bytes = (newmax + 1) * sizeof(const SV *);
#define MALLOC_OVERHEAD 16
@@ -147,38 +159,38 @@ Perl_av_extend(pTHX_ AV *av, I32 key)
itmp /= sizeof(const SV *);
assert(itmp > newmax);
newmax = itmp - 1;
- assert(newmax >= AvMAX(av));
+ assert(newmax >= *maxp);
Newx(ary, newmax+1, SV*);
- Copy(AvALLOC(av), ary, AvMAX(av)+1, SV*);
- Safefree(AvALLOC(av));
- AvALLOC(av) = ary;
+ Copy(*allocp, ary, *maxp+1, SV*);
+ Safefree(*allocp);
+ *allocp = ary;
#endif
#ifdef Perl_safesysmalloc_size
resized:
#endif
- ary = AvALLOC(av) + AvMAX(av) + 1;
- tmp = newmax - AvMAX(av);
+ ary = *allocp + *maxp + 1;
+ tmp = newmax - *maxp;
if (av == PL_curstack) { /* Oops, grew stack (via av_store()?) */
- PL_stack_sp = AvALLOC(av) + (PL_stack_sp - PL_stack_base);
- PL_stack_base = AvALLOC(av);
+ PL_stack_sp = *allocp + (PL_stack_sp - PL_stack_base);
+ PL_stack_base = *allocp;
PL_stack_max = PL_stack_base + newmax;
}
}
else {
newmax = key < 3 ? 3 : key;
MEM_WRAP_CHECK_1(newmax+1, SV*, oom_array_extend);
- Newx(AvALLOC(av), newmax+1, SV*);
- ary = AvALLOC(av) + 1;
+ Newx(*allocp, newmax+1, SV*);
+ ary = *allocp + 1;
tmp = newmax;
- AvALLOC(av)[0] = &PL_sv_undef; /* For the stacks */
+ *allocp[0] = &PL_sv_undef; /* For the stacks */
}
- if (AvREAL(av)) {
+ if (av && AvREAL(av)) {
while (tmp)
ary[--tmp] = &PL_sv_undef;
}
- AvARRAY(av) = AvALLOC(av);
- AvMAX(av) = newmax;
+ *arrayp = *allocp;
+ *maxp = newmax;
}
}
}