Commit aafd8ff9 authored by Elizabeth Smith's avatar Elizabeth Smith Committed by Dave Watson

msvc packed attribute translation

Summary:
Provide translations for gcc packed

MSVC has a very very ugly syntax for packing using pragmas which is very different from the gcc attribute
this makes it very hard to macro around, but lots of ifdefs are also painful - cleanest of the hackery is to simply have push, pop, and attribute macros for packed that define properly depending on the compiler

Test Plan: fbmake runtests

Reviewed By: njormrod@fb.com

FB internal diff: D1279966
parent b7ccdf65
......@@ -524,6 +524,7 @@ template <class T, class Enable=void> struct Unaligned;
/**
* Representation of an unaligned value of a POD type.
*/
FOLLY_PACK_PUSH
template <class T>
struct Unaligned<
T,
......@@ -531,7 +532,8 @@ struct Unaligned<
Unaligned() = default; // uninitialized
/* implicit */ Unaligned(T v) : value(v) { }
T value;
} __attribute__((packed));
} FOLLY_PACK_ATTR;
FOLLY_PACK_POP
/**
* Read an unaligned value of type T and return it.
......
......@@ -79,6 +79,21 @@ struct MaxAlign { char c; } __attribute__((aligned));
# define FOLLY_X64 0
#endif
// packing is very ugly in msvc
#ifdef _MSC_VER
# define FOLLY_PACK_ATTR /**/
# define FOLLY_PACK_PUSH __pragma(pack(push, 1))
# define FOLLY_PACK_POP __pragma(pack(pop))
#elif defined(__clang__) || defined(__GNUC__)
# define FOLLY_PACK_ATTR __attribute__((packed))
# define FOLLY_PACK_PUSH /**/
# define FOLLY_PACK_POP /**/
#else
# define FOLLY_PACK_ATTR /**/
# define FOLLY_PACK_PUSH /**/
# define FOLLY_PACK_POP /**/
#endif
// portable version check
#ifndef __GNUC_PREREQ
# if defined __GNUC__ && defined __GNUC_MINOR__
......
......@@ -61,6 +61,7 @@ namespace recordio_helpers {
namespace detail {
FOLLY_PACK_PUSH
struct Header {
// First 4 bytes of SHA1("zuck"), big-endian
// Any values will do, except that the sequence must not have a
......@@ -75,7 +76,8 @@ struct Header {
uint32_t dataLength;
uint64_t dataHash;
uint32_t headerHash; // must be last
} __attribute__((packed));
} FOLLY_PACK_ATTR;
FOLLY_PACK_POP
static_assert(offsetof(Header, headerHash) + sizeof(Header::headerHash) ==
sizeof(Header), "invalid header layout");
......
......@@ -50,9 +50,13 @@
#if defined(__GNUC__) && FOLLY_X64
# include "folly/SmallLocks.h"
# define FB_PACKED __attribute__((packed))
# define FB_PACK_ATTR FOLLY_PACK_ATTR
# define FB_PACK_PUSH FOLLY_PACK_PUSH
# define FB_PACK_POP FOLLY_PACK_POP
#else
# define FB_PACKED
# define FB_PACK_ATTR
# define FB_PACK_PUSH
# define FB_PACK_POP
#endif
#if FOLLY_HAVE_MALLOC_SIZE
......@@ -427,7 +431,7 @@ namespace detail {
}
//////////////////////////////////////////////////////////////////////
FB_PACK_PUSH
template<class Value,
std::size_t RequestedMaxInline = 1,
class PolicyA = void,
......@@ -1086,7 +1090,7 @@ private:
InternalSizeType* getCapacity() {
return &capacity_;
}
} FB_PACKED;
} FB_PACK_ATTR;
struct HeapPtr {
// Lower order bit of heap_ is used as flag to indicate whether capacity is
......@@ -1098,7 +1102,7 @@ private:
return static_cast<InternalSizeType*>(
detail::pointerFlagClear(heap_));
}
} FB_PACKED;
} FB_PACK_ATTR;
#if FOLLY_X64
typedef unsigned char InlineStorageType[sizeof(value_type) * MaxInline];
......@@ -1167,8 +1171,9 @@ private:
auto vp = detail::pointerFlagClear(pdata_.heap_);
free(vp);
}
} FB_PACKED u;
} FB_PACKED;
} FB_PACK_ATTR u;
} FB_PACK_ATTR;
FB_PACK_POP
//////////////////////////////////////////////////////////////////////
......@@ -1186,8 +1191,10 @@ void swap(small_vector<T,MaxInline,A,B,C>& a,
#pragma GCC diagnostic pop
#ifdef FB_PACKED
# undef FB_PACKED
#ifdef FB_PACK_ATTR
# undef FB_PACK_ATTR
# undef FB_PACK_PUSH
# undef FB_PACK_POP
#endif
#endif
......@@ -28,7 +28,9 @@ namespace {
// Compile time check for packability. This requires that
// PackedSyncPtr is a POD struct on gcc.
struct ignore { PackedSyncPtr<int> foo; char c; } __attribute__((packed));
FOLLY_PACK_PUSH
struct ignore { PackedSyncPtr<int> foo; char c; } FOLLY_PACK_ATTR;
FOLLY_PACK_POP
static_assert(sizeof(ignore) == 9, "PackedSyncPtr wasn't packable");
}
......
......@@ -46,11 +46,13 @@ struct LockedVal {
// Compile time test for packed struct support (requires that both of
// these classes are POD).
struct ignore1 { MicroSpinLock msl; int16_t foo; } __attribute__((packed));
FOLLY_PACK_PUSH
struct ignore1 { MicroSpinLock msl; int16_t foo; } FOLLY_PACK_ATTR;
struct ignore2 { PicoSpinLock<uint32_t> psl; int16_t foo; }
__attribute__((packed));
FOLLY_PACK_ATTR;
static_assert(sizeof(ignore1) == 3, "Size check failed");
static_assert(sizeof(ignore2) == 6, "Size check failed");
FOLLY_PACK_POP
LockedVal v;
void splock_test() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment