develooper 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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About