Skip to content

Commit 0a4d433

Browse files
committed
rt: Move to a custom alignof since __alignof__ returns the "preferred" alignment rather than the one that gets used in structs
1 parent b16a9a9 commit 0a4d433

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

src/rt/rust_shape.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ size_of::compute_tag_size(tag_info &tinfo) {
199199
tinfo.tag_sa.set(1, 1);
200200
} else {
201201
// Add in space for the tag.
202-
tinfo.tag_sa.add(sizeof(uint32_t), ALIGNOF(uint32_t));
202+
tinfo.tag_sa.add(sizeof(uint32_t), alignof<uint32_t>());
203203
}
204204
}
205205

@@ -259,7 +259,7 @@ class cmp : public data<cmp,ptr_pair> {
259259
}
260260

261261
inline void cmp_two_pointers(bool align) {
262-
if (align) dp = align_to(dp, ALIGNOF(uint8_t *) * 2);
262+
if (align) dp = align_to(dp, alignof<uint8_t *>() * 2);
263263
data_pair<uint8_t *> fst = bump_dp<uint8_t *>(dp);
264264
data_pair<uint8_t *> snd = bump_dp<uint8_t *>(dp);
265265
cmp_number(fst);
@@ -268,7 +268,7 @@ class cmp : public data<cmp,ptr_pair> {
268268
}
269269

270270
inline void cmp_pointer(bool align) {
271-
if (align) dp = align_to(dp, ALIGNOF(uint8_t *));
271+
if (align) dp = align_to(dp, alignof<uint8_t *>());
272272
cmp_number(bump_dp<uint8_t *>(dp));
273273
}
274274

src/rt/rust_shape.h

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66

77
#include "rust_internal.h"
88

9-
#ifdef _MSC_VER
10-
#define ALIGNOF __alignof
11-
#else
12-
#define ALIGNOF __alignof__
13-
#endif
14-
159
#define ARENA_SIZE 256
1610

1711
#define DPRINT(fmt,...) fprintf(stderr, fmt, ##__VA_ARGS__)
@@ -86,6 +80,30 @@ class arena {
8680
};
8781

8882

83+
// Alignment inquiries
84+
//
85+
// We can't directly use __alignof__ everywhere because that returns the
86+
// preferred alignment of the type, which is different from the ABI-mandated
87+
// alignment of the type in some cases (e.g. doubles on x86). The latter is
88+
// what actually gets used for struct elements.
89+
90+
template<typename T>
91+
inline size_t
92+
alignof() {
93+
#ifdef _MSC_VER
94+
return __alignof(T);
95+
#else
96+
return __alignof__(T);
97+
#endif
98+
}
99+
100+
template<>
101+
inline size_t
102+
alignof<double>() {
103+
return 4;
104+
}
105+
106+
89107
// Utility classes
90108

91109
struct size_align {
@@ -546,7 +564,7 @@ class size_of : public ctxt<size_of> {
546564
}
547565

548566
template<typename T>
549-
void walk_number(bool align) { sa.set(sizeof(T), ALIGNOF(T)); }
567+
void walk_number(bool align) { sa.set(sizeof(T), alignof<T>()); }
550568

551569
void compute_tag_size(tag_info &tinfo);
552570

@@ -709,7 +727,7 @@ namespace shape {
709727
// for methods that actually manipulate the data involved.
710728

711729
#define DATA_SIMPLE(ty, call) \
712-
if (align) dp = align_to(dp, sizeof(ty)); \
730+
if (align) dp = align_to(dp, alignof<ty>()); \
713731
U end_dp = dp + sizeof(ty); \
714732
static_cast<T *>(this)->call; \
715733
dp = end_dp;
@@ -847,7 +865,7 @@ data<T,U>::walk_tag(bool align, tag_info &tinfo) {
847865
size_of::compute_tag_size(*this, tinfo);
848866

849867
if (tinfo.variant_count > 1 && align)
850-
dp = align_to(dp, ALIGNOF(uint32_t));
868+
dp = align_to(dp, alignof<uint32_t>());
851869

852870
U end_dp = dp + tinfo.tag_sa.size;
853871

0 commit comments

Comments
 (0)