Make vector destructors use the array_destructors list.
hsutter opened this issue · comments
Right now, vector<T, gc_allocator<T>>
stores individual T
constructors in response to construct()
calls. This is needlessly inefficient and would make vector::push_back
a potentially quadratic operation.
Instead, we already track array_destructors
for arrays, so we should use that for vector pages instead of registering individual destructors. That makes more sense anyway, and in all cases there will be a single array_destructors
entry for the entire vector (well, one for every block the vector allocated as it did a regrow operation and that hasn’t been collected yet).
Solution sketch: Have construct()
check to see if this is constructing an object that already covered by an array_destructors
entry in which case no additional tracking is needed (this is the pop_back
-followed-by-push_back
case). If it's one after the end of an array_destructors
entry and still in the same allocation, likewise just increment the number of objects in the array_destructors
entry (this is the push_back
-into-unconstructed-memory case), and optionally add a debug check that it's for the same type. Finally, to cover the one-element vector
case, check to see if this is constructing an object immediately after (and in the same allocation as) a single-object destructors
entry, and if so convert it to an array_destructors
entry.