From 1f1dcfb516e063c29a4b9823ad97b1fc58ffc930 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Sun, 21 Jan 2018 21:55:00 -0800 Subject: =?UTF-8?q?=E2=80=98Nonelems=E2=80=99=20for=20pushing=20sparse=20a?= =?UTF-8?q?rray=20on=20the=20stack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid having to create deferred elements every time a sparse array is pushed on to the stack, store a magic scalar in the array itself, which av_exists and refto recognise as not existing. This means there is only a one-time cost for putting such arrays on the stack. It also means that deferred elements that live long enough don’t start pointing to the wrong array entry if the array gets shifted (or unshifted/spliced) in the mean time. Instead, the scalar is already in the array, so it cannot lose its place. This fix only applies when the array as a whole is pushed on to the stack, but it could be extended in future commits to apply to other places where we currently use deferred elements. --- mg_vtable.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'mg_vtable.h') diff --git a/mg_vtable.h b/mg_vtable.h index c71a988cf7..e4f3f3889d 100644 --- a/mg_vtable.h +++ b/mg_vtable.h @@ -52,6 +52,7 @@ #define PERL_MAGIC_vec 'v' /* vec() lvalue */ #define PERL_MAGIC_utf8 'w' /* Cached UTF-8 information */ #define PERL_MAGIC_substr 'x' /* substr() lvalue */ +#define PERL_MAGIC_nonelem 'Y' /* Array element that does not exist */ #define PERL_MAGIC_defelem 'y' /* Shadow "foreach" iterator variable / smart parameter vivification */ #define PERL_MAGIC_lvref '\\' /* Lvalue reference constructor */ @@ -76,6 +77,7 @@ enum { /* pass one of these to get_vtbl */ want_vtbl_lvref, want_vtbl_mglob, want_vtbl_nkeys, + want_vtbl_nonelem, want_vtbl_ovrld, want_vtbl_pack, want_vtbl_packelem, @@ -112,6 +114,7 @@ EXTCONST char * const PL_magic_vtable_names[magic_vtable_max] = { "lvref", "mglob", "nkeys", + "nonelem", "ovrld", "pack", "packelem", @@ -171,6 +174,7 @@ EXT_MGVTBL PL_magic_vtables[magic_vtable_max] = { { 0, Perl_magic_setlvref, 0, 0, 0, 0, 0, 0 }, { 0, Perl_magic_setmglob, 0, 0, 0, 0, 0, 0 }, { Perl_magic_getnkeys, Perl_magic_setnkeys, 0, 0, 0, 0, 0, 0 }, + { 0, Perl_magic_setnonelem, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, Perl_magic_freeovrld, 0, 0, 0 }, { 0, 0, Perl_magic_sizepack, Perl_magic_wipepack, 0, 0, 0, 0 }, { Perl_magic_getpack, Perl_magic_setpack, 0, Perl_magic_clearpack, 0, 0, 0, 0 }, @@ -216,6 +220,7 @@ EXT_MGVTBL PL_magic_vtables[magic_vtable_max]; #define PL_vtbl_lvref PL_magic_vtables[want_vtbl_lvref] #define PL_vtbl_mglob PL_magic_vtables[want_vtbl_mglob] #define PL_vtbl_nkeys PL_magic_vtables[want_vtbl_nkeys] +#define PL_vtbl_nonelem PL_magic_vtables[want_vtbl_nonelem] #define PL_vtbl_ovrld PL_magic_vtables[want_vtbl_ovrld] #define PL_vtbl_pack PL_magic_vtables[want_vtbl_pack] #define PL_vtbl_packelem PL_magic_vtables[want_vtbl_packelem] -- cgit v1.2.1