remove compare and branch in fast path for c++ operator delete[]

Summary: sdallocx is checking a flag that will never be set (at least in the provided C++ destructor implementation).  This branch will probably only rarely be mispredicted however it removes two instructions in sdallocx and one at the callsite (to zero out flags).
This commit is contained in:
mgrice 2019-03-08 11:50:30 -08:00 committed by Qi Wang
parent c2a3a7cd3f
commit d3d7a8ef09
4 changed files with 17 additions and 3 deletions

View File

@ -2909,6 +2909,7 @@ sub RemoveUninterestingFrames {
'@JEMALLOC_PREFIX@xallocx', '@JEMALLOC_PREFIX@xallocx',
'@JEMALLOC_PREFIX@dallocx', '@JEMALLOC_PREFIX@dallocx',
'@JEMALLOC_PREFIX@sdallocx', '@JEMALLOC_PREFIX@sdallocx',
'@JEMALLOC_PREFIX@sdallocx_noflags',
'tc_calloc', 'tc_calloc',
'tc_cfree', 'tc_cfree',
'tc_malloc', 'tc_malloc',

View File

@ -51,5 +51,6 @@ void jemalloc_prefork(void);
void jemalloc_postfork_parent(void); void jemalloc_postfork_parent(void);
void jemalloc_postfork_child(void); void jemalloc_postfork_child(void);
bool malloc_initialized(void); bool malloc_initialized(void);
void je_sdallocx_noflags(void *ptr, size_t size);
#endif /* JEMALLOC_INTERNAL_EXTERNS_H */ #endif /* JEMALLOC_INTERNAL_EXTERNS_H */

View File

@ -3522,6 +3522,18 @@ je_sdallocx(void *ptr, size_t size, int flags) {
LOG("core.sdallocx.exit", ""); LOG("core.sdallocx.exit", "");
} }
void JEMALLOC_NOTHROW
je_sdallocx_noflags(void *ptr, size_t size) {
LOG("core.sdallocx.entry", "ptr: %p, size: %zu, flags: 0", ptr,
size);
if (!free_fastpath(ptr, size, true)) {
sdallocx_default(ptr, size, 0);
}
LOG("core.sdallocx.exit", "");
}
JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW
JEMALLOC_ATTR(pure) JEMALLOC_ATTR(pure)
je_nallocx(size_t size, int flags) { je_nallocx(size_t size, int flags) {

View File

@ -128,14 +128,14 @@ operator delete(void *ptr, std::size_t size) noexcept {
if (unlikely(ptr == nullptr)) { if (unlikely(ptr == nullptr)) {
return; return;
} }
je_sdallocx(ptr, size, /*flags=*/0); je_sdallocx_noflags(ptr, size);
} }
void operator delete[](void *ptr, std::size_t size) noexcept { void operator delete[](void *ptr, std::size_t size) noexcept {
if (unlikely(ptr == nullptr)) { if (unlikely(ptr == nullptr)) {
return; return;
} }
je_sdallocx(ptr, size, /*flags=*/0); je_sdallocx_noflags(ptr, size);
} }
#endif // __cpp_sized_deallocation #endif // __cpp_sized_deallocation