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;
|
||