Commit aaa42564 authored by Matthias Braun's avatar Matthias Braun
Browse files

array: Cleanup

parent dfebb000
......@@ -24,6 +24,101 @@
* @{
*/
/** @cond PRIVATE */
/** A type that has most constrained alignment. */
typedef union {
long double d;
void *p;
long l;
} aligned_type;
/**
* The array descriptor header type.
*/
typedef struct {
int magic; /**< array magic. */
size_t allocated; /**< number of allocated elements. */
size_t nelts; /**< current length of the array. */
aligned_type elts[]; /**< start of the array data. */
} ir_arr_descr;
extern ir_arr_descr arr_mt_descr;
/**
* Creates a flexible array.
*
* @param nelts The number of elements
* @param elts_size The size of the array elements.
*
* @return A pointer to the flexible array (can be used as a pointer to the
* first element of this array).
*
* @remark Helper function, use NEW_ARR_F() instead.
*/
FIRM_API void *ir_new_arr_f(size_t nelts, size_t elts_size);
/**
* Creates a dynamic array on a obstack.
*
* @param obstack An struct obstack * were the data will be allocated
* @param nelts The number of elements
* @param elts_size The size of the array elements.
*
* @return A pointer to the dynamic array (can be used as a pointer to the
* first element of this array).
*
* @remark Helper function, use NEW_ARR_D() instead.
*/
FIRM_API void *ir_new_arr_d(struct obstack *obstack, size_t nelts, size_t elts_size);
/**
* Resize a flexible array, allocate more data if needed but do NOT
* reduce.
*
* @param elts The flexible array (pointer to the first element).
* @param nelts The new number of elements.
* @param eltsize The size of the array elements.
*
* @return A resized flexible array, possibly other address than
* elts.
*
* @remark Helper function, use ARR_RESIZE() instead.
*/
FIRM_API void *ir_arr_resize(void *elts, size_t nelts, size_t elts_size);
/**
* Resize a flexible array, always reallocate data.
*
* @param elts The flexible array (pointer to the first element).
* @param nelts The new number of elements.
* @param elts_size The size of the array elements.
*
* @return A resized flexible array, possibly other address than
* elts.
*
* @remark Helper function, use ARR_SETLEN() instead.
*/
FIRM_API void *ir_arr_setlen(void *elts, size_t nelts, size_t elts_size);
FIRM_API void ir_verify_arr(const void *elts);
#define ARR_ELTS_OFFS offsetof(ir_arr_descr, elts)
#define ARR_DESCR(elts) ((ir_arr_descr *)(void *)((char *)(elts) - ARR_ELTS_OFFS))
/** Set a length smaller than the current length of the array. Do not
* resize. len must be <= ARR_LEN(arr). */
static inline void ARR_SHRINKLEN(void *arr, size_t new_len)
{
#ifndef NDEBUG
ir_verify_arr(arr);
#endif
assert(ARR_DESCR(arr)->nelts >= new_len);
ARR_DESCR(arr)->nelts = new_len;
}
/** @endcond */
/**
* Creates a flexible array.
*
......@@ -65,7 +160,7 @@
*
* @param arr The flexible array.
*/
#define DEL_ARR_F(arr) (ir_del_arr_f((void *)(arr)))
FIRM_API void DEL_ARR_F(void *elts);
/**
* Creates a dynamic array on an obstack.
......@@ -112,7 +207,13 @@
*
* @param arr a flexible, dynamic, automatic or static array.
*/
#define ARR_LEN(arr) (ARR_VRFY((arr)), ARR_DESCR((arr))->nelts)
static inline size_t ARR_LEN(void const *const arr)
{
#ifndef NDEBUG
ir_verify_arr(arr);
#endif
return ARR_DESCR(arr)->nelts;
}
/**
* Resize a flexible array, allocate more data if needed but do NOT
......@@ -176,119 +277,6 @@
#define ARR_APP1(type, arr, elt) \
(ARR_EXTEND(type, (arr), 1), (arr)[ARR_LEN((arr))-1] = (elt))
#ifdef NDEBUG
# define ARR_VRFY(arr) ((void)0)
# define ARR_IDX_VRFY(arr, idx) ((void)0)
#else
/** Check array for consistency */
# define ARR_VRFY(arr) ir_verify_arr(arr)
/** Check if index is within array bounds */
# define ARR_IDX_VRFY(arr, idx) \
assert((0 <= (idx)) && ((idx) < ARR_LEN((arr))))
#endif
/** @cond PRIVATE */
/** A type that has most constrained alignment. */
typedef union {
long double d;
void *p;
long l;
} aligned_type;
/**
* The array descriptor header type.
*/
typedef struct {
int magic; /**< array magic. */
size_t allocated; /**< number of allocated elements. */
size_t nelts; /**< current length of the array. */
aligned_type elts[1]; /**< start of the array data. */
} ir_arr_descr;
extern ir_arr_descr arr_mt_descr;
/**
* Creates a flexible array.
*
* @param nelts The number of elements
* @param elts_size The size of the array elements.
*
* @return A pointer to the flexible array (can be used as a pointer to the
* first element of this array).
*
* @remark Helper function, use NEW_ARR_F() instead.
*/
FIRM_API void *ir_new_arr_f(size_t nelts, size_t elts_size);
/**
* Delete a flexible array.
*
* @param elts The flexible array (pointer to the first element).
*
* @remark Helper function, use DEL_ARR_F() instead.
*/
FIRM_API void ir_del_arr_f(void *elts);
/**
* Creates a dynamic array on a obstack.
*
* @param obstack An struct obstack * were the data will be allocated
* @param nelts The number of elements
* @param elts_size The size of the array elements.
*
* @return A pointer to the dynamic array (can be used as a pointer to the
* first element of this array).
*
* @remark Helper function, use NEW_ARR_D() instead.
*/
FIRM_API void *ir_new_arr_d(struct obstack *obstack, size_t nelts, size_t elts_size);
/**
* Resize a flexible array, allocate more data if needed but do NOT
* reduce.
*
* @param elts The flexible array (pointer to the first element).
* @param nelts The new number of elements.
* @param eltsize The size of the array elements.
*
* @return A resized flexible array, possibly other address than
* elts.
*
* @remark Helper function, use ARR_RESIZE() instead.
*/
FIRM_API void *ir_arr_resize(void *elts, size_t nelts, size_t elts_size);
/**
* Resize a flexible array, always reallocate data.
*
* @param elts The flexible array (pointer to the first element).
* @param nelts The new number of elements.
* @param elts_size The size of the array elements.
*
* @return A resized flexible array, possibly other address than
* elts.
*
* @remark Helper function, use ARR_SETLEN() instead.
*/
FIRM_API void *ir_arr_setlen(void *elts, size_t nelts, size_t elts_size);
FIRM_API void ir_verify_arr(const void *elts);
#define ARR_ELTS_OFFS offsetof(ir_arr_descr, elts)
#define ARR_DESCR(elts) ((ir_arr_descr *)(void *)((char *)(elts) - ARR_ELTS_OFFS))
/** Set a length smaller than the current length of the array. Do not
* resize. len must be <= ARR_LEN(arr). */
static inline void ARR_SHRINKLEN(void *arr, size_t new_len)
{
ARR_VRFY(arr);
assert(ARR_DESCR(arr)->nelts >= new_len);
ARR_DESCR(arr)->nelts = new_len;
}
/** @endcond */
/** @} */
#include "../end.h"
......
......@@ -18,14 +18,6 @@
#define ARR_D_MAGIC FOURCC('A','R','R','D')
#define ARR_F_MAGIC FOURCC('A','R','R','F')
#ifdef NDEBUG
# define ARR_SET_DBGINF(descr, co) \
((void)(descr), (void)(co), (void)0)
#else
# define ARR_SET_DBGINF(descr, co) \
((descr)->magic = (co))
#endif
/**
* An empty dynamic array descriptor.
*/
......@@ -34,7 +26,7 @@ ir_arr_descr arr_mt_descr = { ARR_D_MAGIC, 0, 0, { { 0 } } };
void ir_verify_arr(const void *arr)
{
#ifndef NDEBUG
ir_arr_descr *descr = ARR_DESCR(arr);
ir_arr_descr *const descr = ARR_DESCR(arr);
assert(descr->magic == ARR_D_MAGIC || descr->magic == ARR_F_MAGIC);
assert(descr->allocated >= descr->nelts);
#else
......@@ -44,68 +36,65 @@ void ir_verify_arr(const void *arr)
void *ir_new_arr_d(struct obstack *obstack, size_t nelts, size_t elts_size)
{
ir_arr_descr *dp;
assert(obstack);
dp = (ir_arr_descr*)obstack_alloc(obstack, ARR_ELTS_OFFS + elts_size);
ARR_SET_DBGINF(dp, ARR_D_MAGIC);
ir_arr_descr *const dp
= (ir_arr_descr*)obstack_alloc(obstack, sizeof(*dp) + elts_size);
#ifndef NDEBUG
dp->magic = ARR_D_MAGIC;
#endif
dp->allocated = dp->nelts = nelts;
return dp->elts;
}
void *ir_new_arr_f(size_t nelts, size_t elts_size)
{
ir_arr_descr *newa;
newa = (ir_arr_descr*)xmalloc(ARR_ELTS_OFFS+elts_size);
ARR_SET_DBGINF(newa, ARR_F_MAGIC);
newa->allocated = newa->nelts = nelts;
return newa->elts;
ir_arr_descr *const dp = (ir_arr_descr*)xmalloc(sizeof(*dp)+elts_size);
#ifndef NDEBUG
dp->magic = ARR_F_MAGIC;
#endif
dp->allocated = dp->nelts = nelts;
return dp->elts;
}
void ir_del_arr_f(void *elts)
void DEL_ARR_F(void *elts)
{
ir_arr_descr *dp = ARR_DESCR (elts);
ir_verify_arr(elts);
ARR_VRFY(elts);
ir_arr_descr *const dp = ARR_DESCR(elts);
assert(dp->magic == ARR_F_MAGIC);
#ifndef NDEBUG
dp->magic = 0xdeadbeef;
#endif
free(dp);
}
void *ir_arr_setlen (void *elts, size_t nelts, size_t elts_size)
void *ir_arr_setlen(void *elts, size_t nelts, size_t elts_size)
{
ir_arr_descr *dp = ARR_DESCR (elts);
ir_verify_arr(elts);
ir_arr_descr *dp = ARR_DESCR(elts);
assert(dp->magic == ARR_F_MAGIC);
ARR_VRFY(elts);
dp = (ir_arr_descr*) xrealloc(dp, ARR_ELTS_OFFS+elts_size);
dp = (ir_arr_descr*)xrealloc(dp, sizeof(*dp)+elts_size);
dp->allocated = dp->nelts = nelts;
return dp->elts;
}
void *ir_arr_resize(void *elts, size_t nelts, size_t eltsize)
{
ir_arr_descr *dp = ARR_DESCR(elts);
size_t n;
ir_verify_arr(elts);
ir_arr_descr *dp = ARR_DESCR(elts);
assert(dp->magic == ARR_F_MAGIC);
ARR_VRFY(elts);
/* @@@ lots of resizes for small nelts */
n = MAX(1, dp->allocated);
while (nelts > n) n <<= 1;
while (3*nelts < n) n >>= 1;
size_t n = MAX(1, dp->allocated);
while (nelts > n)
n <<= 1;
while (3*nelts < n)
n >>= 1;
assert(n >= nelts);
if (n != dp->allocated) {
dp = (ir_arr_descr*) xrealloc(dp, ARR_ELTS_OFFS+eltsize*n);
dp = (ir_arr_descr*)xrealloc(dp, sizeof(*dp) + eltsize*n);
dp->allocated = n;
}
dp->nelts = nelts;
......@@ -135,8 +124,9 @@ size_t array_len(const void *arr)
*/
ir_arr_descr *array_descr(const void *arr)
{
if (! arr)
if (arr == NULL)
return NULL;
return ARR_DESCR(arr);
}
#endif /* DEBUG_libfirm */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment