Skip to content

Commit 01acda7

Browse files
committed
Runtime: Remove linear order on metadata cache keys
1 parent affc232 commit 01acda7

File tree

3 files changed

+63
-129
lines changed

3 files changed

+63
-129
lines changed

include/swift/Runtime/Concurrent.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,6 @@
3333

3434
namespace swift {
3535

36-
/// A utility function for ordering two integers, which is useful
37-
/// for implementing compareWithKey.
38-
template <class T>
39-
static inline int compareIntegers(T left, T right) {
40-
return (left == right ? 0 : left < right ? -1 : 1);
41-
}
42-
43-
/// A utility function for ordering two pointers, which is useful
44-
/// for implementing compareWithKey.
45-
template <class T>
46-
static inline int comparePointers(const T *left, const T *right) {
47-
return (left == right ? 0 : std::less<const T *>()(left, right) ? -1 : 1);
48-
}
49-
5036
/// A simple linked list representing pointers that need to be freed. This is
5137
/// not a concurrent data structure, just a bit of support used in the types
5238
/// below.

stdlib/public/runtime/Metadata.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6372,7 +6372,7 @@ bool swift::swift_compareProtocolConformanceDescriptors(
63726372
rhs = swift_auth_data_non_address(
63736373
rhs, SpecialPointerAuthDiscriminators::ProtocolConformanceDescriptor);
63746374

6375-
return MetadataCacheKey::compareProtocolConformanceDescriptors(lhs, rhs) == 0;
6375+
return MetadataCacheKey::areConformanceDescriptorsEqual(lhs, rhs);
63766376
}
63776377

63786378
/***************************************************************************/

stdlib/public/runtime/MetadataCache.h

Lines changed: 62 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -492,36 +492,6 @@ struct GenericSignatureLayout {
492492
const GenericSignatureLayout<Runtime> &rhs) {
493493
return !(lhs == rhs);
494494
}
495-
496-
int compare(const GenericSignatureLayout<Runtime> &rhs) const {
497-
if (auto result = compareIntegers(NumKeyParameters, rhs.NumKeyParameters))
498-
return result;
499-
500-
if (auto result = compareIntegers(NumWitnessTables, rhs.NumWitnessTables))
501-
return result;
502-
503-
if (auto result = compareIntegers(NumShapeClasses, rhs.NumShapeClasses))
504-
return result;
505-
506-
if (auto result = compareIntegers(NumPacks, rhs.NumPacks))
507-
return result;
508-
509-
for (unsigned i = 0; i < NumPacks; ++i) {
510-
const auto &lhsElt = PackShapeDescriptors[i];
511-
const auto &rhsElt = rhs.PackShapeDescriptors[i];
512-
513-
if (auto result = compareIntegers(lhsElt.Kind, rhsElt.Kind))
514-
return result;
515-
516-
if (auto result = compareIntegers(lhsElt.Index, rhsElt.Index))
517-
return result;
518-
519-
if (auto result = compareIntegers(lhsElt.ShapeClass, rhsElt.ShapeClass))
520-
return result;
521-
}
522-
523-
return 0;
524-
}
525495
};
526496

