@@ -102,6 +102,7 @@ class CountingAllocator
102
102
, memoryLimitLowerBound_(other.memoryLimitLowerBound_)
103
103
, checkPointStepSize_(other.checkPointStepSize_)
104
104
{
105
+
105
106
}
106
107
107
108
// Allocate memory for n objects of type T
@@ -131,15 +132,17 @@ class CountingAllocator
131
132
// Deallocate memory for n objects of type T
132
133
void deallocate (T* ptr, std::size_t n) noexcept
133
134
{
134
- ::operator delete (ptr);
135
-
135
+ // Calculate all size-related values before deletion
136
136
int64_t sizeToDeallocate = n * sizeof (T);
137
-
138
137
int64_t sizeChangeWDirection =
139
138
(currentLocalMemoryUsage_ >= lastMemoryLimitCheckpoint_) ? -sizeToDeallocate : sizeToDeallocate;
140
139
int64_t diffSinceLastCheckPoint = int_distance (currentLocalMemoryUsage_, lastMemoryLimitCheckpoint_);
140
+ bool needsCheckpoint = needCheckPoint (sizeChangeWDirection, diffSinceLastCheckPoint, checkPointStepSize_);
141
141
142
- if (needCheckPoint (sizeChangeWDirection, diffSinceLastCheckPoint, checkPointStepSize_))
142
+ // Now safe to delete
143
+ ::operator delete (ptr);
144
+
145
+ if (needsCheckpoint)
143
146
{
144
147
// Invariant is lastMemoryLimitCheckpoint_ >= currentLocalMemoryUsage_ - sizeToDeallocate
145
148
int64_t lastMemoryLimitCheckpointDiff =
@@ -148,11 +151,14 @@ class CountingAllocator
148
151
: diffSinceLastCheckPoint + sizeToDeallocate;
149
152
150
153
assert (lastMemoryLimitCheckpointDiff > 0 );
154
+
151
155
atomicops::atomicAddRef (*memoryLimit_, lastMemoryLimitCheckpointDiff);
152
156
153
157
lastMemoryLimitCheckpoint_ -= (lastMemoryLimitCheckpoint_ == 0 ) ? 0 : lastMemoryLimitCheckpointDiff;
154
158
}
159
+
155
160
currentLocalMemoryUsage_ = currentLocalMemoryUsage_ - sizeToDeallocate;
161
+
156
162
}
157
163
158
164
// Equality operators (allocators are equal if they share the same counter)
0 commit comments