@@ -398,11 +398,43 @@ class SimpleLockingCacheEntryBase {
398398 }
399399};
400400
401+ // / A summary of the information from a generic signature that's
402+ // / sufficient to compare arguments.
403+ struct GenericSignatureLayout {
404+ uint16_t NumKeyParameters = 0 ;
405+ uint16_t NumWitnessTables = 0 ;
406+
407+ GenericSignatureLayout (const RuntimeGenericSignature &sig) {
408+ for (const auto &gp : sig.getParams ()) {
409+ if (gp.hasKeyArgument ())
410+ ++NumKeyParameters;
411+ }
412+ for (const auto &reqt : sig.getRequirements ()) {
413+ if (reqt.Flags .hasKeyArgument () &&
414+ reqt.getKind () == GenericRequirementKind::Protocol)
415+ ++NumWitnessTables;
416+ }
417+ }
418+
419+ size_t sizeInWords () const {
420+ return NumKeyParameters + NumWitnessTables;
421+ }
422+
423+ friend bool operator ==(const GenericSignatureLayout &lhs,
424+ const GenericSignatureLayout &rhs) {
425+ return lhs.NumKeyParameters == rhs.NumKeyParameters &&
426+ lhs.NumWitnessTables == rhs.NumWitnessTables ;
427+ }
428+ friend bool operator !=(const GenericSignatureLayout &lhs,
429+ const GenericSignatureLayout &rhs) {
430+ return !(lhs == rhs);
431+ }
432+ };
433+
401434// / A key value as provided to the concurrent map.
402435class MetadataCacheKey {
403436 const void * const *Data;
404- uint16_t NumKeyParameters;
405- uint16_t NumWitnessTables;
437+ GenericSignatureLayout Layout;
406438 uint32_t Hash;
407439
408440 // / Compare two witness tables, which may involving checking the
@@ -445,16 +477,15 @@ class MetadataCacheKey {
445477 // / Compare the content from two keys.
446478 static int compareContent (const void * const *adata,
447479 const void * const *bdata,
448- unsigned numKeyParameters,
449- unsigned numWitnessTables) {
480+ const GenericSignatureLayout &layout) {
450481 // Compare generic arguments for key parameters.
451- for (unsigned i = 0 ; i != numKeyParameters ; ++i) {
482+ for (unsigned i = 0 ; i != layout. NumKeyParameters ; ++i) {
452483 if (auto result = comparePointers (*adata++, *bdata++))
453484 return result;
454485 }
455486
456487 // Compare witness tables.
457- for (unsigned i = 0 ; i != numWitnessTables ; ++i) {
488+ for (unsigned i = 0 ; i != layout. NumWitnessTables ; ++i) {
458489 if (auto result =
459490 compareWitnessTables ((const WitnessTable *)*adata++,
460491 (const WitnessTable *)*bdata++))
@@ -465,30 +496,24 @@ class MetadataCacheKey {
465496 }
466497
467498public:
468- MetadataCacheKey (uint16_t numKeyParams,
469- uint16_t numWitnessTables,
499+ MetadataCacheKey (const GenericSignatureLayout &layout,
470500 const void * const *data)
471- : Data(data), NumKeyParameters(numKeyParams),
472- NumWitnessTables (numWitnessTables), Hash(computeHash()) { }
501+ : Data(data), Layout(layout), Hash(computeHash()) { }
473502
474- MetadataCacheKey (uint16_t numKeyParams,
475- uint16_t numWitnessTables,
503+ MetadataCacheKey (const GenericSignatureLayout &layout,
476504 const void * const *data,
477505 uint32_t hash)
478- : Data(data), NumKeyParameters(numKeyParams),
479- NumWitnessTables(numWitnessTables), Hash(hash) {}
506+ : Data(data), Layout(layout), Hash(hash) {}
480507
481508 bool operator ==(MetadataCacheKey rhs) const {
482509 // Compare the hashes.
483510 if (hash () != rhs.hash ()) return false ;
484511
485512 // Compare the sizes.
486- if (NumKeyParameters != rhs.NumKeyParameters ) return false ;
487- if (NumWitnessTables != rhs.NumWitnessTables ) return false ;
513+ if (Layout != rhs.Layout ) return false ;
488514
489515 // Compare the content.
490- return compareContent (begin (), rhs.begin (), NumKeyParameters,
491- NumWitnessTables) == 0 ;
516+ return compareContent (begin (), rhs.begin (), Layout) == 0 ;
492517 }
493518
494519 int compare (const MetadataCacheKey &rhs) const {
@@ -499,40 +524,47 @@ class MetadataCacheKey {
499524
500525 // Compare the # of key parameters.
501526 if (auto keyParamsComparison =
502- compareIntegers (NumKeyParameters, rhs.NumKeyParameters )) {
527+ compareIntegers (Layout.NumKeyParameters ,
528+ rhs.Layout .NumKeyParameters )) {
503529 return keyParamsComparison;
504530 }
505531
506532 // Compare the # of witness tables.
507533 if (auto witnessTablesComparison =
508- compareIntegers (NumWitnessTables, rhs.NumWitnessTables )) {
534+ compareIntegers (Layout.NumWitnessTables ,
535+ rhs.Layout .NumWitnessTables )) {
509536 return witnessTablesComparison;
510537 }
511538
512539 // Compare the content.
513- return compareContent (begin (), rhs.begin (), NumKeyParameters,
514- NumWitnessTables);
540+ return compareContent (begin (), rhs.begin (), Layout);
515541 }
516542
517- uint16_t numKeyParameters () const { return NumKeyParameters; }
518- uint16_t numWitnessTables () const { return NumWitnessTables; }
519-
520543 uint32_t hash () const {
521544 return Hash;
522545 }
523546
547+ const GenericSignatureLayout &layout () const {
548+ return Layout;
549+ }
550+
524551 friend llvm::hash_code hash_value (const MetadataCacheKey &key) {
525552 return key.Hash ;
526553 }
527554
528555 const void * const *begin () const { return Data; }
529556 const void * const *end () const { return Data + size (); }
530- unsigned size () const { return NumKeyParameters + NumWitnessTables; }
557+ unsigned size () const { return Layout.sizeInWords (); }
558+
559+ void installInto (const void **buffer) const {
560+ // FIXME: variadic-parameter-packs
561+ memcpy (buffer, Data, size () * sizeof (const void *));
562+ }
531563
532564private:
533565 uint32_t computeHash () const {
534- size_t H = 0x56ba80d1u * NumKeyParameters;
535- for (unsigned index = 0 ; index != NumKeyParameters; ++index) {
566+ size_t H = 0x56ba80d1u * Layout. NumKeyParameters ;
567+ for (unsigned index = 0 ; index != Layout. NumKeyParameters ; ++index) {
536568 H = (H >> 10 ) | (H << ((sizeof (size_t ) * 8 ) - 10 ));
537569 H ^= (reinterpret_cast <size_t >(Data[index])
538570 ^ (reinterpret_cast <size_t >(Data[index]) >> 19 ));
@@ -1331,7 +1363,7 @@ class VariadicMetadataCacheEntryBase :
13311363 using OverloadToken = typename TrailingObjects::template OverloadToken<T>;
13321364
13331365 size_t numTrailingObjects (OverloadToken<const void *>) const {
1334- return NumKeyParameters + NumWitnessTables ;
1366+ return Layout. sizeInWords () ;
13351367 }
13361368
13371369 template <class ... Args>
@@ -1343,8 +1375,7 @@ class VariadicMetadataCacheEntryBase :
13431375
13441376private:
13451377 // / These are set during construction and never changed.
1346- const uint16_t NumKeyParameters;
1347- const uint16_t NumWitnessTables;
1378+ const GenericSignatureLayout Layout;
13481379 const uint32_t Hash;
13491380
13501381 // / Valid if TrackingInfo.getState() >= PrivateMetadataState::Abstract.
@@ -1364,18 +1395,16 @@ class VariadicMetadataCacheEntryBase :
13641395 PrivateMetadataState initialState,
13651396 ValueType value)
13661397 : super(worker, initialState),
1367- NumKeyParameters (key.numKeyParameters()),
1368- NumWitnessTables(key.numWitnessTables()),
1398+ Layout (key.layout()),
13691399 Hash(key.hash()),
13701400 Value(value) {
13711401 assert ((value != nullptr ) ==
13721402 (initialState != PrivateMetadataState::Allocating));
1373- memcpy (this ->template getTrailingObjects <const void *>(),
1374- key.begin (), key.size () * sizeof (const void *));
1403+ key.installInto (this ->template getTrailingObjects <const void *>());
13751404 }
13761405
13771406 MetadataCacheKey getKey () const {
1378- return MetadataCacheKey (NumKeyParameters, NumWitnessTables ,
1407+ return MetadataCacheKey (Layout ,
13791408 this ->template getTrailingObjects <const void *>(),
13801409 Hash);
13811410 }
0 commit comments