@@ -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().
@@ -824,16 +820,20 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
824820 return true ;
825821 }
826822
827- void init (unsigned InitNumEntries) {
828- auto InitBuckets = BaseT::getMinBucketToReserveForEntries (InitNumEntries);
829- if (allocateBuckets (InitBuckets)) {
823+ void initWithExactBucketCount (unsigned NewNumBuckets) {
824+ if (allocateBuckets (NewNumBuckets)) {
830825 this ->BaseT ::initEmpty ();
831826 } else {
832827 NumEntries = 0 ;
833828 NumTombstones = 0 ;
834829 }
835830 }
836831
832+ void init (unsigned InitNumEntries) {
833+ auto InitBuckets = BaseT::getMinBucketToReserveForEntries (InitNumEntries);
834+ initWithExactBucketCount (InitBuckets);
835+ }
836+
837837 // Put the zombie instance in a known good state after a move.
838838 void kill () {
839839 deallocateBuckets ();
@@ -842,23 +842,10 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
842842 }
843843
844844 void grow (unsigned AtLeast) {
845- unsigned OldNumBuckets = NumBuckets;
846- BucketT *OldBuckets = Buckets;
847-
848- allocateBuckets (std::max<unsigned >(
849- 64 , static_cast <unsigned >(NextPowerOf2 (AtLeast - 1 ))));
850- assert (Buckets);
851- if (!OldBuckets) {
852- this ->BaseT ::initEmpty ();
853- return ;
854- }
855-
856- this ->moveFromOldBuckets (
857- llvm::make_range (OldBuckets, OldBuckets + OldNumBuckets));
858-
859- // Free the old table.
860- deallocate_buffer (OldBuckets, sizeof (BucketT) * OldNumBuckets,
861- alignof (BucketT));
845+ AtLeast = std::max<unsigned >(64 , NextPowerOf2 (AtLeast - 1 ));
846+ DenseMap Tmp (AtLeast, ExactBucketCount{});
847+ Tmp.moveFrom (*this );
848+ swapImpl (Tmp);
862849 }
863850
864851 // Plan how to shrink the bucket table. Return:
0 commit comments