Bug #9681 » 20141106-ruby2_1-r48288+r48289.patch
| compile.c (working copy) | ||
|---|---|---|
|
/* definition of data structure for compiler */
|
||
|
/*********************************************/
|
||
|
/*
|
||
|
* On 32-bit SPARC, GCC by default generates SPARC V7 code that may require
|
||
|
* 8-byte word alignment. On the other hand, Oracle Solaris Studio seems to
|
||
|
* generate SPARCV8PLUS code with unaligned memory accesss instructions.
|
||
|
* That is why the STRICT_ALIGNMENT is defined only with GCC.
|
||
|
*/
|
||
|
#if defined(__sparc) && SIZEOF_VOIDP == 4 && defined(__GNUC__)
|
||
|
#define STRICT_ALIGNMENT
|
||
|
#endif
|
||
|
#ifdef STRICT_ALIGNMENT
|
||
|
#if defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG > SIZEOF_VALUE
|
||
|
#define ALIGNMENT_SIZE SIZEOF_LONG_LONG
|
||
|
#else
|
||
|
#define ALIGNMENT_SIZE SIZEOF_VALUE
|
||
|
#endif
|
||
|
#define PADDING_SIZE_MAX ((size_t)((ALIGNMENT_SIZE) - 1))
|
||
|
#define ALIGNMENT_SIZE_MASK PADDING_SIZE_MAX
|
||
|
/* Note: ALIGNMENT_SIZE == (2 ** N) is expected. */
|
||
|
#else
|
||
|
#define PADDING_SIZE_MAX 0
|
||
|
#endif /* STRICT_ALIGNMENT */
|
||
|
#ifdef STRICT_ALIGNMENT
|
||
|
/* calculate padding size for aligned memory access */
|
||
|
static size_t
|
||
|
calc_padding(void *ptr, size_t size)
|
||
|
{
|
||
|
size_t mis;
|
||
|
size_t padding = 0;
|
||
|
mis = (size_t)ptr & ALIGNMENT_SIZE_MASK;
|
||
|
if (mis > 0) {
|
||
|
padding = ALIGNMENT_SIZE - mis;
|
||
|
}
|
||
|
/*
|
||
|
* On 32-bit sparc or equivalents, when a single VALUE is requested
|
||
|
* and padding == sizeof(VALUE), it is clear that no padding is needed.
|
||
|
*/
|
||
|
#if ALIGNMENT_SIZE > SIZEOF_VALUE
|
||
|
if (size == sizeof(VALUE) && padding == sizeof(VALUE)) {
|
||
|
padding = 0;
|
||
|
}
|
||
|
#endif
|
||
|
return padding;
|
||
|
}
|
||
|
#endif /* STRICT_ALIGNMENT */
|
||
|
static void *
|
||
|
compile_data_alloc(rb_iseq_t *iseq, size_t size)
|
||
|
{
|
||
|
void *ptr = 0;
|
||
|
struct iseq_compile_data_storage *storage =
|
||
|
iseq->compile_data->storage_current;
|
||
|
#ifdef STRICT_ALIGNMENT
|
||
|
size_t padding = calc_padding((void *)&storage->buff[storage->pos], size);
|
||
|
#else
|
||
|
const size_t padding = 0; /* expected to be optimized by compiler */
|
||
|
#endif /* STRICT_ALIGNMENT */
|
||
|
if (storage->pos + size > storage->size) {
|
||
|
if (storage->pos + size + padding > storage->size) {
|
||
|
unsigned long alloc_size = storage->size * 2;
|
||
|
retry:
|
||
|
if (alloc_size < size) {
|
||
|
if (alloc_size < size + PADDING_SIZE_MAX) {
|
||
|
alloc_size *= 2;
|
||
|
goto retry;
|
||
|
}
|
||
| ... | ... | |
|
storage->pos = 0;
|
||
|
storage->size = alloc_size;
|
||
|
storage->buff = (char *)(&storage->buff + 1);
|
||
|
#ifdef STRICT_ALIGNMENT
|
||
|
padding = calc_padding((void *)&storage->buff[storage->pos], size);
|
||
|
#endif /* STRICT_ALIGNMENT */
|
||
|
}
|
||
|
#ifdef STRICT_ALIGNMENT
|
||
|
storage->pos += (int)padding;
|
||
|
#endif /* STRICT_ALIGNMENT */
|
||
|
ptr = (void *)&storage->buff[storage->pos];
|
||
|
storage->pos += size;
|
||
|
return ptr;
|
||