瀏覽代碼

Remove malloc usages in favor of operator new (#2150)

In a few places, llvm uses malloc instead of operator new, especially with collections that want to avoid calling constructors. In those cases, the allocation won't go through our custom allocator and will crash rather than throw on out-of-memory conditions. This fixes the biggest offenders.
Tristan Labelle 6 年之前
父節點
當前提交
725189cf17

+ 10 - 12
include/llvm/ADT/BitVector.h

@@ -83,7 +83,7 @@ public:
   /// bits are initialized to the specified value.
   /// bits are initialized to the specified value.
   explicit BitVector(unsigned s, bool t = false) : Size(s) {
   explicit BitVector(unsigned s, bool t = false) : Size(s) {
     Capacity = NumBitWords(s);
     Capacity = NumBitWords(s);
-    Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
+    Bits = new BitWord[Capacity]; // HLSL Change: Use overridable operator new
     init_words(Bits, Capacity, t);
     init_words(Bits, Capacity, t);
     if (t)
     if (t)
       clear_unused_bits();
       clear_unused_bits();
@@ -98,8 +98,7 @@ public:
     }
     }
 
 
     Capacity = NumBitWords(RHS.size());
     Capacity = NumBitWords(RHS.size());
-    Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
-	if (Bits == nullptr) throw std::bad_alloc(); // HLSL Change
+    Bits = new BitWord[Capacity]; // HLSL Change: Use overridable operator new
     std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
     std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
   }
   }
 
 
@@ -109,7 +108,7 @@ public:
   }
   }
 
 
   ~BitVector() {
   ~BitVector() {
-    std::free(Bits);
+    delete[] Bits; // HLSL Change: Use overridable operator new
   }
   }
 
 
   /// empty - Tests whether there are no bits in this bitvector.
   /// empty - Tests whether there are no bits in this bitvector.
@@ -436,12 +435,11 @@ public:
     // Grow the bitvector to have enough elements.
     // Grow the bitvector to have enough elements.
     Capacity = RHSWords;
     Capacity = RHSWords;
     assert(Capacity > 0 && "negative capacity?");
     assert(Capacity > 0 && "negative capacity?");
-    BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
-	if (NewBits == nullptr) throw std::bad_alloc(); // HLSL Change
+    BitWord *NewBits = new BitWord[Capacity]; // HLSL Change: Use overridable operator new
     std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
     std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
 
 
     // Destroy the old bits.
     // Destroy the old bits.
-    std::free(Bits);
+    delete[] Bits; // HLSL Change: Use overridable operator delete
     Bits = NewBits;
     Bits = NewBits;
 
 
     return *this;
     return *this;
