Bug 1943811, avoid calling SegmentedVector::Length() in hot code paths, r=mccr8

Differential Revision: https://phabricator.services.mozilla.com/D240910
This commit is contained in:
Olli Pettay
2025-03-12 10:04:03 +00:00
parent cc2e56ebdb
commit ecc628e6be
3 changed files with 19 additions and 9 deletions

View File

@@ -3041,13 +3041,8 @@ struct DeferredFinalizerImpl {
static bool DeferredFinalize(uint32_t aSlice, void* aData) { static bool DeferredFinalize(uint32_t aSlice, void* aData) {
MOZ_ASSERT(aSlice > 0, "nonsensical/useless call with aSlice == 0"); MOZ_ASSERT(aSlice > 0, "nonsensical/useless call with aSlice == 0");
SmartPtrArray* pointers = static_cast<SmartPtrArray*>(aData); SmartPtrArray* pointers = static_cast<SmartPtrArray*>(aData);
uint32_t oldLen = pointers->Length();
if (oldLen < aSlice) {
aSlice = oldLen;
}
uint32_t newLen = oldLen - aSlice;
pointers->PopLastN(aSlice); pointers->PopLastN(aSlice);
if (newLen == 0) { if (pointers->IsEmpty()) {
delete pointers; delete pointers;
return true; return true;
} }

View File

@@ -224,10 +224,8 @@ class SegmentedVector : private AllocPolicy {
} }
// Equivalent to calling |PopLast| |aNumElements| times, but potentially // Equivalent to calling |PopLast| |aNumElements| times, but potentially
// more efficient. // more efficient. It is safe to call this even when aNumElements > Length().
void PopLastN(uint32_t aNumElements) { void PopLastN(uint32_t aNumElements) {
MOZ_ASSERT(aNumElements <= Length());
Segment* last; Segment* last;
// Pop full segments for as long as we can. Note that this loop // Pop full segments for as long as we can. Note that this loop

View File

@@ -110,6 +110,23 @@ void TestBasics() {
// Verify the contents are what we expect. // Verify the contents are what we expect.
CheckContents(v, 700); CheckContents(v, 700);
// Verify PopLastN can take larger than .Length() value as an argument.
v.PopLastN(1000);
MOZ_RELEASE_ASSERT(v.Length() == 0);
MOZ_RELEASE_ASSERT(v.IsEmpty());
// Fill the vector again.
for (i = 0; i < 1000; ++i) {
v.InfallibleAppend(std::move(i));
}
MOZ_RELEASE_ASSERT(!v.IsEmpty());
MOZ_RELEASE_ASSERT(v.Length() == 1000);
// Verify that calling PopLastN with Length() empties the vector.
v.PopLastN(v.Length());
MOZ_RELEASE_ASSERT(v.Length() == 0);
MOZ_RELEASE_ASSERT(v.IsEmpty());
} }
void TestMoveAndSwap() { void TestMoveAndSwap() {