[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]