@@ -450,7 +448,7 @@ public:
   const BitVector &operator=(BitVector &&RHS) {
   const BitVector &operator=(BitVector &&RHS) {
     if (this == &RHS) return *this;
     if (this == &RHS) return *this;
 
 
-    std::free(Bits);
+    delete[] Bits; // HLSL Change: Use overridable operator delete
     Bits = RHS.Bits;
     Bits = RHS.Bits;
     Size = RHS.Size;
     Size = RHS.Size;
     Capacity = RHS.Capacity;
     Capacity = RHS.Capacity;
@@ -533,11 +531,11 @@ private:
   void grow(unsigned NewSize) {
   void grow(unsigned NewSize) {
     Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
     Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
     assert(Capacity > 0 && "realloc-ing zero space");
     assert(Capacity > 0 && "realloc-ing zero space");
-    // HLSL Change Starts: don't lose old buffer while reallocating
+    // HLSL Change Starts: Use overridable operator new
     // Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
     // Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
-    BitWord  *newBits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
-    if (newBits == nullptr)
-      throw std::bad_alloc();
+    BitWord  *newBits = new BitWord[Capacity];
+    std::memcpy(newBits, Bits, NumBitWords(Size));
+    delete[] Bits;
     Bits = newBits;
     Bits = newBits;
     // HLSL Change Ends
     // HLSL Change Ends
 
 

+ 4 - 4
include/llvm/ADT/SmallVector.h

@@ -248,7 +248,7 @@ void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
   size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
   size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
   if (NewCapacity < MinSize)
   if (NewCapacity < MinSize)
     NewCapacity = MinSize;
     NewCapacity = MinSize;
-  T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
+  T *NewElts = (T*)new char[NewCapacity*sizeof(T)]; // HLSL Change: Use overridable operator new
 
 
   // Move the elements over.
   // Move the elements over.
   this->uninitialized_move(this->begin(), this->end(), NewElts);
   this->uninitialized_move(this->begin(), this->end(), NewElts);
@@ -258,7 +258,7 @@ void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
 
 
   // If this wasn't grown from the inline copy, deallocate the old space.
   // If this wasn't grown from the inline copy, deallocate the old space.
   if (!this->isSmall())
   if (!this->isSmall())
-    free(this->begin());
+    delete[] (char*)this->begin(); // HLSL Change: Use overridable operator delete
 
 
   this->setEnd(NewElts+CurSize);
   this->setEnd(NewElts+CurSize);
   this->BeginX = NewElts;
   this->BeginX = NewElts;
@@ -364,7 +364,7 @@ public:
 
 
     // If this wasn't grown from the inline copy, deallocate the old space.
     // If this wasn't grown from the inline copy, deallocate the old space.
     if (!this->isSmall())
     if (!this->isSmall())
-      free(this->begin());
+      delete[] (char*)this->begin(); // HLSL Change: Use overridable operator delete
   }
   }
 
 
 
 
@@ -784,7 +784,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
   // If the RHS isn't small, clear this vector and then steal its buffer.
   // If the RHS isn't small, clear this vector and then steal its buffer.
   if (!RHS.isSmall()) {
   if (!RHS.isSmall()) {
     this->destroy_range(this->begin(), this->end());
     this->destroy_range(this->begin(), this->end());
-    if (!this->isSmall()) free(this->begin());
+    if (!this->isSmall()) delete[] (char*)this->begin(); // HLSL Change: Use overridable operator delete
     this->BeginX = RHS.BeginX;
     this->BeginX = RHS.BeginX;
     this->EndX = RHS.EndX;
     this->EndX = RHS.EndX;
     this->CapacityX = RHS.CapacityX;
     this->CapacityX = RHS.CapacityX;

+ 2 - 2
lib/CodeGen/LiveIntervalUnion.cpp

@@ -189,7 +189,7 @@ void LiveIntervalUnion::Array::init(LiveIntervalUnion::Allocator &Alloc,
   clear();
   clear();
   Size = NSize;
   Size = NSize;
   LIUs = static_cast<LiveIntervalUnion*>(
   LIUs = static_cast<LiveIntervalUnion*>(
-    malloc(sizeof(LiveIntervalUnion)*NSize));
+    new char[sizeof(LiveIntervalUnion)*NSize]); // HLSL Change: Use overridable operator new
   for (unsigned i = 0; i != Size; ++i)
   for (unsigned i = 0; i != Size; ++i)
     new(LIUs + i) LiveIntervalUnion(Alloc);
     new(LIUs + i) LiveIntervalUnion(Alloc);
 }
 }
@@ -199,7 +199,7 @@ void LiveIntervalUnion::Array::clear() {
     return;
     return;
   for (unsigned i = 0; i != Size; ++i)
   for (unsigned i = 0; i != Size; ++i)
     LIUs[i].~LiveIntervalUnion();
     LIUs[i].~LiveIntervalUnion();
-  free(LIUs);
+  delete[] static_cast<char*>(LIUs); // HLSL Change: Use overridable operator delete
   Size =  0;
   Size =  0;
   LIUs = nullptr;
   LIUs = nullptr;
 }
 }

+ 2 - 0
lib/IR/LegacyPassManager.cpp

@@ -1883,6 +1883,7 @@ void FunctionPass::assignPassManager(PMStack &PMS,
 
 
     // [1] Create new Function Pass Manager
     // [1] Create new Function Pass Manager
     FPP = new FPPassManager();
     FPP = new FPPassManager();
+    std::unique_ptr<FPPassManager> NewFPP(FPP); // HLSL Change
     FPP->populateInheritedAnalysis(PMS);
     FPP->populateInheritedAnalysis(PMS);
 
 
     // [2] Set up new manager's top level manager
     // [2] Set up new manager's top level manager
@@ -1891,6 +1892,7 @@ void FunctionPass::assignPassManager(PMStack &PMS,
 
 
     // [3] Assign manager to manage this new manager. This may create
     // [3] Assign manager to manage this new manager. This may create
     // and push new managers into PMS
     // and push new managers into PMS
+    NewFPP.release(); // HLSL Change: assignPassManager transfers ownership of 'this'...
     FPP->assignPassManager(PMS, PMD->getPassManagerType());
     FPP->assignPassManager(PMS, PMD->getPassManagerType());
 
 
     // [4] Push new manager into PMS
     // [4] Push new manager into PMS

+ 14 - 13
lib/Support/SmallPtrSet.cpp

@@ -22,14 +22,14 @@ using namespace llvm;
 
 
 void SmallPtrSetImplBase::shrink_and_clear() {
 void SmallPtrSetImplBase::shrink_and_clear() {
   assert(!isSmall() && "Can't shrink a small set!");
   assert(!isSmall() && "Can't shrink a small set!");
-  free(CurArray);
+  delete[] CurArray; // HLSL Change: Use overridable operator delete
 
 
   // Reduce the number of buckets.
   // Reduce the number of buckets.
   CurArraySize = NumElements > 16 ? 1 << (Log2_32_Ceil(NumElements) + 1) : 32;
   CurArraySize = NumElements > 16 ? 1 << (Log2_32_Ceil(NumElements) + 1) : 32;
   NumElements = NumTombstones = 0;
   NumElements = NumTombstones = 0;
 
 
   // Install the new array.  Clear all the buckets to empty.
   // Install the new array.  Clear all the buckets to empty.
-  CurArray = (const void**)malloc(sizeof(void*) * CurArraySize);
+  CurArray = new const void*[CurArraySize]; // HLSL Change: Use overridable operator new
   assert(CurArray && "Failed to allocate memory?");
   assert(CurArray && "Failed to allocate memory?");
   memset(CurArray, -1, CurArraySize*sizeof(void*));
   memset(CurArray, -1, CurArraySize*sizeof(void*));
 }
 }
@@ -138,7 +138,7 @@ void SmallPtrSetImplBase::Grow(unsigned NewSize) {
   bool WasSmall = isSmall();
   bool WasSmall = isSmall();
   
   
   // Install the new array.  Clear all the buckets to empty.
   // Install the new array.  Clear all the buckets to empty.
-  CurArray = (const void**)malloc(sizeof(void*) * NewSize);
+  CurArray = new const void*[NewSize]; // HLSL Change: Use overridable operator new
   assert(CurArray && "Failed to allocate memory?");
   assert(CurArray && "Failed to allocate memory?");
   CurArraySize = NewSize;
   CurArraySize = NewSize;
   memset(CurArray, -1, NewSize*sizeof(void*));
   memset(CurArray, -1, NewSize*sizeof(void*));
@@ -161,7 +161,7 @@ void SmallPtrSetImplBase::Grow(unsigned NewSize) {
         *const_cast<void**>(FindBucketFor(Elt)) = const_cast<void*>(Elt);
         *const_cast<void**>(FindBucketFor(Elt)) = const_cast<void*>(Elt);
     }
     }
     
     
-    free(OldBuckets);
+    delete[] OldBuckets; // HLSL Change: Use overridable operator delete
     NumTombstones = 0;
     NumTombstones = 0;
   }
   }
 }
 }
