* compile.c (compile_data_alloc): add padding when strict alignment
is required for memory access. Currently, the padding is enabled only when the CPU is 32-bit SPARC and the compiler is GCC. [Bug #9681] [ruby-core:61715] * compile.c (STRICT_ALIGNMENT): defined if strict alignment is required * compile.c (ALIGNMENT_SIZE, ALIGNMENT_SIZE_MASK, PADDING_SIZE_MAX): new macros for alignemnt word size, bit mask, max size of padding. * compile.c (calc_padding): new function to calculate padding size. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48288 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f4c848e158
commit
da4a5ef141
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
Wed Nov 5 23:43:24 2014 Naohisa Goto <ngotogenome@gmail.com>
|
||||||
|
|
||||||
|
* compile.c (compile_data_alloc): add padding when strict alignment
|
||||||
|
is required for memory access. Currently, the padding is enabled
|
||||||
|
only when the CPU is 32-bit SPARC and the compiler is GCC.
|
||||||
|
[Bug #9681] [ruby-core:61715]
|
||||||
|
|
||||||
|
* compile.c (STRICT_ALIGNMENT): defined if strict alignment is required
|
||||||
|
|
||||||
|
* compile.c (ALIGNMENT_SIZE, ALIGNMENT_SIZE_MASK, PADDING_SIZE_MAX):
|
||||||
|
new macros for alignemnt word size, bit mask, max size of padding.
|
||||||
|
|
||||||
|
* compile.c (calc_padding): new function to calculate padding size.
|
||||||
|
|
||||||
Wed Nov 5 23:24:45 2014 Tanaka Akira <akr@fsij.org>
|
Wed Nov 5 23:24:45 2014 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* test/open-uri/test_open-uri.rb: Don't ignore webrick's log.
|
* test/open-uri/test_open-uri.rb: Don't ignore webrick's log.
|
||||||
|
67
compile.c
67
compile.c
@ -625,18 +625,72 @@ rb_iseq_original_iseq(rb_iseq_t *iseq) /* cold path */
|
|||||||
/* definition of data structure for compiler */
|
/* 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 *
|
static void *
|
||||||
compile_data_alloc(rb_iseq_t *iseq, size_t size)
|
compile_data_alloc(rb_iseq_t *iseq, size_t size)
|
||||||
{
|
{
|
||||||
void *ptr = 0;
|
void *ptr = 0;
|
||||||
struct iseq_compile_data_storage *storage =
|
struct iseq_compile_data_storage *storage =
|
||||||
iseq->compile_data->storage_current;
|
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 (size >= INT_MAX) rb_memerror();
|
if (size >= INT_MAX - padding) rb_memerror();
|
||||||
if (storage->pos + size > storage->size) {
|
if (storage->pos + size + padding > storage->size) {
|
||||||
unsigned int alloc_size = storage->size;
|
unsigned int alloc_size = storage->size;
|
||||||
|
|
||||||
while (alloc_size < size) {
|
while (alloc_size < size + PADDING_SIZE_MAX) {
|
||||||
if (alloc_size >= INT_MAX / 2) rb_memerror();
|
if (alloc_size >= INT_MAX / 2) rb_memerror();
|
||||||
alloc_size *= 2;
|
alloc_size *= 2;
|
||||||
}
|
}
|
||||||
@ -646,8 +700,15 @@ compile_data_alloc(rb_iseq_t *iseq, size_t size)
|
|||||||
storage->next = 0;
|
storage->next = 0;
|
||||||
storage->pos = 0;
|
storage->pos = 0;
|
||||||
storage->size = alloc_size;
|
storage->size = alloc_size;
|
||||||
|
#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];
|
ptr = (void *)&storage->buff[storage->pos];
|
||||||
storage->pos += (int)size;
|
storage->pos += (int)size;
|
||||||
return ptr;
|
return ptr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user