Index: compile.c =================================================================== --- compile.c (revision 48106) +++ compile.c (working copy) @@ -583,6 +583,29 @@ /* 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) { @@ -590,9 +613,33 @@ 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; @@ -608,6 +655,9 @@ 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;