527497
/// A key value as provided to the concurrent map.
@@ -532,10 +502,10 @@ class MetadataCacheKey {
532502

533503
/// Compare two witness tables, which may involving checking the
534504
/// contents of their conformance descriptors.
535-
static int compareWitnessTables(const WitnessTable *awt,
536-
const WitnessTable *bwt) {
505+
static bool areWitnessTablesEqual(const WitnessTable *awt,
506+
const WitnessTable *bwt) {
537507
if (awt == bwt)
538-
return 0;
508+
return true;
539509
#if SWIFT_STDLIB_USE_RELATIVE_PROTOCOL_WITNESS_TABLES
540510
auto *aDescription = lookThroughOptionalConditionalWitnessTable(
541511
reinterpret_cast<const RelativeWitnessTable*>(awt))->getDescription();
@@ -545,37 +515,34 @@ class MetadataCacheKey {
545515
auto *aDescription = awt->getDescription();
546516
auto *bDescription = bwt->getDescription();
547517
#endif
548-
return compareProtocolConformanceDescriptors(aDescription, bDescription);
518+
return areConformanceDescriptorsEqual(aDescription, bDescription);
549519
}
550520

551521
public:
552522
/// Compare two conformance descriptors, checking their contents if necessary.
553-
static int compareProtocolConformanceDescriptors(
523+
static bool areConformanceDescriptorsEqual(
554524
const ProtocolConformanceDescriptor *aDescription,
555525
const ProtocolConformanceDescriptor *bDescription) {
556526
if (aDescription == bDescription)
557-
return 0;
527+
return true;
558528

559529
if (!aDescription->isSynthesizedNonUnique() ||
560530
!bDescription->isSynthesizedNonUnique())
561-
return comparePointers(aDescription, bDescription);
531+
return aDescription == bDescription;
562532

563533
auto aType = aDescription->getCanonicalTypeMetadata();
564534
auto bType = bDescription->getCanonicalTypeMetadata();
565535
if (!aType || !bType)
566-
return comparePointers(aDescription, bDescription);
536+
return aDescription == bDescription;
567537

568-
if (int result = comparePointers(aType, bType))
569-
return result;
570-
571-
return comparePointers(aDescription->getProtocol(),
572-
bDescription->getProtocol());
538+
return (aType == bType &&
539+
aDescription->getProtocol() == bDescription->getProtocol());
573540
}
574541

575542
private:
576-
static int compareMetadataPacks(const void *lhsPtr,
577-
const void *rhsPtr,
578-
uintptr_t count) {
543+
static bool areMetadataPacksEqual(const void *lhsPtr,
544+
const void *rhsPtr,
545+
uintptr_t count) {
579546
MetadataPackPointer lhs(lhsPtr);
580547
MetadataPackPointer rhs(rhsPtr);
581548

@@ -586,16 +553,16 @@ class MetadataCacheKey {
586553
auto *rhsElt = rhs.getElements();
587554

588555
for (uintptr_t i = 0; i < count; ++i) {
589-
if (auto result = comparePointers(lhsElt[i], rhsElt[i]))
590-
return result;
556+
if (lhsElt[i] != rhsElt[i])
557+
return false;
591558
}
592559

593-
return 0;
560+
return true;
594561
}
595562

596-
static int compareWitnessTablePacks(const void *lhsPtr,
597-
const void *rhsPtr,
598-
uintptr_t count) {
563+
static bool areWitnessTablePacksEqual(const void *lhsPtr,
564+
const void *rhsPtr,
565+
uintptr_t count) {
599566
WitnessTablePackPointer lhs(lhsPtr);
600567
WitnessTablePackPointer rhs(rhsPtr);
601568

@@ -606,107 +573,88 @@ class MetadataCacheKey {
606573
auto *rhsElt = rhs.getElements();
607574

608575
for (uintptr_t i = 0; i < count; ++i) {
609-
if (auto result = compareWitnessTables(lhsElt[i], rhsElt[i]))
610-
return result;
576+
if (!areWitnessTablesEqual(lhsElt[i], rhsElt[i]))
577+
return false;
611578
}
612579

613-
return 0;
580+
return true;
614581
}
615582

616-
/// Compare the content from two keys.
617-
static int compareContent(const void *const *adata, const void *const *bdata,
618-
const GenericSignatureLayout<InProcess> &layout) {
583+
public:
584+
MetadataCacheKey(const GenericSignatureLayout<InProcess> &layout,
585+
const void *const *data)
586+
: Data(data), Layout(layout), Hash(computeHash()) {}
587+
588+
MetadataCacheKey(const GenericSignatureLayout<InProcess> &layout,
589+
const void *const *data, uint32_t hash)
590+
: Data(data), Layout(layout), Hash(hash) {}
591+
592+
bool operator==(MetadataCacheKey rhs) const {
593+
// Compare the hashes.
594+
if (hash() != rhs.hash()) return false;
595+
596+
// Compare the layouts.
597+
if (Layout != rhs.Layout) return false;
598+
599+
// Compare the content.
600+
auto *adata = begin();
601+
auto *bdata = rhs.begin();
619602
const uintptr_t *packCounts = reinterpret_cast<const uintptr_t *>(adata);
620603

621604
// Compare pack lengths for shape classes.
622-
for (unsigned i = 0; i != layout.NumShapeClasses; ++i) {
623-
if (auto result = compareIntegers(reinterpret_cast<uintptr_t>(*adata++),
624-
reinterpret_cast<uintptr_t>(*bdata++)))
625-
return result;
605+
for (unsigned i = 0; i != Layout.NumShapeClasses; ++i) {
606+
if (*adata++ != *bdata++)
607+
return false;
626608
}
627609

628-
auto *nextPack = layout.PackShapeDescriptors;
610+
auto *nextPack = Layout.PackShapeDescriptors;
629611
unsigned numPacks = 0;
630612

631613
// Compare generic arguments for key parameters.
632-
for (unsigned i = 0; i != layout.NumKeyParameters; ++i) {
614+
for (unsigned i = 0; i != Layout.NumKeyParameters; ++i) {
633615
// Is this entry a metadata pack?
634-
if (numPacks < layout.NumPacks &&
616+
if (numPacks < Layout.NumPacks &&
635617
nextPack->Kind == GenericPackKind::Metadata &&
636618
i == nextPack->Index) {
637-
assert(nextPack->ShapeClass < layout.NumShapeClasses);
619+
assert(nextPack->ShapeClass < Layout.NumShapeClasses);
638620
uintptr_t count = packCounts[nextPack->ShapeClass];
639621
++numPacks;
640622
++nextPack;
641623

642-
if (auto result = compareMetadataPacks(*adata++, *bdata++, count))
643-
return result;
624+
if (!areMetadataPacksEqual(*adata++, *bdata++, count))
625+
return false;
644626

645627
continue;
646628
}
647629

648-
if (auto result = comparePointers(*adata++, *bdata++))
649-
return result;
630+
if (*adata++ != *bdata++)
631+
return false;
650632
}
651633

652634
// Compare witness tables.
653-
for (unsigned i = 0; i != layout.NumWitnessTables; ++i) {
635+
for (unsigned i = 0; i != Layout.NumWitnessTables; ++i) {
654636
// Is this entry a witness table pack?
655-
if (numPacks < layout.NumPacks &&
637+
if (numPacks < Layout.NumPacks &&
656638
nextPack->Kind == GenericPackKind::WitnessTable &&
657639
i == nextPack->Index) {
658-
assert(nextPack->ShapeClass < layout.NumShapeClasses);
640+
assert(nextPack->ShapeClass < Layout.NumShapeClasses);
659641
uintptr_t count = packCounts[nextPack->ShapeClass];
660642
++numPacks;
661643
++nextPack;
662644

663-
if (auto result = compareWitnessTablePacks(*adata++, *bdata++, count))
664-
return result;
645+
if (!areWitnessTablePacksEqual(*adata++, *bdata++, count))
646+
return false;
665647

666648
continue;
667649
}
668650

669-
if (auto result =
670-
compareWitnessTables((const WitnessTable *)*adata++,
671-
(const WitnessTable *)*bdata++))
672-
return result;
651+
if (!areWitnessTablesEqual((const WitnessTable *)*adata++,
652+
(const WitnessTable *)*bdata++))
653+
return false;
673654
}
674655

675-
assert(numPacks == layout.NumPacks && "Missed a pack");
676-
return 0;
677-
}
678-
679-
public:
680-
MetadataCacheKey(const GenericSignatureLayout<InProcess> &layout,
681-
const void *const *data)
682-
: Data(data), Layout(layout), Hash(computeHash()) {}
683-
684-
MetadataCacheKey(const GenericSignatureLayout<InProcess> &layout,
685-
const void *const *data, uint32_t hash)
686-
: Data(data), Layout(layout), Hash(hash) {}
687-
688-
bool operator==(MetadataCacheKey rhs) const {
689-
// Compare the hashes.
690-
if (hash() != rhs.hash()) return false;
691-
692-
// Compare the layouts.
693-
if (Layout != rhs.Layout) return false;
694-
695-
// Compare the content.
696-
return compareContent(begin(), rhs.begin(), Layout) == 0;
697-
}
698-
699-
int compare(const MetadataCacheKey &rhs) const {
700-
// Compare the hashes.
701-
if (auto result = compareIntegers(Hash, rhs.Hash))
702-
return result;
703-
704-
// Compare the layouts.
705-
if (auto result = Layout.compare(rhs.Layout))
706-
return result;
707-
708-
// Compare the content.
709-
return compareContent(begin(), rhs.begin(), Layout);
656+
assert(numPacks == Layout.NumPacks && "Missed a pack");
657+
return true;
710658
}
711659

712660
uint32_t hash() const {

0 commit comments

Comments
 (0)