Skip to content

Remove allocated_size from RepeatedPtrFieldBase::Rep.#26880

Draft
copybara-service[bot] wants to merge 1 commit intomainfrom
test_899189917
Draft

Remove allocated_size from RepeatedPtrFieldBase::Rep.#26880
copybara-service[bot] wants to merge 1 commit intomainfrom
test_899189917

Conversation

@copybara-service
Copy link
Copy Markdown

Remove allocated_size from RepeatedPtrFieldBase::Rep.

This comes with wins in a few places, notably that we don't need to maintain allocated_size when adding/removing elements, simplifying common methods like Add.

Without allocated_size, we need some other way to distinguish the end of allocated entries from uninitialized entries in the heap rep. Instead of leaving the remainder of Rep uninitialized after the last allocated element, we memset all of Rep to 0 when resizing.

This change comes with a slight regression to resize, which now needs to memset the remainder of the newly allocated rep to 0. Additionally, the destructor, when destroying cleared elements (unlikely), has to iterate until it finds a null element, which is an additional few instructions.

The most glaring regression is in ReleaseLast/UnsafeArenaReleaseLast/CloseGap, which all need to calculate AllocatedSize in order to move any allocated elements from the end to the front, maintaining the invariant that all allocated elements immediately follow the last exposed element. They call AllocatedSizeSlow, which either does a linear scan of the elements, or a binary search, depending on how large the search range is.

This comes with wins in a few places, notably that we don't need to maintain `allocated_size` when adding/removing elements, simplifying common methods like `Add`.

Without `allocated_size`, we need some other way to distinguish the end of allocated entries from uninitialized entries in the heap rep. Instead of leaving the remainder of `Rep` uninitialized after the last allocated element, we memset all of `Rep` to 0 when resizing.

This change comes with a slight regression to resize, which now needs to memset the remainder of the newly allocated rep to 0. Additionally, the destructor, when destroying cleared elements (unlikely), has to iterate until it finds a null element, which is an additional few instructions.

The most glaring regression is in `ReleaseLast`/`UnsafeArenaReleaseLast`/`CloseGap`, which all need to calculate `AllocatedSize` in order to move any allocated elements from the end to the front, maintaining the invariant that all allocated elements immediately follow the last exposed element. They call `AllocatedSizeSlow`, which either does a linear scan of the elements, or a binary search, depending on how large the search range is.

PiperOrigin-RevId: 899189917
Copy link
Copy Markdown

@saeed00637-jpg saeed00637-jpg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1128286695

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants