Skip to content

Skip DeleteInfo construction in InvokeHooksAndFreePages when no delete hooks. - #1002

Draft
copybara-service[bot] wants to merge 1 commit into
masterfrom
test_983911102
Draft

copybara-service[bot] wants to merge 1 commit into
masterfrom
test_983911102

Conversation

@copybara-service

Copy link
Copy Markdown

Skip DeleteInfo construction in InvokeHooksAndFreePages when no delete hooks.

InvokeHooksAndFreePages (the page-heap free path for large and sampled
objects) built a DeleteInfo unconditionally before calling
MallocHook::InvokeDeleteHook, which only then checked delete_hooks_.empty().
Constructing the argument requires GetLargeSize: a reload of the span flags,
a sampled-bit test, either the num_pages shift or the sampled-allocation
size (plus a GWP-ASan bounds check and possible out-of-line
GetRequestedSize call), and five stack stores to materialize the struct.

Check delete_hooks_.empty() first and only compute the size and invoke the
hook when a hook is installed. The hook still runs before the span is
unsampled and before the pages are returned to the page allocator, so
ordering and behaviour with hooks installed are unchanged.

On the no-hook, non-sampled path this removes 16 instructions (5 stores,
2 loads) from each instantiation; the remaining cost is one relaxed load
and a well-predicted branch. The size computation is now emitted out of
line in a cold block, which costs the (rare) hooked delete path ~1%.

Add hooks_test coverage for the large-object free path (sized and unsized)
so the hook invocation and its span-derived allocated size remain guarded.

…e hooks.

InvokeHooksAndFreePages (the page-heap free path for large and sampled
objects) built a DeleteInfo unconditionally before calling
MallocHook::InvokeDeleteHook, which only then checked delete_hooks_.empty().
Constructing the argument requires GetLargeSize: a reload of the span flags,
a sampled-bit test, either the num_pages shift or the sampled-allocation
size (plus a GWP-ASan bounds check and possible out-of-line
GetRequestedSize call), and five stack stores to materialize the struct.

Check delete_hooks_.empty() first and only compute the size and invoke the
hook when a hook is installed.  The hook still runs before the span is
unsampled and before the pages are returned to the page allocator, so
ordering and behaviour with hooks installed are unchanged.

On the no-hook, non-sampled path this removes 16 instructions (5 stores,
2 loads) from each instantiation; the remaining cost is one relaxed load
and a well-predicted branch.  The size computation is now emitted out of
line in a cold block, which costs the (rare) hooked delete path ~1%.

Add hooks_test coverage for the large-object free path (sized and unsized)
so the hook invocation and its span-derived allocated size remain guarded.

PiperOrigin-RevId: 983911102
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.

1 participant