23
23
#include " swift/Runtime/Concurrent.h"
24
24
#include " swift/Runtime/HeapObject.h"
25
25
#include " swift/Runtime/Metadata.h"
26
- #include " swift/Runtime/Mutex.h"
27
26
#include " swift/Strings.h"
28
27
#include " llvm/ADT/DenseMap.h"
29
28
#include " llvm/ADT/Optional.h"
@@ -106,11 +105,9 @@ namespace {
106
105
107
106
struct TypeMetadataPrivateState {
108
107
ConcurrentMap<NominalTypeDescriptorCacheEntry> NominalCache;
109
- std::vector<TypeMetadataSection> SectionsToScan;
110
- Mutex SectionsToScanLock;
108
+ ConcurrentReadableArray<TypeMetadataSection> SectionsToScan;
111
109
112
110
TypeMetadataPrivateState () {
113
- SectionsToScan.reserve (16 );
114
111
initializeTypeMetadataRecordLookup ();
115
112
}
116
113
@@ -122,7 +119,6 @@ static void
122
119
_registerTypeMetadataRecords (TypeMetadataPrivateState &T,
123
120
const TypeMetadataRecord *begin,
124
121
const TypeMetadataRecord *end) {
125
- ScopedLock guard (T.SectionsToScanLock );
126
122
T.SectionsToScan .push_back (TypeMetadataSection{begin, end});
127
123
}
128
124
@@ -296,12 +292,9 @@ swift::_contextDescriptorMatchesMangling(const ContextDescriptor *context,
296
292
297
293
// returns the nominal type descriptor for the type named by typeName
298
294
static const TypeContextDescriptor *
299
- _searchTypeMetadataRecords (const TypeMetadataPrivateState &T,
295
+ _searchTypeMetadataRecords (TypeMetadataPrivateState &T,
300
296
Demangle::NodePointer node) {
301
- unsigned sectionIdx = 0 ;
302
- unsigned endSectionIdx = T.SectionsToScan .size ();
303
- for (; sectionIdx < endSectionIdx; ++sectionIdx) {
304
- auto §ion = T.SectionsToScan [sectionIdx];
297
+ for (auto §ion : T.SectionsToScan .snapshot ()) {
305
298
for (const auto &record : section) {
306
299
if (auto ntd = record.getTypeContextDescriptor ()) {
307
300
if (_contextDescriptorMatchesMangling (ntd, node)) {
@@ -342,9 +335,7 @@ _findNominalTypeDescriptor(Demangle::NodePointer node,
342
335
return Value->getDescription ();
343
336
344
337
// Check type metadata records
345
- T.SectionsToScanLock .withLock ([&] {
346
- foundNominal = _searchTypeMetadataRecords (T, node);
347
- });
338
+ foundNominal = _searchTypeMetadataRecords (T, node);
348
339
349
340
// Check protocol conformances table. Note that this has no support for
350
341
// resolving generic types yet.
@@ -395,11 +386,9 @@ namespace {
395
386
396
387
struct ProtocolMetadataPrivateState {
397
388
ConcurrentMap<ProtocolDescriptorCacheEntry> ProtocolCache;
398
- std::vector<ProtocolSection> SectionsToScan;
399
- Mutex SectionsToScanLock;
389
+ ConcurrentReadableArray<ProtocolSection> SectionsToScan;
400
390
401
391
ProtocolMetadataPrivateState () {
402
- SectionsToScan.reserve (16 );
403
392
initializeProtocolLookup ();
404
393
}
405
394
};
@@ -411,7 +400,6 @@ static void
411
400
_registerProtocols (ProtocolMetadataPrivateState &C,
412
401
const ProtocolRecord *begin,
413
402
const ProtocolRecord *end) {
414
- ScopedLock guard (C.SectionsToScanLock );
415
403
C.SectionsToScan .push_back (ProtocolSection{begin, end});
416
404
}
417
405
@@ -439,12 +427,9 @@ void swift::swift_registerProtocols(const ProtocolRecord *begin,
439
427
}
440
428
441
429
static const ProtocolDescriptor *
442
- _searchProtocolRecords (const ProtocolMetadataPrivateState &C,
430
+ _searchProtocolRecords (ProtocolMetadataPrivateState &C,
443
431
const llvm::StringRef protocolName){
444
- unsigned sectionIdx = 0 ;
445
- unsigned endSectionIdx = C.SectionsToScan .size ();
446
- for (; sectionIdx < endSectionIdx; ++sectionIdx) {
447
- auto §ion = C.SectionsToScan [sectionIdx];
432
+ for (auto §ion : C.SectionsToScan .snapshot ()) {
448
433
for (const auto &record : section) {
449
434
if (auto protocol = record.Protocol .getPointer ()) {
450
435
// Drop the "S$" prefix from the protocol record. It's not used in
@@ -472,9 +457,7 @@ _findProtocolDescriptor(llvm::StringRef mangledName) {
472
457
return Value->getDescription ();
473
458
474
459
// Check type metadata records
475
- T.SectionsToScanLock .withLock ([&] {
476
- foundProtocol = _searchProtocolRecords (T, mangledName);
477
- });
460
+ foundProtocol = _searchProtocolRecords (T, mangledName);
478
461
479
462
if (foundProtocol) {
480
463
T.ProtocolCache .getOrInsert (mangledName, foundProtocol);
@@ -534,21 +517,18 @@ class DynamicFieldSection {
534
517
DynamicFieldSection (const FieldDescriptor **fields, size_t size)
535
518
: Begin(fields), End(fields + size) {}
536
519
537
- const FieldDescriptor **begin () { return Begin; }
520
+ const FieldDescriptor **begin () const { return Begin; }
538
521
539
522
const FieldDescriptor **end () const { return End; }
540
523
};
541
524
542
525
struct FieldCacheState {
543
526
ConcurrentMap<FieldDescriptorCacheEntry> FieldCache;
544
527
545
- Mutex SectionsLock;
546
- std::vector<StaticFieldSection> StaticSections;
547
- std::vector<DynamicFieldSection> DynamicSections;
528
+ ConcurrentReadableArray<StaticFieldSection> StaticSections;
529
+ ConcurrentReadableArray<DynamicFieldSection> DynamicSections;
548
530
549
531
FieldCacheState () {
550
- StaticSections.reserve (16 );
551
- DynamicSections.reserve (8 );
552
532
initializeTypeFieldLookup ();
553
533
}
554
534
};
@@ -559,7 +539,6 @@ static Lazy<FieldCacheState> FieldCache;
559
539
void swift::swift_registerFieldDescriptors (const FieldDescriptor **records,
560
540
size_t size) {
561
541
auto &cache = FieldCache.get ();
562
- ScopedLock guard (cache.SectionsLock );
563
542
cache.DynamicSections .push_back ({records, size});
564
543
}
565
544
@@ -570,7 +549,6 @@ void swift::addImageTypeFieldDescriptorBlockCallback(const void *recordsBegin,
570
549
571
550
// Field cache should always be sufficiently initialized by this point.
572
551
auto &cache = FieldCache.unsafeGetAlreadyInitialized ();
573
- ScopedLock guard (cache.SectionsLock );
574
552
cache.StaticSections .push_back ({recordsBegin, recordsEnd});
575
553
}
576
554
@@ -1216,16 +1194,15 @@ void swift::swift_getFieldAt(
1216
1194
return ;
1217
1195
}
1218
1196
1219
- ScopedLock guard (cache.SectionsLock );
1220
1197
// Otherwise let's try to find it in one of the sections.
1221
- for (auto §ion : cache.DynamicSections ) {
1198
+ for (auto §ion : cache.DynamicSections . snapshot () ) {
1222
1199
for (const auto *descriptor : section) {
1223
1200
if (isRequestedDescriptor (*descriptor))
1224
1201
return ;
1225
1202
}
1226
1203
}
1227
1204
1228
- for (const auto §ion : cache.StaticSections ) {
1205
+ for (const auto §ion : cache.StaticSections . snapshot () ) {
1229
1206
for (auto &descriptor : section) {
1230
1207
if (isRequestedDescriptor (descriptor))
1231
1208
return ;
0 commit comments