- ary = AvALLOC(av) + AvMAX(av) + 1;
- tmp = newmax - AvMAX(av);
- 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_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;
- tmp = newmax;
- AvALLOC(av)[0] = &PL_sv_undef; /* For the stacks */
- }
- if (AvREAL(av)) {
- while (tmp)
- ary[--tmp] = &PL_sv_undef;
- }
-
- AvARRAY(av) = AvALLOC(av);
- AvMAX(av) = newmax;
- }
+ to_null += newmax - *maxp;
+ *maxp = newmax;
+
+ /* See GH#18014 for discussion of when this might be needed: */
+ if (av == PL_curstack) { /* Oops, grew stack (via av_store()?) */
+ PL_stack_sp = *allocp + (PL_stack_sp - PL_stack_base);
+ PL_stack_base = *allocp;
+ PL_stack_max = PL_stack_base + newmax;
+ }
+ } else { /* there is no SV* array yet */
+ *maxp = key < 3 ? 3 : key;
+ {
+ /* see comment above about newmax+1*/
+ MEM_WRAP_CHECK_s(*maxp, SV*,
+ "Out of memory during array extend");
+ }
+ /* Newxz isn't used below because testing showed it to be slower
+ * than Newx+Zero (also slower than Newx + the previous while
+ * loop) for small arrays, which are very common in perl. */
+ Newx(*allocp, *maxp+1, SV*);
+ /* Stacks require only the first element to be &PL_sv_undef
+ * (set elsewhere). However, since non-stack AVs are likely
+ * to dominate in modern production applications, stacks
+ * don't get any special treatment here. */
+ ary_offset = 0;
+ to_null = *maxp+1;
+ goto zero;
+ }
+
+ if (av && AvREAL(av)) {
+ zero:
+ Zero(*allocp + ary_offset,to_null,SV*);
+ }
+
+ *arrayp = *allocp;