@@ -2641,24 +2641,40 @@ void swift::swift_initStructMetadata(StructMetadata *structType,
26412641 vwtable->publishLayout (layout);
26422642}
26432643
2644- enum LayoutStringFlags : uint64_t {
2645- Empty = 0 ,
2646- // TODO: Track other useful information tha can be used to optimize layout
2647- // strings, like different reference kinds contained in the string
2648- // number of ref counting operations (maybe up to 4), so we can
2649- // use witness functions optimized for these cases.
2650- HasRelativePointers = (1ULL << 63 ),
2651- };
2644+ namespace {
2645+ enum LayoutStringFlags : uint64_t {
2646+ Empty = 0 ,
2647+ // TODO: Track other useful information tha can be used to optimize layout
2648+ // strings, like different reference kinds contained in the string
2649+ // number of ref counting operations (maybe up to 4), so we can
2650+ // use witness functions optimized for these cases.
2651+ HasRelativePointers = (1ULL << 63 ),
2652+ };
26522653
2653- inline bool operator &(LayoutStringFlags a, LayoutStringFlags b) {
2654- return (uint64_t (a) & uint64_t (b)) != 0 ;
2655- }
2656- inline LayoutStringFlags operator |(LayoutStringFlags a, LayoutStringFlags b) {
2657- return LayoutStringFlags (uint64_t (a) | uint64_t (b));
2658- }
2659- inline LayoutStringFlags &operator |=(LayoutStringFlags &a, LayoutStringFlags b) {
2660- return a = (a | b);
2661- }
2654+ inline bool operator &(LayoutStringFlags a, LayoutStringFlags b) {
2655+ return (uint64_t (a) & uint64_t (b)) != 0 ;
2656+ }
2657+ inline LayoutStringFlags operator |(LayoutStringFlags a, LayoutStringFlags b) {
2658+ return LayoutStringFlags (uint64_t (a) | uint64_t (b));
2659+ }
2660+ inline LayoutStringFlags &operator |=(LayoutStringFlags &a, LayoutStringFlags b) {
2661+ return a = (a | b);
2662+ }
2663+
2664+ template <typename T>
2665+ inline T readBytes (const uint8_t *layoutStr, size_t &i) {
2666+ T returnVal;
2667+ memcpy (&returnVal, layoutStr + i, sizeof (T));
2668+ i += sizeof (T);
2669+ return returnVal;
2670+ }
2671+
2672+ template <typename T>
2673+ inline void writeBytes (uint8_t *layoutStr, size_t &i, T value) {
2674+ memcpy (layoutStr + i, &value, sizeof (T));
2675+ i += sizeof (T);
2676+ }
2677+ } // end anonymous namespace
26622678
26632679void swift::swift_initStructMetadataWithLayoutString (
26642680 StructMetadata *structType, StructLayoutFlags layoutFlags, size_t numFields,
@@ -2732,9 +2748,9 @@ void swift::swift_initStructMetadataWithLayoutString(
27322748 uint8_t *layoutStr = (uint8_t *)MetadataAllocator (LayoutStringTag)
27332749 .Allocate (fixedLayoutStringSize + refCountBytes, alignof (uint8_t ));
27342750
2735- *(( size_t *)(layoutStr + sizeof (uint64_t ))) = refCountBytes ;
2751+ size_t layoutStrOffset = sizeof (uint64_t );
27362752
2737- size_t layoutStrOffset = layoutStringHeaderSize ;
2753+ writeBytes (layoutStr, layoutStrOffset, refCountBytes) ;
27382754 size_t fullOffset = 0 ;
27392755 size_t previousFieldOffset = 0 ;
27402756 LayoutStringFlags flags = LayoutStringFlags::Empty;
@@ -2753,9 +2769,8 @@ void swift::swift_initStructMetadataWithLayoutString(
27532769 auto tag = fieldTag <= 0x2 ? RefCountingKind::UnknownUnowned :
27542770 RefCountingKind::UnknownWeak;
27552771
2756- *(uint64_t *)(layoutStr + layoutStrOffset) =
2757- ((uint64_t )tag << 56 ) | offset;
2758- layoutStrOffset += sizeof (uint64_t );
2772+ auto tagAndOffset = ((uint64_t )tag << 56 ) | offset;
2773+ writeBytes (layoutStr, layoutStrOffset, tagAndOffset);
27592774 }
27602775
27612776 fullOffset += fieldType->size ;
@@ -2793,10 +2808,18 @@ void swift::swift_initStructMetadataWithLayoutString(
27932808 }
27942809
27952810 if (offset) {
2796- *(uint64_t *)(layoutStr + layoutStrOffset) += offset;
2811+ auto layoutStrOffsetCopy = layoutStrOffset;
2812+ auto firstTagAndOffset =
2813+ readBytes<uint64_t >(layoutStr, layoutStrOffsetCopy);
2814+ layoutStrOffsetCopy = layoutStrOffset;
2815+ firstTagAndOffset += offset;
2816+ writeBytes (layoutStr, layoutStrOffsetCopy, firstTagAndOffset);
27972817 }
27982818
2799- previousFieldOffset = *(const uint64_t *)(fieldLayoutStr + layoutStringHeaderSize + fieldRefCountBytes);
2819+ auto previousFieldOffsetOffset =
2820+ layoutStringHeaderSize + fieldRefCountBytes;
2821+ previousFieldOffset = readBytes<uint64_t >(fieldLayoutStr,
2822+ previousFieldOffsetOffset);
28002823 layoutStrOffset += fieldRefCountBytes;
28012824 } else {
28022825 previousFieldOffset += fieldType->vw_size ();
@@ -2827,39 +2850,35 @@ void swift::swift_initStructMetadataWithLayoutString(
28272850 };
28282851 }
28292852
2830- *(uint64_t *)(layoutStr + layoutStrOffset) =
2831- ((uint64_t )tag << 56 ) | offset;
2832- layoutStrOffset += sizeof (uint64_t );
2853+ writeBytes (layoutStr, layoutStrOffset, ((uint64_t )tag << 56 ) | offset);
28332854 previousFieldOffset = fieldType->vw_size ();
28342855 fullOffset += previousFieldOffset;
28352856 } else if (fieldType->isAnyExistentialType ()) {
28362857 auto *existential = dyn_cast<ExistentialTypeMetadata>(fieldType);
28372858 assert (existential);
28382859 auto tag = existential->isClassBounded () ? RefCountingKind::Unknown
28392860 : RefCountingKind::Existential;
2840- *(uint64_t *)(layoutStr + layoutStrOffset) =
2841- ((uint64_t )tag << 56 ) | offset;
2842- layoutStrOffset += sizeof (uint64_t );
2861+ writeBytes (layoutStr, layoutStrOffset, ((uint64_t )tag << 56 ) | offset);
28432862 previousFieldOffset = fieldType->vw_size ();
28442863 fullOffset += previousFieldOffset;
28452864 } else {
28462865metadata:
2847- *(uint64_t *)(layoutStr + layoutStrOffset) =
2848- ((uint64_t )RefCountingKind::Metatype << 56 ) | offset;
2849- *(uintptr_t *)(layoutStr + layoutStrOffset + sizeof (uint64_t )) =
2850- (uintptr_t )fieldType;
2851- layoutStrOffset += sizeof (uint64_t ) + sizeof (uintptr_t );
2866+ writeBytes (layoutStr, layoutStrOffset,
2867+ ((uint64_t )RefCountingKind::Metatype << 56 ) | offset);
2868+ writeBytes (layoutStr, layoutStrOffset, fieldType);
28522869 previousFieldOffset = fieldType->vw_size ();
28532870 fullOffset += previousFieldOffset;
28542871 }
28552872 }
28562873
2857- *( uint64_t *)( layoutStr + layoutStrOffset) = previousFieldOffset;
2858- *( uint64_t *)( layoutStr + layoutStrOffset + sizeof ( uint64_t )) = 0 ;
2874+ writeBytes ( layoutStr, layoutStrOffset, previousFieldOffset) ;
2875+ writeBytes ( layoutStr, layoutStrOffset, 0 ) ;
28592876
28602877 // we mask out HasRelativePointers, because at this point they have all been
28612878 // resolved to metadata pointers
2862- *(uint64_t *)(layoutStr) = ((uint64_t )flags) & ~((uint64_t )LayoutStringFlags::HasRelativePointers);
2879+ layoutStrOffset = 0 ;
2880+ writeBytes (layoutStr, layoutStrOffset,
2881+ ((uint64_t )flags) & ~((uint64_t )LayoutStringFlags::HasRelativePointers));
28632882
28642883 structType->setLayoutString (layoutStr);
28652884
0 commit comments