ruby-changes:36215
From: usa <ko1@a...>
Date: Thu, 6 Nov 2014 17:36:21 +0900 (JST)
Subject: [ruby-changes:36215] usa:r48296 (ruby_2_0_0): * compile.c (compile_data_alloc): add padding when strict alignment
usa 2014-11-06 17:36:10 +0900 (Thu, 06 Nov 2014) New Revision: 48296 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48296 Log: * 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 Modified files: branches/ruby_2_0_0/ChangeLog branches/ruby_2_0_0/compile.c branches/ruby_2_0_0/version.h Index: ruby_2_0_0/ChangeLog =================================================================== --- ruby_2_0_0/ChangeLog (revision 48295) +++ ruby_2_0_0/ChangeLog (revision 48296) @@ -1,3 +1,17 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/ChangeLog#L1 +Thu Nov 6 17:31:51 2014 Naohisa Goto <ngotogenome@g...> + + * 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 18:26:49 2014 NAKAMURA Usaku <usa@r...> * vm_insnhelper.c (unknown_keyword_error): delete expected keywords Index: ruby_2_0_0/compile.c =================================================================== --- ruby_2_0_0/compile.c (revision 48295) +++ ruby_2_0_0/compile.c (revision 48296) @@ -581,18 +581,72 @@ rb_iseq_translate_threaded_code(rb_iseq_ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/compile.c#L581 /* 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; } @@ -604,8 +658,15 @@ compile_data_alloc(rb_iseq_t *iseq, size https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/compile.c#L658 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; Index: ruby_2_0_0/version.h =================================================================== --- ruby_2_0_0/version.h (revision 48295) +++ ruby_2_0_0/version.h (revision 48296) @@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/version.h#L1 #define RUBY_VERSION "2.0.0" -#define RUBY_RELEASE_DATE "2014-11-05" -#define RUBY_PATCHLEVEL 596 +#define RUBY_RELEASE_DATE "2014-11-06" +#define RUBY_PATCHLEVEL 597 #define RUBY_RELEASE_YEAR 2014 #define RUBY_RELEASE_MONTH 11 -#define RUBY_RELEASE_DAY 5 +#define RUBY_RELEASE_DAY 6 #include "ruby/version.h" -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/