Hi,

After the last few changes (including a proposed one), we now have in
the .data segment (i.e. mutable initialized variables):

$ objdump -j .data -t 
~/build/postgres/dev-optimize/vpath/src/backend/postgres|awk '{print $4, $5, 
$6}'|sort -r|lessGreetings,
.data 0000000000004380 ConfigureNamesInt
.data 0000000000003570 ConfigureNamesBool
.data 0000000000002140 ConfigureNamesString
.data 00000000000010e0 ConfigureNamesEnum
.data 0000000000000d20 ConfigureNamesReal

These are by far the largest chunk of the .data segment (like 47152
bytes out of 51168 bytes).  It's not entirely trivial to fix. While we
can slap consts onto large parts of the functions taking a struct
config_generic*, there's a few places where *do* modify them.

ISTM, to actually fix, we'd have to split
struct config_generic
{
        /* constant fields, must be set correctly in initial value: */
        const char *name;                       /* name of variable - MUST BE 
FIRST */
        GucContext      context;                /* context required to set the 
variable */
        enum config_group group;        /* to help organize variables by 
function */
        const char *short_desc;         /* short desc. of this variable's 
purpose */
        const char *long_desc;          /* long desc. of this variable's 
purpose */
        int                     flags;                  /* flag bits, see guc.h 
*/
        /* variable fields, initialized at runtime: */
        enum config_type vartype;       /* type of variable (set only at 
startup) */
        int                     status;                 /* status bits, see 
below */
        GucSource       source;                 /* source of the current actual 
value */
        GucSource       reset_source;   /* source of the reset_value */
        GucContext      scontext;               /* context that set the current 
value */
        GucContext      reset_scontext; /* context that set the reset value */
        GucStack   *stack;                      /* stacked prior values */
        void       *extra;                      /* "extra" pointer for current 
actual value */
        char       *sourcefile;         /* file current setting is from (NULL 
if not
                                                                 * set in 
config file) */
        int                     sourceline;             /* line in source file 
*/
};

into two different arrays. Namely the already denoted 'constant fields'
and 'variable fields.  But it's a bit more complicated than that: The
size doesn't come just from the base config_struct, but also from the
config_{bool,int,real,string,enum} arrays.  Where we again have separate
'constant fields' and 'variable fields'.

So we'd have to refactor more heavily than just splitting the above
array into two.

I kind of wonder, if we shouldn't remove the separate ConfigureNamesInt*
int arrays and change things so we have one

struct config_def
{
        const char *name;                       /* name of variable - MUST BE 
FIRST */
        GucContext      context;                /* context required to set the 
variable */
        enum config_group group;        /* to help organize variables by 
function */
        const char *short_desc;         /* short desc. of this variable's 
purpose */
        const char *long_desc;          /* long desc. of this variable's 
purpose */
        int                     flags;                  /* flag bits, see guc.h 
*/
        enum config_type vartype;       /* type of variable (set only at 
startup) */

        union
        {
                struct
                {
                        bool       *variable;
                        bool            boot_val;
                        GucBoolCheckHook check_hook;
                        GucBoolAssignHook assign_hook;
                        GucShowHook show_hook;
                } config_bool;

                struct
                {
                        int                *variable;
                        int                     boot_val;
                        int                     min;
                        int                     max;
                        GucIntCheckHook check_hook;
                        GucIntAssignHook assign_hook;
                        GucShowHook show_hook;
                } config_int

                ...
        } pertype;
}

and then a corresponding struct config_val with a similar union.

Besides reducing modified memory, it'd also have the benefit of making
the grouping within the various arrays much more sensible, because
related fields could be grouped together.


.data 0000000000000420 intRelOpts
.data 00000000000001c0 realRelOpts
.data 0000000000000118 boolRelOpts
.data 00000000000000a8 stringRelOpts

these should be readonly, but the code doesn't make that easy. There's
pending refactorings, I don't know how they effect this.


.data 0000000000000068 SnapshotSelfData
.data 0000000000000068 SnapshotAnyData
.data 0000000000000068 SecondarySnapshotData
.data 0000000000000068 CurrentSnapshotData
.data 0000000000000068 CatalogSnapshotData

The obviously actually are modifyable.


.data 0000000000000028 spi_printtupDR
.data 0000000000000028 printsimpleDR
.data 0000000000000028 donothingDR
.data 0000000000000028 debugtupDR

These we could actually make constant, but CreateDestReceiver() as an
API makes that inconvenient. They also are pretty darn small...  There's
a security benefit in making them constant and casting the constness
away - I think that might not be insane.


- Andres

Reply via email to