Front page | perl.perl5.porters |
Postings from October 2014
RFC removing SVt_NULL, and SVt_IV will be the simplest/smallest type
Thread Next
From:
bulk88
Date:
October 2, 2014 22:03
Subject:
RFC removing SVt_NULL, and SVt_IV will be the simplest/smallest type
Message ID:
BLU436-SMTP100AE27153487D402E16810DFB90@phx.gbl
In further refactoring of sv.c's sv allocation/lifecycle code, I need a
svtype slot for a non SV body but still arena allocated memory block.
Why I'll explain later.
from sv.h
-------------------------------------
typedef enum {
SVt_NULL, /* 0 */
/* BIND was here, before INVLIST replaced it. */
SVt_IV, /* 1 */
SVt_NV, /* 2 */
/* RV was here, before it was merged with IV. */
--------------------------------------
Types have disappeared before in perl's history, so it isn't impossible
to do it. Ever since commit
http://perl5.git.perl.org/perl.git/commitdiff/7b2c381cf37e4e4611c4a864b5d6f7134344e3e6
SVt_IVs dont take any additional memory over SVt_NULL. Also with integer
math heavy code, doing sv_upgrade wont ever been done again to from
SVt_NULL to SVt_IV. Under the proposal"# define new_SV(p) \" will
always create SVt_IVs, and SVt_NULL will be #define to SVt_IV. The
different between a SVt_NULL and a SVt_IV is 1 asm instruction to do"
*sv = 0" vs "reg = (char*)(sv) -16; *sv = reg;".
Why I need the svtype slot.
from sv.c now
/* There is collusion here with sv_clear - sv_clear exits early for SVt_NULL
so never reaches the clause at the end that uses
sv_type_details->body_size
to determine whether to call safefree(). Hence body_size can be set
non-zero to record the size of HEs, without fear of bogus frees. */
#if defined(PERL_IN_HV_C) || defined(PERL_IN_XS_APITEST)
#define HE_SVSLOT SVt_NULL
#endif
static const struct body_details bodies_by_type[]'s first slice is for
SVt_NULL, but HE_SVSLOT claims to be a SVt_NULL.
S_new_he in hv.c uses Perl_more_bodies to make HEs be arena alloced.
Perl_more_bodies is unaware of what struct body_details * is. I want to
make Perl_more_bodies take a struct body_details * or just a svtype enum
constant, so its prototype and machine code overhead (and it is rarely
called compared to quick path when a free block exists) is minimized.
This would mean SVt_NULL/HE_SVSLOT's body_details struct must have a
valid body_size member. It is currently 0. If I change body_size to
non-0, then in sv_upgrade
/* if this is zero, this is a body-less SVt_NULL, SVt_IV/SVt_RV,
and sometimes SVt_NV */
if (old_type_details->body_size) {
/* Note that there is an assumption that all bodies of types that
can be upgraded came from arenas. Only the more complex non-
upgradable types are allowed to be directly malloc()ed. */
assert(old_type_details->arena);
del_body((void*)((char*)old_body + old_type_details->offset),
&PL_body_roots[old_type]);
}
this will execute and SVt_NULL's old body pointer (NULL or uninit, I
dont remember) will be "freed"/mem corruption. Previously the test was
" if (old_type > SVt_IV) {" and not the current "if
(old_type_details->body_size) {" but I changed it since sv_upgrade is
supposed to be table driven and not have hard coded constants vs using
the table, and the transition point between bodyless SV types and arena
body SV types is now variable based on build details
http://perl5.git.perl.org/perl.git/commit/5b306eef3a433a3b83e47635168aa11235246bae
.
An easy but hackish way out would be to a 17th slice to static const
struct body_details bodies_by_type[], and have HE_SVSLOT be a constant
for 16. SV types are still 4 bits long, but the HE body, is a 5 bit
type, which isn't used or ever placed in the SV head/sv_flags, but 5
bits are now used for PL_body_roots. [0] slice of PL_body_roots would
now unused memory. Currently PL_body_roots[SVt_IV] on all builds and
some builds PL_body_roots[SVt_NV] are unused. Also the malloced upper
body types, their PL_body_roots's slices are never used. Should
PL_body_roots be shaved down to match arena's types through CPP+pointer
tricks? (writing to PL_body_roots[0] would cause memory corruption in
the interp then). Remember PL_body_roots is an inline array in the
interp struct.
Another reason for me not wanting HE_SVSLOT to be the 17th slice is the
last half of the svtypes, SVt_REGEXP, SVt_PVGV, SVt_PVLV, SVt_PVAV, etc,
are less rarely created/upgraded than the previous slices/svtypes. HE
are more common than HVs. So HE's struct body_details should be in the
first half for cache reasons.
Thread Next
-
RFC removing SVt_NULL, and SVt_IV will be the simplest/smallest type
by bulk88