@@ -411,28 +411,83 @@ template<typename Runtime>
411
411
struct GenericSignatureLayout {
412
412
uint16_t NumKeyParameters = 0 ;
413
413
uint16_t NumWitnessTables = 0 ;
414
+ uint16_t NumPacks = 0 ;
415
+ uint16_t NumShapeClasses = 0 ;
416
+ const GenericPackShapeDescriptor *PackShapeDescriptors = nullptr ;
417
+
418
+ GenericSignatureLayout (const RuntimeGenericSignature<Runtime> &sig)
419
+ : NumPacks(sig.getGenericPackShapeHeader().NumPacks),
420
+ NumShapeClasses (sig.getGenericPackShapeHeader().NumShapeClasses),
421
+ PackShapeDescriptors(sig.getGenericPackShapeDescriptors().data()) {
422
+
423
+ #ifndef NDEBUG
424
+ unsigned numPacks = 0 ;
425
+ #endif
414
426
415
- GenericSignatureLayout (const RuntimeGenericSignature<Runtime> &sig) {
416
427
for (const auto &gp : sig.getParams ()) {
417
- if (gp.hasKeyArgument ())
428
+ if (gp.hasKeyArgument ()) {
418
429
++NumKeyParameters;
430
+
431
+ #ifndef NDEBUG
432
+ if (gp.getKind () == GenericParamKind::TypePack) {
433
+ assert (PackShapeDescriptors[numPacks].Kind
434
+ == GenericPackKind::Metadata);
435
+ assert (PackShapeDescriptors[numPacks].Index
436
+ == NumKeyParameters);
437
+ assert (PackShapeDescriptors[numPacks].ShapeClass
438
+ < NumShapeClasses);
439
+ ++numPacks;
440
+ }
441
+ #endif
442
+ }
419
443
}
420
444
for (const auto &reqt : sig.getRequirements ()) {
421
445
if (reqt.Flags .hasKeyArgument () &&
422
- reqt.getKind () == GenericRequirementKind::Protocol)
446
+ reqt.getKind () == GenericRequirementKind::Protocol) {
447
+ #ifndef NDEBUG
448
+ if (reqt.getFlags ().isPackRequirement ()) {
449
+ assert (PackShapeDescriptors[numPacks].Kind
450
+ == GenericPackKind::WitnessTable);
451
+ assert (PackShapeDescriptors[numPacks].Index
452
+ == NumKeyParameters + NumWitnessTables);
453
+ assert (PackShapeDescriptors[numPacks].ShapeClass
454
+ < NumShapeClasses);
455
+ ++numPacks;
456
+ }
457
+ #endif
458
+
423
459
++NumWitnessTables;
460
+ }
424
461
}
462
+
463
+ assert (numPacks == NumPacks);
425
464
}
426
465
427
466
size_t sizeInWords () const {
428
- return NumKeyParameters + NumWitnessTables;
467
+ return NumShapeClasses + NumKeyParameters + NumWitnessTables;
429
468
}
430
469
431
470
friend bool operator ==(const GenericSignatureLayout<Runtime> &lhs,
432
471
const GenericSignatureLayout<Runtime> &rhs) {
433
- return lhs.NumKeyParameters == rhs.NumKeyParameters &&
434
- lhs.NumWitnessTables == rhs.NumWitnessTables ;
472
+ if (lhs.NumKeyParameters != rhs.NumKeyParameters ||
473
+ lhs.NumWitnessTables != rhs.NumWitnessTables ||
474
+ lhs.NumShapeClasses != rhs.NumShapeClasses ||
475
+ lhs.NumPacks != rhs.NumPacks ) {
476
+ return false ;
477
+ }
478
+
479
+ for (unsigned i = 0 ; i < lhs.NumPacks ; ++i) {
480
+ const auto &lhsElt = lhs.PackShapeDescriptors [i];
481
+ const auto &rhsElt = rhs.PackShapeDescriptors [i];
482
+ if (lhsElt.Kind != rhsElt.Kind ||
483
+ lhsElt.Index != rhsElt.Index ||
484
+ lhsElt.ShapeClass != rhsElt.ShapeClass )
485
+ return false ;
486
+ }
487
+
488
+ return true ;
435
489
}
490
+
436
491
friend bool operator !=(const GenericSignatureLayout<Runtime> &lhs,
437
492
const GenericSignatureLayout<Runtime> &rhs) {
438
493
return !(lhs == rhs);
@@ -445,6 +500,26 @@ struct GenericSignatureLayout {
445
500
if (auto result = compareIntegers (NumWitnessTables, rhs.NumWitnessTables ))
446
501
return result;
447
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
+
448
523
return 0 ;
449
524
}
450
525
};
@@ -498,23 +573,106 @@ class MetadataCacheKey {
498
573
}
499
574
500
575
private:
576
+ static int compareMetadataPacks (const void *lhsPtr,
577
+ const void *rhsPtr,
578
+ uintptr_t count) {
579
+ MetadataPackPointer lhs (lhsPtr);
580
+ MetadataPackPointer rhs (rhsPtr);
581
+
582
+ assert (lhs.getLifetime () == PackLifetime::OnHeap);
583
+ assert (rhs.getLifetime () == PackLifetime::OnHeap);
584
+
585
+ auto *lhsElt = lhs.getElements ();
586
+ auto *rhsElt = rhs.getElements ();
587
+
588
+ for (uintptr_t i = 0 ; i < count; ++i) {
589
+ if (auto result = comparePointers (lhsElt[i], rhsElt[i]))
590
+ return result;
591
+ }
592
+
593
+ return 0 ;
594
+ }
595
+
596
+ static int compareWitnessTablePacks (const void *lhsPtr,
597
+ const void *rhsPtr,
598
+ uintptr_t count) {
599
+ WitnessTablePackPointer lhs (lhsPtr);
600
+ WitnessTablePackPointer rhs (rhsPtr);
601
+
602
+ assert (lhs.getLifetime () == PackLifetime::OnHeap);
603
+ assert (rhs.getLifetime () == PackLifetime::OnHeap);
604
+
605
+ auto *lhsElt = lhs.getElements ();
606
+ auto *rhsElt = rhs.getElements ();
607
+
608
+ for (uintptr_t i = 0 ; i < count; ++i) {
609
+ if (auto result = compareWitnessTables (lhsElt[i], rhsElt[i]))
610
+ return result;
611
+ }
612
+
613
+ return 0 ;
614
+ }
615
+
501
616
// / Compare the content from two keys.
502
617
static int compareContent (const void *const *adata, const void *const *bdata,
503
618
const GenericSignatureLayout<InProcess> &layout) {
619
+ const uintptr_t *packCounts = reinterpret_cast <const uintptr_t *>(adata);
620
+
621
+ // 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;
626
+ }
627
+
628
+ auto *nextPack = layout.PackShapeDescriptors ;
629
+ unsigned numPacks = 0 ;
630
+
504
631
// Compare generic arguments for key parameters.
505
632
for (unsigned i = 0 ; i != layout.NumKeyParameters ; ++i) {
633
+ // Is this entry a metadata pack?
634
+ if (numPacks < layout.NumPacks &&
635
+ nextPack->Kind == GenericPackKind::Metadata &&
636
+ i == nextPack->Index ) {
637
+ assert (nextPack->ShapeClass < layout.NumShapeClasses );
638
+ uintptr_t count = packCounts[nextPack->ShapeClass ];
639
+ ++numPacks;
640
+ ++nextPack;
641
+
642
+ if (auto result = compareMetadataPacks (*adata++, *bdata++, count))
643
+ return result;
644
+
645
+ continue ;
646
+ }
647
+
506
648
if (auto result = comparePointers (*adata++, *bdata++))
507
649
return result;
508
650
}
509
651
510
652
// Compare witness tables.
511
653
for (unsigned i = 0 ; i != layout.NumWitnessTables ; ++i) {
654
+ // Is this entry a witness table pack?
655
+ if (numPacks < layout.NumPacks &&
656
+ nextPack->Kind == GenericPackKind::WitnessTable &&
657
+ i == nextPack->Index ) {
658
+ assert (nextPack->ShapeClass < layout.NumShapeClasses );
659
+ uintptr_t count = packCounts[nextPack->ShapeClass ];
660
+ ++numPacks;
661
+ ++nextPack;
662
+
663
+ if (auto result = compareWitnessTablePacks (*adata++, *bdata++, count))
664
+ return result;
665
+
666
+ continue ;
667
+ }
668
+
512
669
if (auto result =
513
670
compareWitnessTables ((const WitnessTable *)*adata++,
514
671
(const WitnessTable *)*bdata++))
515
672
return result;
516
673
}
517
674
675
+ assert (numPacks == layout.NumPacks && " Missed a pack" );
518
676
return 0 ;
519
677
}
520
678
@@ -573,16 +731,41 @@ class MetadataCacheKey {
573
731
private:
574
732
uint32_t computeHash () const {
575
733
size_t H = 0x56ba80d1u * Layout.NumKeyParameters ;
576
- for (unsigned index = 0 ; index != Layout.NumKeyParameters ; ++index) {
577
- H = (H >> 10 ) | (H << ((sizeof (size_t ) * 8 ) - 10 ));
578
- H ^= (reinterpret_cast <size_t >(Data[index])
579
- ^ (reinterpret_cast <size_t >(Data[index]) >> 19 ));
734
+
735
+ auto *nextPack = Layout.PackShapeDescriptors ;
736
+ unsigned numPacks = 0 ;
737
+
738
+ auto update = [&H](uintptr_t value) {
739
+ H = (H >> 10 ) | (H << ((sizeof (uintptr_t ) * 8 ) - 10 ));
740
+ H ^= (value ^ (value >> 19 ));
741
+ };
742
+
743
+ // FIXME: Incorporate NumShapeClasses into the hash
744
+
745
+ for (unsigned i = 0 ; i != Layout.NumKeyParameters ; ++i) {
746
+ // Is this entry a metadata pack?
747
+ if (numPacks < Layout.NumPacks &&
748
+ nextPack->Kind == GenericPackKind::Metadata &&
749
+ i == nextPack->Index ) {
750
+ assert (nextPack->ShapeClass < Layout.NumShapeClasses );
751
+ auto count = reinterpret_cast <uintptr_t >(Data[nextPack->ShapeClass ]);
752
+ ++numPacks;
753
+ ++nextPack;
754
+
755
+ MetadataPackPointer pack (Data[i]);
756
+ for (unsigned j = 0 ; j < count; ++j)
757
+ update (reinterpret_cast <uintptr_t >(pack.getElements ()[j]));
758
+
759
+ continue ;
760
+ }
761
+
762
+ update (reinterpret_cast <uintptr_t >(Data[i]));
580
763
}
581
764
582
765
H *= 0x27d4eb2d ;
583
766
584
767
// Rotate right by 10 and then truncate to 32 bits.
585
- return uint32_t ((H >> 10 ) | (H << ((sizeof (size_t ) * 8 ) - 10 )));
768
+ return uint32_t ((H >> 10 ) | (H << ((sizeof (uintptr_t ) * 8 ) - 10 )));
586
769
}
587
770
};
588
771
0 commit comments