Bug #9681 » 20141023-compile_data_alloc-word-align.patch
compile.c (working copy) | ||
---|---|---|
/* definition of data structure for compiler */
|
||
/*********************************************/
|
||
/* check if word-aligned memory access is needed */
|
||
#if defined(__sparc) /* sparc 32-bit and 64-bit (sparc v9) */
|
||
#define STRICT_ADDRESS_ALIGNMENT
|
||
#endif
|
||
#ifdef STRICT_ADDRESS_ALIGNMENT
|
||
/*
|
||
* On sparc V8 (32-bit), because sizeof(long long) > sizeof(VALUE) and
|
||
* sizeof(double) > sizeof(VALUE), a struct that may contain long long or
|
||
* double is aligned to sizeof(double) or sizeof(long long), respectively.
|
||
*/
|
||
#if defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG > SIZEOF_VALUE && \
|
||
SIZEOF_LONG_LONG >= SIZEOF_DOUBLE
|
||
#define ALIGN_SIZE SIZEOF_LONG_LONG
|
||
#elif SIZEOF_DOUBLE > SIZEOF_VALUE
|
||
#define ALIGN_SIZE SIZEOF_DOUBLE
|
||
#else
|
||
#define ALIGN_SIZE SIZEOF_VALUE
|
||
#endif
|
||
/* ALIGN_SIZE must be 2 ** N. */
|
||
#define ALIGN_SIZE_MASK ((size_t)((ALIGN_SIZE) - 1))
|
||
#endif /* STRICT_ADDRESS_ALIGNMENT */
|
||
static void *
|
||
compile_data_alloc(rb_iseq_t *iseq, size_t size)
|
||
{
|
||
... | ... | |
struct iseq_compile_data_storage *storage =
|
||
iseq->compile_data->storage_current;
|
||
if (storage->pos + size > storage->size) {
|
||
#ifdef STRICT_ADDRESS_ALIGNMENT
|
||
size_t padding = 0;
|
||
size_t mis;
|
||
#else
|
||
const size_t padding = 0; /* to be optimized by compiler */
|
||
#endif
|
||
#ifdef STRICT_ADDRESS_ALIGNMENT
|
||
mis = (size_t)storage->pos & ALIGN_SIZE_MASK;
|
||
if (mis > 0) {
|
||
padding = ALIGN_SIZE - mis;
|
||
/* Optimize when a VALUE is requested on 32-bit sparc or equivalents. */
|
||
#if ALIGN_SIZE > SIZEOF_VALUE
|
||
if (padding == sizeof(VALUE)) {
|
||
padding = 0;
|
||
}
|
||
#endif
|
||
}
|
||
#endif /* STRICT_ADDRESS_ALIGNMENT */
|
||
if (storage->pos + padding + size > storage->size) {
|
||
unsigned long alloc_size = storage->size * 2;
|
||
#ifdef STRICT_ADDRESS_ALIGNMENT
|
||
padding = 0; /* assumes that start address is always aligned. */
|
||
#endif
|
||
retry:
|
||
if (alloc_size < size) {
|
||
alloc_size *= 2;
|
||
... | ... | |
storage->buff = (char *)(&storage->buff + 1);
|
||
}
|
||
#ifdef STRICT_ADDRESS_ALIGNMENT
|
||
storage->pos += padding;
|
||
#endif
|
||
ptr = (void *)&storage->buff[storage->pos];
|
||
storage->pos += size;
|
||
return ptr;
|