@@ -3301,6 +3301,69 @@ struct TargetForeignMetadataInitialization {
3301
3301
CompletionFunction;
3302
3302
};
3303
3303
3304
+ // / The cache structure for non-trivial initialization of singleton value
3305
+ // / metadata.
3306
+ template <typename Runtime>
3307
+ struct TargetInPlaceValueMetadataCache {
3308
+ // / The metadata pointer. Clients can do dependency-ordered loads
3309
+ // / from this, and if they see a non-zero value, it's a Complete
3310
+ // / metadata.
3311
+ std::atomic<TargetMetadataPointer<Runtime, TargetMetadata>> Metadata;
3312
+
3313
+ // / The private cache data.
3314
+ std::atomic<TargetPointer<Runtime, void >> Private;
3315
+ };
3316
+ using InPlaceValueMetadataCache =
3317
+ TargetInPlaceValueMetadataCache<InProcess>;
3318
+
3319
+ // / An instantiation pattern for non-generic resilient class metadata.
3320
+ // / Used in conjunction with InPlaceValueMetadataInitialization.
3321
+ using MetadataRelocator =
3322
+ Metadata *(const TargetTypeContextDescriptor<InProcess> *description);
3323
+
3324
+ // / The control structure for performing non-trivial initialization of
3325
+ // / singleton value metadata, which is required when e.g. a non-generic
3326
+ // / value type has a resilient component type.
3327
+ template <typename Runtime>
3328
+ struct TargetInPlaceValueMetadataInitialization {
3329
+ // / The initialization cache. Out-of-line because mutable.
3330
+ TargetRelativeDirectPointer<Runtime,
3331
+ TargetInPlaceValueMetadataCache<Runtime>>
3332
+ InitializationCache;
3333
+
3334
+ union {
3335
+ // / The incomplete metadata, for structs, enums and classes without
3336
+ // / resilient ancestry.
3337
+ TargetRelativeDirectPointer<Runtime, TargetMetadata<Runtime>>
3338
+ IncompleteMetadata;
3339
+
3340
+ // / If the class descriptor's hasResilientSuperclass() flag is set,
3341
+ // / this field instead points at a function that allocates metadata
3342
+ // / with the correct size at runtime.
3343
+ TargetRelativeDirectPointer<Runtime, MetadataRelocator>
3344
+ RelocationFunction;
3345
+ };
3346
+
3347
+ // / The completion function. The pattern will always be null.
3348
+ TargetRelativeDirectPointer<Runtime, MetadataCompleter>
3349
+ CompletionFunction;
3350
+
3351
+ bool hasRelocationFunction (
3352
+ const TargetTypeContextDescriptor<Runtime> *description) const {
3353
+ auto *classDescription =
3354
+ dyn_cast<TargetClassDescriptor<Runtime>>(description);
3355
+ return (classDescription != nullptr &&
3356
+ classDescription->hasResilientSuperclass ());
3357
+ }
3358
+
3359
+ TargetMetadata<Runtime> *allocate (
3360
+ const TargetTypeContextDescriptor<Runtime> *description) const {
3361
+ if (hasRelocationFunction (description))
3362
+ return RelocationFunction (description);
3363
+ return IncompleteMetadata.get ();
3364
+ }
3365
+ };
3366
+
3304
3367
template <typename Runtime>
3305
3368
class TargetTypeContextDescriptor
3306
3369
: public TargetContextDescriptor<Runtime> {
@@ -3355,8 +3418,11 @@ class TargetTypeContextDescriptor
3355
3418
const TargetForeignMetadataInitialization<Runtime> &
3356
3419
getForeignMetadataInitialization () const ;
3357
3420
3421
+ const TargetInPlaceValueMetadataInitialization<Runtime> &
3422
+ getInPlaceMetadataInitialization () const ;
3423
+
3358
3424
const TargetTypeGenericContextDescriptorHeader<Runtime> &
3359
- getFullGenericContextHeader () const ;
3425
+ getFullGenericContextHeader () const ;
3360
3426
3361
3427
const TargetGenericContextDescriptorHeader<Runtime> &
3362
3428
getGenericContextHeader () const {
@@ -3479,13 +3545,15 @@ class TargetClassDescriptor final
3479
3545
TargetTypeGenericContextDescriptorHeader,
3480
3546
/* additional trailing objects:*/
3481
3547
TargetForeignMetadataInitialization<Runtime>,
3548
+ TargetInPlaceValueMetadataInitialization<Runtime>,
3482
3549
TargetVTableDescriptorHeader<Runtime>,
3483
3550
TargetMethodDescriptor<Runtime>> {
3484
3551
private:
3485
3552
using TrailingGenericContextObjects =
3486
3553
TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
3487
3554
TargetTypeGenericContextDescriptorHeader,
3488
3555
TargetForeignMetadataInitialization<Runtime>,
3556
+ TargetInPlaceValueMetadataInitialization<Runtime>,
3489
3557
TargetVTableDescriptorHeader<Runtime>,
3490
3558
TargetMethodDescriptor<Runtime>>;
3491
3559
@@ -3498,6 +3566,8 @@ class TargetClassDescriptor final
3498
3566
using VTableDescriptorHeader = TargetVTableDescriptorHeader<Runtime>;
3499
3567
using ForeignMetadataInitialization =
3500
3568
TargetForeignMetadataInitialization<Runtime>;
3569
+ using InPlaceMetadataInitialization =
3570
+ TargetInPlaceValueMetadataInitialization<Runtime>;
3501
3571
3502
3572
using StoredPointer = typename Runtime::StoredPointer;
3503
3573
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
@@ -3589,6 +3659,10 @@ class TargetClassDescriptor final
3589
3659
return this ->hasForeignMetadataInitialization () ? 1 : 0 ;
3590
3660
}
3591
3661
3662
+ size_t numTrailingObjects (OverloadToken<InPlaceMetadataInitialization>) const {
3663
+ return this ->hasInPlaceMetadataInitialization () ? 1 : 0 ;
3664
+ }
3665
+
3592
3666
size_t numTrailingObjects (OverloadToken<VTableDescriptorHeader>) const {
3593
3667
return hasVTable () ? 1 : 0 ;
3594
3668
}
@@ -3606,6 +3680,11 @@ class TargetClassDescriptor final
3606
3680
return *this ->template getTrailingObjects <ForeignMetadataInitialization>();
3607
3681
}
3608
3682
3683
+ const InPlaceMetadataInitialization &getInPlaceMetadataInitialization () const {
3684
+ assert (this ->hasInPlaceMetadataInitialization ());
3685
+ return *this ->template getTrailingObjects <InPlaceMetadataInitialization>();
3686
+ }
3687
+
3609
3688
// / True if metadata records for this type have a field offset vector for
3610
3689
// / its stored properties.
3611
3690
bool hasFieldOffsetVector () const { return FieldOffsetVectorOffset != 0 ; }
@@ -3698,49 +3777,10 @@ class TargetClassDescriptor final
3698
3777
3699
3778
using ClassDescriptor = TargetClassDescriptor<InProcess>;
3700
3779
3701
- // / The cache structure for non-trivial initialization of singleton value
3702
- // / metadata.
3703
- template <typename Runtime>
3704
- struct TargetInPlaceValueMetadataCache {
3705
- // / The metadata pointer. Clients can do dependency-ordered loads
3706
- // / from this, and if they see a non-zero value, it's a Complete
3707
- // / metadata.
3708
- std::atomic<TargetMetadataPointer<Runtime, TargetMetadata>> Metadata;
3709
-
3710
- // / The private cache data.
3711
- std::atomic<TargetPointer<Runtime, void >> Private;
3712
- };
3713
- using InPlaceValueMetadataCache =
3714
- TargetInPlaceValueMetadataCache<InProcess>;
3715
-
3716
- // / The control structure for performing non-trivial initialization of
3717
- // / singleton value metadata, which is required when e.g. a non-generic
3718
- // / value type has a resilient component type.
3719
- template <typename Runtime>
3720
- struct TargetInPlaceValueMetadataInitialization {
3721
- // / The initialization cache. Out-of-line because mutable.
3722
- TargetRelativeDirectPointer<Runtime,
3723
- TargetInPlaceValueMetadataCache<Runtime>>
3724
- InitializationCache;
3725
-
3726
- // / The incomplete metadata.
3727
- TargetRelativeDirectPointer<Runtime, TargetMetadata<Runtime>>
3728
- IncompleteMetadata;
3729
-
3730
- // / The completion function. The pattern will always be null.
3731
- TargetRelativeDirectPointer<Runtime, MetadataCompleter>
3732
- CompletionFunction;
3733
- };
3734
-
3735
3780
template <typename Runtime>
3736
3781
class TargetValueTypeDescriptor
3737
3782
: public TargetTypeContextDescriptor<Runtime> {
3738
3783
public:
3739
- using InPlaceMetadataInitialization =
3740
- TargetInPlaceValueMetadataInitialization<Runtime>;
3741
-
3742
- const InPlaceMetadataInitialization &getInPlaceMetadataInitialization () const ;
3743
-
3744
3784
static bool classof (const TargetContextDescriptor<Runtime> *cd) {
3745
3785
return cd->getKind () == ContextDescriptorKind::Struct ||
3746
3786
cd->getKind () == ContextDescriptorKind::Enum;
@@ -4015,16 +4055,19 @@ TargetTypeContextDescriptor<Runtime>::getForeignMetadataInitialization() const {
4015
4055
4016
4056
template <typename Runtime>
4017
4057
inline const TargetInPlaceValueMetadataInitialization<Runtime> &
4018
- TargetValueTypeDescriptor <Runtime>::getInPlaceMetadataInitialization() const {
4058
+ TargetTypeContextDescriptor <Runtime>::getInPlaceMetadataInitialization() const {
4019
4059
switch (this ->getKind ()) {
4020
4060
case ContextDescriptorKind::Enum:
4021
4061
return llvm::cast<TargetEnumDescriptor<Runtime>>(this )
4022
4062
->getInPlaceMetadataInitialization ();
4023
4063
case ContextDescriptorKind::Struct:
4024
4064
return llvm::cast<TargetStructDescriptor<Runtime>>(this )
4025
4065
->getInPlaceMetadataInitialization ();
4066
+ case ContextDescriptorKind::Class:
4067
+ return llvm::cast<TargetClassDescriptor<Runtime>>(this )
4068
+ ->getInPlaceMetadataInitialization ();
4026
4069
default :
4027
- swift_runtime_unreachable (" Not a value type descriptor." );
4070
+ swift_runtime_unreachable (" Not a enum, struct or class type descriptor." );
4028
4071
}
4029
4072
}
4030
4073
0 commit comments