@@ -175,7 +175,7 @@ SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage,
     CurArray = SmallArray;
     CurArray = SmallArray;
   // Otherwise, allocate new heap space (unless we were the same size)
   // Otherwise, allocate new heap space (unless we were the same size)
   } else {
   } else {
-    CurArray = (const void**)malloc(sizeof(void*) * that.CurArraySize);
+    CurArray = new const void*[that.CurArraySize]; // HLSL Change: Use overridable operator new
     assert(CurArray && "Failed to allocate memory?");
     assert(CurArray && "Failed to allocate memory?");
   }
   }
   
   
@@ -228,18 +228,19 @@ void SmallPtrSetImplBase::CopyFrom(const SmallPtrSetImplBase &RHS) {
   // If we're becoming small, prepare to insert into our stack space
   // If we're becoming small, prepare to insert into our stack space
   if (RHS.isSmall()) {
   if (RHS.isSmall()) {
     if (!isSmall())
     if (!isSmall())
-      free(CurArray);
+      delete[] CurArray; // HLSL Change: Use overridable operator delete
     CurArray = SmallArray;
     CurArray = SmallArray;
   // Otherwise, allocate new heap space (unless we were the same size)
   // Otherwise, allocate new heap space (unless we were the same size)
   } else if (CurArraySize != RHS.CurArraySize) {
   } else if (CurArraySize != RHS.CurArraySize) {
     if (isSmall())
     if (isSmall())
-      CurArray = (const void**)malloc(sizeof(void*) * RHS.CurArraySize);
+      CurArray = new const void*[RHS.CurArraySize]; // HLSL Change: Use overridable operator new
     else {
     else {
-      const void **T = (const void**)realloc(CurArray,
-                                             sizeof(void*) * RHS.CurArraySize);
-      if (!T)
-        free(CurArray);
+      // HLSL Change Begins: Use overridable operator new
+      const void **T = new const void*[RHS.CurArraySize];
+      std::memcpy(T, CurArray, std::min(CurArraySize, RHS.CurArraySize));
+      delete[] CurArray;
       CurArray = T;
       CurArray = T;
+      // HLSL Change Ends
     }
     }
     assert(CurArray && "Failed to allocate memory?");
     assert(CurArray && "Failed to allocate memory?");
   }
   }
@@ -259,7 +260,7 @@ void SmallPtrSetImplBase::MoveFrom(unsigned SmallSize,
   assert(&RHS != this && "Self-move should be handled by the caller.");
   assert(&RHS != this && "Self-move should be handled by the caller.");
 
 
   if (!isSmall())
   if (!isSmall())
-    free(CurArray);
+    delete[] CurArray; // HLSL Change: Use overridable operator delete
 
 
   if (RHS.isSmall()) {
   if (RHS.isSmall()) {
     // Copy a small RHS rather than moving.
     // Copy a small RHS rather than moving.
@@ -334,5 +335,5 @@ void SmallPtrSetImplBase::swap(SmallPtrSetImplBase &RHS) {
 
 
 SmallPtrSetImplBase::~SmallPtrSetImplBase() {
 SmallPtrSetImplBase::~SmallPtrSetImplBase() {
   if (!isSmall())
   if (!isSmall())
-    free(CurArray);
+    delete[] CurArray; // HLSL Change: Use overridable operator delete
 }
 }

+ 6 - 2
lib/Support/SmallVector.cpp

@@ -25,13 +25,17 @@ void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSizeInBytes,
 
 
   void *NewElts;
   void *NewElts;
   if (BeginX == FirstEl) {
   if (BeginX == FirstEl) {
-    NewElts = malloc(NewCapacityInBytes);
+    NewElts = new char[NewCapacityInBytes]; // HLSL Change: Use overridable operator new
 
 
     // Copy the elements over.  No need to run dtors on PODs.
     // Copy the elements over.  No need to run dtors on PODs.
     memcpy(NewElts, this->BeginX, CurSizeBytes);
     memcpy(NewElts, this->BeginX, CurSizeBytes);
   } else {
   } else {
     // If this wasn't grown from the inline copy, grow the allocated space.
     // If this wasn't grown from the inline copy, grow the allocated space.
-    NewElts = realloc(this->BeginX, NewCapacityInBytes);
+    // HLSL Change Begins: Use overridable operator new
+    NewElts = new char[NewCapacityInBytes];
+    memcpy(NewElts, this->BeginX, CurSizeBytes);
+    delete[] (char*)this->BeginX;
+    // HLSL Change Ends
   }
   }
   assert(NewElts && "Out of memory");
   assert(NewElts && "Out of memory");