diff --git a/folly/detail/ThreadLocalDetail.h b/folly/detail/ThreadLocalDetail.h index de3ebb8a5f957d7efbbf8f8e2133c0be1b1a8ff0..505682f28d1856f6d1fba108431bafd2bcea8f47 100644 --- a/folly/detail/ThreadLocalDetail.h +++ b/folly/detail/ThreadLocalDetail.h @@ -277,12 +277,18 @@ struct StaticMeta { // still linked in meta, so another thread might access invalid memory // after realloc succeeds. We'll copy by hand and update threadEntry_ // under the lock. + // + // Note that we're using calloc instead of malloc in order to zero + // the entire region. rallocm (ALLOCM_ZERO) will only zero newly + // allocated memory, so if a previous allocation allocated more than + // we requested, it's our responsibility to guarantee that the tail + // is zeroed. calloc() is simpler than malloc() followed by memset(), + // and potentially faster when dealing with a lot of memory, as + // it can get already-zeroed pages from the kernel. if ((ptr = static_cast<ElementWrapper*>( - malloc(sizeof(ElementWrapper) * newSize))) != NULL) { + calloc(newSize, sizeof(ElementWrapper)))) != NULL) { memcpy(ptr, threadEntry_.elements, sizeof(ElementWrapper) * prevSize); - memset(ptr + prevSize, 0, - (newSize - prevSize) * sizeof(ElementWrapper)); } else { throw std::bad_alloc(); }