99 lines
3.8 KiB
C
99 lines
3.8 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2012 Fidelity Information Services, Inc *
|
|
* *
|
|
* This source code contains the intellectual property *
|
|
* of its copyright holder(s), and is made available *
|
|
* under a license. If you do not know the terms of *
|
|
* the license, please stop and do not read further. *
|
|
* *
|
|
****************************************************************/
|
|
|
|
#ifndef PARM_POOL_H_INCLUDED
|
|
#define PARM_POOL_H_INCLUDED
|
|
|
|
#ifdef DEBUG
|
|
# define PARM_POOL_INIT_CAP 2 /* Initial debug capacity */
|
|
# define MAX_SET_COUNT 3 /* Max parameter sets stored at one time */
|
|
# define MAX_TOTAL_SLOTS (MAX_SET_COUNT * MAX_ACTUALS) /* Max total slots allowed in the pool */
|
|
#else
|
|
# define PARM_POOL_INIT_CAP 8 /* Initial pro capacity */
|
|
#endif
|
|
|
|
#ifdef GTM64
|
|
# define LV_VALS_PER_SLOT 1 /* 64: number of lv_vals that one slot fits */
|
|
# define SLOTS_NEEDED_FOR_SET(parms) (parms + 2) /* 64: slots needed for params, frame, and mask_and_cnt */
|
|
#else
|
|
# define LV_VALS_PER_SLOT 2 /* 32: number of lv_vals that one slot fits */
|
|
# define SLOTS_NEEDED_FOR_SET(parms) (parms / 2 + 2) /* 32: slots needed for params, frame, and mask_and_cnt.
|
|
* Note that parms / 2 is used instead of (parms + 1) / 2
|
|
* because on 32-bit platforms if the number of params is
|
|
* even, then we need two additional slots for frame and
|
|
* mask_and_cnt; if odd, then the parameter not counted due
|
|
* to integer division will share the same slot with frame
|
|
* field, making this macro still correct */
|
|
#endif
|
|
|
|
/* The first vacant slot */
|
|
#define PARM_CURR_SLOT ((TREF(parm_pool_ptr))->parms + (TREF(parm_pool_ptr))->start_idx)
|
|
|
|
/* Frame field of the previous set */
|
|
#ifdef GTM64
|
|
# define PARM_ACT_FRAME(curr_slot, count) (*(curr_slot - 2)).frame
|
|
#else
|
|
# define PARM_ACT_FRAME(curr_slot, count) (*((&(*(curr_slot - 2)).frame) + ((count % 2) ? 1 : 0)))
|
|
#endif
|
|
|
|
/* This value has to be even, so that when count is increased by this value, it retains its divisibility by two. */
|
|
#define SAFE_TO_OVWRT (((MAX_ACTUALS + 1) % 2 == 0) ? (MAX_ACTUALS + 1) : (MAX_ACTUALS + 2))
|
|
|
|
/* round capacity up to the next power of 2 above or equal to min */
|
|
#define CAPACITY_ROUND_UP2(cap, min) \
|
|
{ \
|
|
while (cap < min) \
|
|
cap <<= 1; \
|
|
}
|
|
|
|
/* Reclaim the space used by the parameter set stored last, because the corresponding frame is being rewound. */
|
|
#define PARM_ACT_UNSTACK_IF_NEEDED \
|
|
{ \
|
|
int count; \
|
|
parm_slot *curr_slot; \
|
|
if (TREF(parm_pool_ptr) && (0 < (TREF(parm_pool_ptr))->start_idx)) \
|
|
{ \
|
|
curr_slot = PARM_CURR_SLOT; \
|
|
count = (*(curr_slot - 1)).mask_and_cnt.actualcnt; \
|
|
if (PARM_ACT_FRAME(curr_slot, count) == frame_pointer) \
|
|
(TREF(parm_pool_ptr))->start_idx \
|
|
-= (SLOTS_NEEDED_FOR_SET(((MAX_ACTUALS < count) \
|
|
? (count - SAFE_TO_OVWRT) : count))); \
|
|
} \
|
|
}
|
|
|
|
typedef union
|
|
{
|
|
struct
|
|
{
|
|
uint4 mask; /* Mask for the param list (alias/non-alias) of up to 32 params */
|
|
unsigned int actualcnt; /* Number of parameters in the parameter set */
|
|
} mask_and_cnt;
|
|
struct stack_frame_struct *frame; /* Pointer to the frame that the parameter set corresponds to */
|
|
lv_val *actuallist; /* On 32-bit platforms this field is 4 bytes, so when the number of
|
|
* parameters is odd, a frame value is stored in the second half of
|
|
* this union; otherwise, frame is stored in a separate slot, thus
|
|
* leaving 4 bytes unused. For details, refer to parm_pool.c.
|
|
*/
|
|
} parm_slot;
|
|
|
|
typedef struct
|
|
{
|
|
uint4 capacity;
|
|
uint4 start_idx;
|
|
parm_slot parms[1];
|
|
} parm_pool;
|
|
|
|
STATICFNDCL void parm_pool_init(unsigned int init_capacity);
|
|
STATICFNDCL void parm_pool_expand(int slots_needed, int slots_copied);
|
|
|
|
#endif /* PARM_POOL_H_INCLUDED */
|