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

ruby-changes:69462

From: Nobuyoshi <ko1@a...>
Date: Wed, 27 Oct 2021 02:05:23 +0900 (JST)
Subject: [ruby-changes:69462] e3a783b141 (master): Align `RFloat` at VALUE boundary

https://git.ruby-lang.org/ruby.git/commit/?id=e3a783b141

From e3a783b14191fef175c9a59996afdc744c8edc4c Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Tue, 26 Oct 2021 23:39:43 +0900
Subject: Align `RFloat` at VALUE boundary

---
 gc.c               | 11 +++++------
 internal/numeric.h | 27 ++++++++++++++++-----------
 numeric.c          |  8 ++++++--
 3 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/gc.c b/gc.c
index 0c739ba709b..bd3915fb470 100644
--- a/gc.c
+++ b/gc.c
@@ -565,10 +565,6 @@ struct RMoved { https://github.com/ruby/ruby/blob/trunk/gc.c#L565
 
 #define RMOVED(obj) ((struct RMoved *)(obj))
 
-#if (SIZEOF_DOUBLE > SIZEOF_VALUE) && (defined(_MSC_VER) || defined(__CYGWIN__))
-#pragma pack(push, 4) /* == SIZEOF_VALUE: magic for reducing sizeof(RVALUE): 24 -> 20 */
-#endif
-
 typedef struct RVALUE {
     union {
 	struct {
@@ -618,9 +614,12 @@ typedef struct RVALUE { https://github.com/ruby/ruby/blob/trunk/gc.c#L614
 #endif
 } RVALUE;
 
-#if (SIZEOF_DOUBLE > SIZEOF_VALUE) && (defined(_MSC_VER) || defined(__CYGWIN__))
-#pragma pack(pop)
+#if GC_DEBUG
+STATIC_ASSERT(sizeof_rvalue, offsetof(RVALUE, file) == SIZEOF_VALUE * 5);
+#else
+STATIC_ASSERT(sizeof_rvalue, sizeof(RVALUE) == SIZEOF_VALUE * 5);
 #endif
+STATIC_ASSERT(alignof_rvalue, RUBY_ALIGNOF(RVALUE) == SIZEOF_VALUE);
 
 typedef uintptr_t bits_t;
 enum {
diff --git a/internal/numeric.h b/internal/numeric.h
index 3d88845a169..440bef16711 100644
--- a/internal/numeric.h
+++ b/internal/numeric.h
@@ -35,9 +35,18 @@ enum ruby_num_rounding_mode { https://github.com/ruby/ruby/blob/trunk/internal/numeric.h#L35
     RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT,
 };
 
+#if SIZEOF_DOUBLE < SIZEOF_VALUE
+typedef double rb_float_value_type;
+#else
+typedef struct {
+    VALUE values[(SIZEOF_DOUBLE + SIZEOF_VALUE - 1) / SIZEOF_VALUE];
+    /* roomof() needs internal.h, and the order of some macros may matter */
+} rb_float_value_type;
+#endif
+
 struct RFloat {
     struct RBasic basic;
-    double float_value;
+    rb_float_value_type float_value;
 };
 
 #define RFLOAT(obj)  ((struct RFloat *)(obj))
@@ -206,21 +215,17 @@ rb_float_flonum_value(VALUE v) https://github.com/ruby/ruby/blob/trunk/internal/numeric.h#L215
     return 0.0;
 }
 
-#if SIZEOF_VALUE >= SIZEOF_DOUBLE || defined(UNALIGNED_WORD_ACCESS)
-# define UNALIGNED_DOUBLE_ACCESS 1
-#else
-# define UNALIGNED_DOUBLE_ACCESS 0
-#endif
-
 static inline double
 rb_float_noflonum_value(VALUE v)
 {
-#if UNALIGNED_DOUBLE_ACCESS
+#if SIZEOF_DOUBLE < SIZEOF_VALUE
     return RFLOAT(v)->float_value;
 #else
-    double d;
-    memcpy(&d, &RFLOAT(v)->float_value, sizeof(double));
-    return d;
+    union {
+        rb_float_value_type v;
+        double d;
+    } u = {RFLOAT(v)->float_value};
+    return u.d;
 #endif
 }
 
diff --git a/numeric.c b/numeric.c
index e12bcce5b8f..3ee98343a73 100644
--- a/numeric.c
+++ b/numeric.c
@@ -951,10 +951,14 @@ rb_float_new_in_heap(double d) https://github.com/ruby/ruby/blob/trunk/numeric.c#L951
 {
     NEWOBJ_OF(flt, struct RFloat, rb_cFloat, T_FLOAT | (RGENGC_WB_PROTECTED_FLOAT ? FL_WB_PROTECTED : 0));
 
-#if UNALIGNED_DOUBLE_ACCESS
+#if SIZEOF_DOUBLE < SIZEOF_VALUE
     flt->float_value = d;
 #else
-    memcpy(&flt->float_value, &d, sizeof(double));
+    union {
+        double d;
+        rb_float_value_type v;
+    } u = {d};
+    flt->float_value = u.v;
 #endif
     OBJ_FREEZE((VALUE)flt);
     return (VALUE)flt;
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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