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

@ -2732,7 +2732,7 @@ bool free_fastpath(void *ptr, size_t size, bool size_hint) {
tcache_t *tcache = tsd_tcachep_get(tsd); tcache_t *tcache = tsd_tcachep_get(tsd);
alloc_ctx_t alloc_ctx; alloc_ctx_t alloc_ctx;
/* /*
* If !config_cache_oblivious, we can check PAGE alignment to * If !config_cache_oblivious, we can check PAGE alignment to
* detect sampled objects. Otherwise addresses are * detect sampled objects. Otherwise addresses are
* randomized, and we have to look it up in the rtree anyway. * randomized, and we have to look it up in the rtree anyway.
@ -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