Issue
This is a follow-up from another href="https://stackoverflow.com/questions/74157781/cause-of-difference-in-performances-of-default-pmr-allocator-and-default-std-all/74183319?noredirect=1#comment130979137_74183319">question.
I think the following code should not use monotonic_buffer_resource
, but in the generated assembly there are references to it.
void default_pmr_alloc(std::pmr::polymorphic_allocator<int>& alloc) {
(void)alloc.allocate(1);
}
I looked into the source code of the header files and libstdc++, but could not find how monotonic_buffer_resource was selected to be used by the default pmr allocator.
Solution
The assembly tells the story. In particular, this:
cmp rax, OFFSET FLAT:_ZNSt3pmr25monotonic_buffer_resource11do_allocateEmm
jne .L11
This appears to be a test to see if the memory resource is a monotonic_buffer_resource
. This seems to be done by checking the do_allocate
member of the vtable. If it is not such a resource (ie: if do_allocate
in the memory resource is not the monotonic one), then it jumps down to this:
.L11:
mov rdi, rbx
mov edx, 4
mov esi, 4
pop rbx
jmp rax
This appears to be a vtable call.
The rest of the assembly appears to be an inlined version of monotonic_buffer_resource::do_allocate
. Which is why it conditionally calls std::pmr::monotonic_buffer_resource::_M_new_buffer
.
So overall, this implementation of polymorphic_resource::allocate
seems to have some built-in inlining of monotonic_buffer_resource::do_allocate
if the resource is appropriate for that. That is, it won't do a vtable call if it can determine that it should call monotonic_buffer_resource::do_allocate
.
Answered By - Nicol Bolas Answer Checked By - Gilberto Lyons (WPSolving Admin)