MCPcopy Create free account
hub / github.com/apache/impala / Reallocate

Method Reallocate

be/src/runtime/free-pool.h:125–170  ·  view source on GitHub ↗

Returns an allocation that is at least 'size'. If the current allocation backing 'ptr' is big enough, 'ptr' is returned. Otherwise a new one is made and the contents of ptr are copied into it. nullptr will be returned on allocation failure. It's the caller's responsibility to free the memory buffer pointed to by "ptr" in this case.

Source from the content-addressed store, hash-verified

123 /// nullptr will be returned on allocation failure. It's the caller's responsibility to
124 /// free the memory buffer pointed to by "ptr" in this case.
125 uint8_t* Reallocate(uint8_t* ptr, int64_t size) {
126 if (UNLIKELY(ptr == nullptr || ptr == mem_pool_->EmptyAllocPtr())) return Allocate(size);
127 FreeListNode* node = reinterpret_cast<FreeListNode*>(ptr - sizeof(FreeListNode));
128 FreeListNode* list = node->list;
129#ifndef NDEBUG
130 CheckValidAllocation(list, ptr);
131#endif
132 int bucket_idx = (list - &lists_[0]);
133 DCHECK_LT(bucket_idx, NUM_LISTS);
134 // This is the actual size of ptr.
135 int64_t allocation_size = 1LL << bucket_idx;
136
137 // If it's already big enough, just return the ptr.
138 if (allocation_size >= size) {
139 // Ensure that only first size bytes are unpoisoned. Need to poison whole region
140 // first in case size is smaller than original allocation's size.
141#ifdef ADDRESS_SANITIZER
142 DCHECK(alloc_to_size_.find(ptr) != alloc_to_size_.end());
143 int64_t prev_allocation_size = alloc_to_size_[ptr];
144 if (prev_allocation_size > size) {
145 // Allocation is shrinking: poison the 'freed' bytes.
146 ASAN_POISON_MEMORY_REGION(ptr + size, prev_allocation_size - size);
147 } else {
148 // Allocation is growing: unpoison the newly allocated bytes.
149 ASAN_UNPOISON_MEMORY_REGION(
150 ptr + prev_allocation_size, size - prev_allocation_size);
151 }
152 alloc_to_size_[ptr] = size;
153#endif
154 return ptr;
155 }
156
157 // Make a new one. Since Allocate() already rounds up to powers of 2, this effectively
158 // doubles for the caller.
159 uint8_t* new_ptr = Allocate(size);
160 if (LIKELY(new_ptr != nullptr)) {
161#ifdef ADDRESS_SANITIZER
162 DCHECK(alloc_to_size_.find(ptr) != alloc_to_size_.end());
163 // Unpoison the region so that we can copy the old allocation to the new one.
164 ASAN_UNPOISON_MEMORY_REGION(ptr, allocation_size);
165#endif
166 memcpy(new_ptr, ptr, allocation_size);
167 Free(ptr);
168 }
169 return new_ptr;
170 }
171
172 MemTracker* mem_tracker() { return mem_pool_->mem_tracker(); }
173 int64_t net_allocations() const { return net_allocations_; }

Callers 1

TESTFunction · 0.45

Calls 3

EmptyAllocPtrMethod · 0.80
findMethod · 0.45
endMethod · 0.45

Tested by 1

TESTFunction · 0.36