@@ -2641,24 +2641,40 @@ void swift::swift_initStructMetadata(StructMetadata *structType,
2641
2641
vwtable->publishLayout (layout);
2642
2642
}
2643
2643
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
+ };
2652
2653
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
2662
2678
2663
2679
void swift::swift_initStructMetadataWithLayoutString (
2664
2680
StructMetadata *structType, StructLayoutFlags layoutFlags, size_t numFields,
@@ -2732,9 +2748,9 @@ void swift::swift_initStructMetadataWithLayoutString(
2732
2748
uint8_t *layoutStr = (uint8_t *)MetadataAllocator (LayoutStringTag)
2733
2749
.Allocate (fixedLayoutStringSize + refCountBytes, alignof (uint8_t ));
2734
2750
2735
- *(( size_t *)(layoutStr + sizeof (uint64_t ))) = refCountBytes ;
2751
+ size_t layoutStrOffset = sizeof (uint64_t );
2736
2752
2737
- size_t layoutStrOffset = layoutStringHeaderSize ;
2753
+ writeBytes (layoutStr, layoutStrOffset, refCountBytes) ;
2738
2754
size_t fullOffset = 0 ;
2739
2755
size_t previousFieldOffset = 0 ;
2740
2756
LayoutStringFlags flags = LayoutStringFlags::Empty;
@@ -2753,9 +2769,8 @@ void swift::swift_initStructMetadataWithLayoutString(
2753
2769
auto tag = fieldTag <= 0x2 ? RefCountingKind::UnknownUnowned :
2754
2770
RefCountingKind::UnknownWeak;
2755
2771
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);
2759
2774
}
2760
2775
2761
2776
fullOffset += fieldType->size ;
@@ -2793,10 +2808,18 @@ void swift::swift_initStructMetadataWithLayoutString(
2793
2808
}
2794
2809
2795
2810
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);
2797
2817
}
2798
2818
2799
- previousFieldOffset = *(const uint64_t *)(fieldLayoutStr + layoutStringHeaderSize + fieldRefCountBytes);
2819
+ auto previousFieldOffsetOffset =
2820
+ layoutStringHeaderSize + fieldRefCountBytes;
2821
+ previousFieldOffset = readBytes<uint64_t >(fieldLayoutStr,
2822
+ previousFieldOffsetOffset);
2800
2823
layoutStrOffset += fieldRefCountBytes;
2801
2824
} else {
2802
2825
previousFieldOffset += fieldType->vw_size ();
@@ -2827,39 +2850,35 @@ void swift::swift_initStructMetadataWithLayoutString(
2827
2850
};
2828
2851
}
2829
2852
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);
2833
2854
previousFieldOffset = fieldType->vw_size ();
2834
2855
fullOffset += previousFieldOffset;
2835
2856
} else if (fieldType->isAnyExistentialType ()) {
2836
2857
auto *existential = dyn_cast<ExistentialTypeMetadata>(fieldType);
2837
2858
assert (existential);
2838
2859
auto tag = existential->isClassBounded () ? RefCountingKind::Unknown
2839
2860
: 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);
2843
2862
previousFieldOffset = fieldType->vw_size ();
2844
2863
fullOffset += previousFieldOffset;
2845
2864
} else {
2846
2865
metadata:
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);
2852
2869
previousFieldOffset = fieldType->vw_size ();
2853
2870
fullOffset += previousFieldOffset;
2854
2871
}
2855
2872
}
2856
2873
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 ) ;
2859
2876
2860
2877
// we mask out HasRelativePointers, because at this point they have all been
2861
2878
// 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));
2863
2882
2864
2883
structType->setLayoutString (layoutStr);
2865
2884
0 commit comments