Align `RFloat` at VALUE boundary

This commit is contained in:
Nobuyoshi Nakada 2021-10-26 23:39:43 +09:00
parent afdca0e780
commit e3a783b141
Notes: git 2021-10-27 02:05:34 +09:00
3 changed files with 27 additions and 19 deletions

11
gc.c
View File

@ -565,10 +565,6 @@ struct RMoved {
#define RMOVED(obj) ((struct RMoved *)(obj)) #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 { typedef struct RVALUE {
union { union {
struct { struct {
@ -618,9 +614,12 @@ typedef struct RVALUE {
#endif #endif
} RVALUE; } RVALUE;
#if (SIZEOF_DOUBLE > SIZEOF_VALUE) && (defined(_MSC_VER) || defined(__CYGWIN__)) #if GC_DEBUG
#pragma pack(pop) STATIC_ASSERT(sizeof_rvalue, offsetof(RVALUE, file) == SIZEOF_VALUE * 5);
#else
STATIC_ASSERT(sizeof_rvalue, sizeof(RVALUE) == SIZEOF_VALUE * 5);
#endif #endif
STATIC_ASSERT(alignof_rvalue, RUBY_ALIGNOF(RVALUE) == SIZEOF_VALUE);
typedef uintptr_t bits_t; typedef uintptr_t bits_t;
enum { enum {

View File

@ -35,9 +35,18 @@ enum ruby_num_rounding_mode {
RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT, 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 RFloat {
struct RBasic basic; struct RBasic basic;
double float_value; rb_float_value_type float_value;
}; };
#define RFLOAT(obj) ((struct RFloat *)(obj)) #define RFLOAT(obj) ((struct RFloat *)(obj))
@ -206,21 +215,17 @@ rb_float_flonum_value(VALUE v)
return 0.0; 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 static inline double
rb_float_noflonum_value(VALUE v) rb_float_noflonum_value(VALUE v)
{ {
#if UNALIGNED_DOUBLE_ACCESS #if SIZEOF_DOUBLE < SIZEOF_VALUE
return RFLOAT(v)->float_value; return RFLOAT(v)->float_value;
#else #else
double d; union {
memcpy(&d, &RFLOAT(v)->float_value, sizeof(double)); rb_float_value_type v;
return d; double d;
} u = {RFLOAT(v)->float_value};
return u.d;
#endif #endif
} }

View File

@ -951,10 +951,14 @@ rb_float_new_in_heap(double d)
{ {
NEWOBJ_OF(flt, struct RFloat, rb_cFloat, T_FLOAT | (RGENGC_WB_PROTECTED_FLOAT ? FL_WB_PROTECTED : 0)); 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; flt->float_value = d;
#else #else
memcpy(&flt->float_value, &d, sizeof(double)); union {
double d;
rb_float_value_type v;
} u = {d};
flt->float_value = u.v;
#endif #endif
OBJ_FREEZE((VALUE)flt); OBJ_FREEZE((VALUE)flt);
return (VALUE)flt; return (VALUE)flt;