@@ -413,11 +413,13 @@ class DenseMapBase : public DebugEpochBase {
413413 return NextPowerOf2 (NumEntries * 4 / 3 + 1 );
414414 }
415415
416- void moveFromImpl (iterator_range<BucketT *> OldBuckets) {
416+ // Move key/value from Other to *this.
417+ // Other is left in a valid but empty state.
418+ void moveFrom (DerivedT &Other) {
417419 // Insert all the old elements.
418420 const KeyT EmptyKey = KeyInfoT::getEmptyKey ();
419421 const KeyT TombstoneKey = KeyInfoT::getTombstoneKey ();
420- for (BucketT &B : OldBuckets ) {
422+ for (BucketT &B : Other. buckets () ) {
421423 if (!KeyInfoT::isEqual (B.getFirst (), EmptyKey) &&
422424 !KeyInfoT::isEqual (B.getFirst (), TombstoneKey)) {
423425 // Insert the key/value into the new table.
@@ -434,17 +436,6 @@ class DenseMapBase : public DebugEpochBase {
434436 }
435437 B.getFirst ().~KeyT ();
436438 }
437- }
438-
439- void moveFromOldBuckets (iterator_range<BucketT *> OldBuckets) {
440- initEmpty ();
441- moveFromImpl (OldBuckets);
442- }
443-
444- // Move key/value from Other to *this.
445- // Other is left in a valid but empty state.
446- void moveFrom (DerivedT &Other) {
447- moveFromImpl (Other.buckets ());
448439 Other.derived ().kill ();
449440 }
450441
@@ -738,6 +729,11 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
738729 unsigned NumTombstones;
739730 unsigned NumBuckets;
740731
732+ struct ExactBucketCount {};
733+ explicit DenseMap (unsigned NumBuckets, ExactBucketCount) {
734+ initWithExactBucketCount (NumBuckets);
735+ }
736+
741737public:
742738 // / Create a DenseMap with an optional \p NumElementsToReserve to guarantee
743739 // / that this number of elements can be inserted in the map without grow().
@@ -822,16 +818,20 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
822818 return true ;
823819 }
824820
825- void init (unsigned InitNumEntries) {
826- auto InitBuckets = BaseT::getMinBucketToReserveForEntries (InitNumEntries);
827- if (allocateBuckets (InitBuckets)) {
821+ void initWithExactBucketCount (unsigned NewNumBuckets) {
822+ if (allocateBuckets (NewNumBuckets)) {
828823 this ->BaseT ::initEmpty ();
829824 } else {
830825 NumEntries = 0 ;
831826 NumTombstones = 0 ;
832827 }
833828 }
834829
830+ void init (unsigned InitNumEntries) {
831+ auto InitBuckets = BaseT::getMinBucketToReserveForEntries (InitNumEntries);
832+ initWithExactBucketCount (InitBuckets);
833+ }
834+
835835 // Put the zombie instance in a known good state after a move.
836836 void kill () {
837837 deallocateBuckets ();
@@ -840,23 +840,10 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
840840 }
841841
842842 void grow (unsigned AtLeast) {
843- unsigned OldNumBuckets = NumBuckets;
844- BucketT *OldBuckets = Buckets;
845-
846- allocateBuckets (std::max<unsigned >(
847- 64 , static_cast <unsigned >(NextPowerOf2 (AtLeast - 1 ))));
848- assert (Buckets);
849- if (!OldBuckets) {
850- this ->BaseT ::initEmpty ();
851- return ;
852- }
853-
854- this ->moveFromOldBuckets (
855- llvm::make_range (OldBuckets, OldBuckets + OldNumBuckets));
856-
857- // Free the old table.
858- deallocate_buffer (OldBuckets, sizeof (BucketT) * OldNumBuckets,
859- alignof (BucketT));
843+ AtLeast = std::max<unsigned >(64 , NextPowerOf2 (AtLeast - 1 ));
844+ DenseMap Tmp (AtLeast, ExactBucketCount{});
845+ Tmp.moveFrom (*this );
846+ swapImpl (Tmp);
860847 }
861848
862849 // Plan how to shrink the bucket table. Return:
0 commit comments