@@ -2641,41 +2641,6 @@ void swift::swift_initStructMetadata(StructMetadata *structType,
2641
2641
vwtable->publishLayout (layout);
2642
2642
}
2643
2643
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
- };
2653
-
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
2678
-
2679
2644
void swift::swift_initStructMetadataWithLayoutString (
2680
2645
StructMetadata *structType, StructLayoutFlags layoutFlags, size_t numFields,
2681
2646
const uint8_t *const *fieldTypes, const uint8_t *fieldTags,
@@ -2727,21 +2692,9 @@ void swift::swift_initStructMetadataWithLayoutString(
2727
2692
extraInhabitantCount = fieldExtraInhabitantCount;
2728
2693
}
2729
2694
2730
- if (fieldType->vw_size () == 0 ) {
2731
- continue ;
2732
- } else if (fieldType->getValueWitnesses ()->isPOD ()) {
2733
- // no extra space required for POD
2734
- } else if (fieldType->hasLayoutString ()) {
2735
- refCountBytes += *(const size_t *)(fieldType->getLayoutString () +
2736
- sizeof (uint64_t ));
2737
- } else if (fieldType->isClassObject () || fieldType->isAnyExistentialType ()) {
2738
- refCountBytes += sizeof (uint64_t );
2739
- } else {
2740
- refCountBytes += sizeof (uint64_t ) + sizeof (uintptr_t );
2741
- }
2695
+ refCountBytes += _swift_refCountBytesForMetatype (fieldType);
2742
2696
}
2743
2697
2744
- const size_t layoutStringHeaderSize = sizeof (uint64_t ) + sizeof (size_t );
2745
2698
const size_t fixedLayoutStringSize = layoutStringHeaderSize +
2746
2699
sizeof (uint64_t ) * 2 ;
2747
2700
@@ -2781,93 +2734,9 @@ void swift::swift_initStructMetadataWithLayoutString(
2781
2734
2782
2735
const Metadata *fieldType = (const Metadata*)fieldTypes[i];
2783
2736
2784
- fullOffset = roundUpToAlignMask (fullOffset, fieldType->vw_alignment () - 1 );
2785
- size_t offset = fullOffset - unalignedOffset + previousFieldOffset;
2786
-
2787
- if (fieldType->vw_size () == 0 ) {
2788
- continue ;
2789
- } else if (fieldType->getValueWitnesses ()->isPOD ()) {
2790
- // No need to handle PODs
2791
- previousFieldOffset = offset + fieldType->vw_size ();
2792
- fullOffset += fieldType->vw_size ();
2793
- } else if (fieldType->hasLayoutString ()) {
2794
- const uint8_t *fieldLayoutStr = fieldType->getLayoutString ();
2795
- const LayoutStringFlags fieldFlags =
2796
- *(const LayoutStringFlags *)fieldLayoutStr;
2797
- const size_t fieldRefCountBytes =
2798
- *(const size_t *)(fieldLayoutStr + sizeof (uint64_t ));
2799
- if (fieldRefCountBytes > 0 ) {
2800
- flags |= fieldFlags;
2801
- memcpy (layoutStr + layoutStrOffset, fieldLayoutStr + layoutStringHeaderSize,
2802
- fieldRefCountBytes);
2803
-
2804
- if (fieldFlags & LayoutStringFlags::HasRelativePointers) {
2805
- swift_resolve_resilientAccessors (layoutStr, layoutStrOffset,
2806
- fieldLayoutStr, fieldType);
2807
- }
2808
-
2809
- if (offset) {
2810
- auto layoutStrOffsetCopy = layoutStrOffset;
2811
- auto firstTagAndOffset =
2812
- readBytes<uint64_t >(layoutStr, layoutStrOffsetCopy);
2813
- layoutStrOffsetCopy = layoutStrOffset;
2814
- firstTagAndOffset += offset;
2815
- writeBytes (layoutStr, layoutStrOffsetCopy, firstTagAndOffset);
2816
- }
2817
-
2818
- auto previousFieldOffsetOffset =
2819
- layoutStringHeaderSize + fieldRefCountBytes;
2820
- previousFieldOffset = readBytes<uint64_t >(fieldLayoutStr,
2821
- previousFieldOffsetOffset);
2822
- layoutStrOffset += fieldRefCountBytes;
2823
- } else {
2824
- previousFieldOffset += fieldType->vw_size ();
2825
- }
2826
- fullOffset += fieldType->vw_size ();
2827
- } else if (auto *cls = fieldType->getClassObject ()) {
2828
- RefCountingKind tag;
2829
- if (!cls->isTypeMetadata ()) {
2830
- #if SWIFT_OBJC_INTEROP
2831
- tag = RefCountingKind::ObjC;
2832
- #else
2833
- tag = RefCountingKind::Unknown;
2834
- #endif
2835
- } else {
2836
- auto *vwt = cls->getValueWitnesses ();
2837
- if (vwt == &VALUE_WITNESS_SYM (Bo)) {
2838
- tag = RefCountingKind::NativeStrong;
2839
- } else if (vwt == &VALUE_WITNESS_SYM (BO)) {
2840
- #if SWIFT_OBJC_INTEROP
2841
- tag = RefCountingKind::ObjC;
2842
- #else
2843
- tag = RefCountingKind::Unknown;
2844
- #endif
2845
- } else if (vwt == &VALUE_WITNESS_SYM (Bb)) {
2846
- tag = RefCountingKind::Bridge;
2847
- } else {
2848
- goto metadata;
2849
- };
2850
- }
2851
-
2852
- writeBytes (layoutStr, layoutStrOffset, ((uint64_t )tag << 56 ) | offset);
2853
- previousFieldOffset = fieldType->vw_size ();
2854
- fullOffset += previousFieldOffset;
2855
- } else if (fieldType->isAnyExistentialType ()) {
2856
- auto *existential = dyn_cast<ExistentialTypeMetadata>(fieldType);
2857
- assert (existential);
2858
- auto tag = existential->isClassBounded () ? RefCountingKind::Unknown
2859
- : RefCountingKind::Existential;
2860
- writeBytes (layoutStr, layoutStrOffset, ((uint64_t )tag << 56 ) | offset);
2861
- previousFieldOffset = fieldType->vw_size ();
2862
- fullOffset += previousFieldOffset;
2863
- } else {
2864
- metadata:
2865
- writeBytes (layoutStr, layoutStrOffset,
2866
- ((uint64_t )RefCountingKind::Metatype << 56 ) | offset);
2867
- writeBytes (layoutStr, layoutStrOffset, fieldType);
2868
- previousFieldOffset = fieldType->vw_size ();
2869
- fullOffset += previousFieldOffset;
2870
- }
2737
+ _swift_addRefCountStringForMetatype (layoutStr, layoutStrOffset, flags,
2738
+ fieldType, fullOffset,
2739
+ previousFieldOffset);
2871
2740
}
2872
2741
2873
2742
writeBytes (layoutStr, layoutStrOffset, previousFieldOffset);
@@ -2896,6 +2765,128 @@ void swift::swift_initStructMetadataWithLayoutString(
2896
2765
vwtable->publishLayout (layout);
2897
2766
}
2898
2767
2768
+ size_t swift::_swift_refCountBytesForMetatype (const Metadata *type) {
2769
+ if (type->vw_size () == 0 || type->getValueWitnesses ()->isPOD ()) {
2770
+ return 0 ;
2771
+ } else if (type->hasLayoutString ()) {
2772
+ size_t offset = sizeof (uint64_t );
2773
+ return readBytes<size_t >(type->getLayoutString (), offset);
2774
+ } else if (type->isClassObject () || type->isAnyExistentialType ()) {
2775
+ return sizeof (uint64_t );
2776
+ } else if (auto *tuple = dyn_cast<TupleTypeMetadata>(type)) {
2777
+ size_t res = 0 ;
2778
+ for (InProcess::StoredSize i = 0 ; i < tuple->NumElements ; i++) {
2779
+ res += _swift_refCountBytesForMetatype (tuple->getElement (i).Type );
2780
+ }
2781
+ return res;
2782
+ } else {
2783
+ return sizeof (uint64_t ) + sizeof (uintptr_t );
2784
+ }
2785
+ }
2786
+
2787
+ void swift::_swift_addRefCountStringForMetatype (uint8_t *layoutStr,
2788
+ size_t &layoutStrOffset,
2789
+ LayoutStringFlags &flags,
2790
+ const Metadata *fieldType,
2791
+ size_t &fullOffset,
2792
+ size_t &previousFieldOffset) {
2793
+ size_t unalignedOffset = fullOffset;
2794
+ fullOffset = roundUpToAlignMask (fullOffset, fieldType->vw_alignment () - 1 );
2795
+ size_t offset = fullOffset - unalignedOffset + previousFieldOffset;
2796
+ if (fieldType->vw_size () == 0 ) {
2797
+ return ;
2798
+ } else if (fieldType->getValueWitnesses ()->isPOD ()) {
2799
+ // No need to handle PODs
2800
+ previousFieldOffset = offset + fieldType->vw_size ();
2801
+ fullOffset += fieldType->vw_size ();
2802
+ } else if (fieldType->hasLayoutString ()) {
2803
+ const uint8_t *fieldLayoutStr = fieldType->getLayoutString ();
2804
+ const LayoutStringFlags fieldFlags =
2805
+ *(const LayoutStringFlags *)fieldLayoutStr;
2806
+ size_t refCountBytesOffset = sizeof (uint64_t );
2807
+ const size_t fieldRefCountBytes = readBytes<size_t >(fieldLayoutStr,
2808
+ refCountBytesOffset);
2809
+ if (fieldRefCountBytes > 0 ) {
2810
+ flags |= fieldFlags;
2811
+ memcpy (layoutStr + layoutStrOffset,
2812
+ fieldLayoutStr + layoutStringHeaderSize,
2813
+ fieldRefCountBytes);
2814
+
2815
+ if (fieldFlags & LayoutStringFlags::HasRelativePointers) {
2816
+ swift_resolve_resilientAccessors (layoutStr, layoutStrOffset,
2817
+ fieldLayoutStr, fieldType);
2818
+ }
2819
+
2820
+ if (offset) {
2821
+ auto layoutStrOffsetCopy = layoutStrOffset;
2822
+ auto firstTagAndOffset =
2823
+ readBytes<uint64_t >(layoutStr, layoutStrOffsetCopy);
2824
+ layoutStrOffsetCopy = layoutStrOffset;
2825
+ firstTagAndOffset += offset;
2826
+ writeBytes (layoutStr, layoutStrOffsetCopy, firstTagAndOffset);
2827
+ }
2828
+
2829
+ auto previousFieldOffsetOffset =
2830
+ layoutStringHeaderSize + fieldRefCountBytes;
2831
+ previousFieldOffset = readBytes<uint64_t >(fieldLayoutStr,
2832
+ previousFieldOffsetOffset);
2833
+ layoutStrOffset += fieldRefCountBytes;
2834
+ } else {
2835
+ previousFieldOffset += fieldType->vw_size ();
2836
+ }
2837
+ fullOffset += fieldType->vw_size ();
2838
+ } else if (auto *tuple = dyn_cast<TupleTypeMetadata>(fieldType)) {
2839
+ for (InProcess::StoredSize i = 0 ; i < tuple->NumElements ; i++) {
2840
+ _swift_addRefCountStringForMetatype (layoutStr, layoutStrOffset, flags,
2841
+ tuple->getElement (i).Type , fullOffset,
2842
+ previousFieldOffset);
2843
+ }
2844
+ } else if (auto *cls = fieldType->getClassObject ()) {
2845
+ RefCountingKind tag;
2846
+ if (!cls->isTypeMetadata ()) {
2847
+ #if SWIFT_OBJC_INTEROP
2848
+ tag = RefCountingKind::ObjC;
2849
+ #else
2850
+ tag = RefCountingKind::Unknown;
2851
+ #endif
2852
+ } else {
2853
+ auto *vwt = cls->getValueWitnesses ();
2854
+ if (vwt == &VALUE_WITNESS_SYM (Bo)) {
2855
+ tag = RefCountingKind::NativeStrong;
2856
+ } else if (vwt == &VALUE_WITNESS_SYM (BO)) {
2857
+ #if SWIFT_OBJC_INTEROP
2858
+ tag = RefCountingKind::ObjC;
2859
+ #else
2860
+ tag = RefCountingKind::Unknown;
2861
+ #endif
2862
+ } else if (vwt == &VALUE_WITNESS_SYM (Bb)) {
2863
+ tag = RefCountingKind::Bridge;
2864
+ } else {
2865
+ goto metadata;
2866
+ };
2867
+ }
2868
+
2869
+ writeBytes (layoutStr, layoutStrOffset, ((uint64_t )tag << 56 ) | offset);
2870
+ previousFieldOffset = fieldType->vw_size ();
2871
+ fullOffset += previousFieldOffset;
2872
+ } else if (fieldType->isAnyExistentialType ()) {
2873
+ auto *existential = dyn_cast<ExistentialTypeMetadata>(fieldType);
2874
+ assert (existential);
2875
+ auto tag = existential->isClassBounded () ? RefCountingKind::Unknown
2876
+ : RefCountingKind::Existential;
2877
+ writeBytes (layoutStr, layoutStrOffset, ((uint64_t )tag << 56 ) | offset);
2878
+ previousFieldOffset = fieldType->vw_size ();
2879
+ fullOffset += previousFieldOffset;
2880
+ } else {
2881
+ metadata:
2882
+ writeBytes (layoutStr, layoutStrOffset,
2883
+ ((uint64_t )RefCountingKind::Metatype << 56 ) | offset);
2884
+ writeBytes (layoutStr, layoutStrOffset, fieldType);
2885
+ previousFieldOffset = fieldType->vw_size ();
2886
+ fullOffset += previousFieldOffset;
2887
+ }
2888
+ }
2889
+
2899
2890
/* **************************************************************************/
2900
2891
/* ** Classes ***************************************************************/
2901
2892
/* **************************************************************************/
0 commit comments