Commit 5ead4c5e authored by Chris Sarbora's avatar Chris Sarbora Committed by Facebook GitHub Bot

Correctly handle Android not having malloc_usable_size below API17

Summary: Android doesn't expose `malloc_usable_size` below API-level 17. Correctly reflect this in folly-config.h, and then ensure that all code paths that use `malloc_usable_size` are unreachable when compiling without it.

Reviewed By: yfeldblum

Differential Revision: D20721326

fbshipit-source-id: d60b3caa1910dc2bf8ed0844177f5cb93a9fd067
parent eb877c83
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include <folly/Portability.h> #include <folly/Portability.h>
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
#include <folly/Traits.h> #include <folly/Traits.h>
#include <folly/functional/Invoke.h>
#include <folly/lang/Assume.h> #include <folly/lang/Assume.h>
#include <folly/lang/Exception.h> #include <folly/lang/Exception.h>
#include <folly/memory/Malloc.h> #include <folly/memory/Malloc.h>
...@@ -764,11 +765,18 @@ class small_vector : public detail::small_vector_base< ...@@ -764,11 +765,18 @@ class small_vector : public detail::small_vector_base<
} }
size_type capacity() const { size_type capacity() const {
struct Unreachable {
size_t operator()(void*) const {
assume_unreachable();
}
};
using AllocationSizeOrUnreachable =
conditional_t<kMustTrackHeapifiedCapacity, Unreachable, AllocationSize>;
if (this->isExtern()) { if (this->isExtern()) {
if (u.hasCapacity()) { if (u.hasCapacity()) {
return u.getCapacity(); return u.getCapacity();
} }
return malloc_usable_size(u.pdata_.heap_) / sizeof(value_type); return AllocationSizeOrUnreachable{}(u.pdata_.heap_) / sizeof(value_type);
} }
return MaxInline; return MaxInline;
} }
...@@ -1112,7 +1120,7 @@ class small_vector : public detail::small_vector_base< ...@@ -1112,7 +1120,7 @@ class small_vector : public detail::small_vector_base<
// allocation is grown to over some threshold, we should store // allocation is grown to over some threshold, we should store
// a capacity at the front of the heap allocation. // a capacity at the front of the heap allocation.
const bool heapifyCapacity = const bool heapifyCapacity =
!kHasInlineCapacity && needBytes > kHeapifyCapacityThreshold; !kHasInlineCapacity && needBytes >= kHeapifyCapacityThreshold;
const size_t allocationExtraBytes = const size_t allocationExtraBytes =
heapifyCapacity ? kHeapifyCapacitySize : 0; heapifyCapacity ? kHeapifyCapacitySize : 0;
const size_t goodAllocationSizeBytes = const size_t goodAllocationSizeBytes =
...@@ -1225,9 +1233,28 @@ class small_vector : public detail::small_vector_base< ...@@ -1225,9 +1233,28 @@ class small_vector : public detail::small_vector_base<
typename std:: typename std::
aligned_storage<sizeof(InternalSizeType), alignof(value_type)>::type); aligned_storage<sizeof(InternalSizeType), alignof(value_type)>::type);
struct AllocationSize {
auto operator()(void* ptr) const {
(void)ptr;
#if defined(FOLLY_HAVE_MALLOC_USABLE_SIZE)
return malloc_usable_size(ptr);
#endif
// it is important that this method not return a size_t if we can't call
// malloc_usable_size! kMustTrackHeapifiedCapacity uses the deduced return
// type of this function in order to decide whether small_vector must
// track its own capacity or not.
}
};
static bool constexpr kMustTrackHeapifiedCapacity =
!is_invocable_r_v<size_t, AllocationSize, void*>;
// Threshold to control capacity heapifying. // Threshold to control capacity heapifying.
static size_t constexpr kHeapifyCapacityThreshold = static size_t constexpr kHeapifyCapacityThreshold =
100 * kHeapifyCapacitySize; (kMustTrackHeapifiedCapacity ? 0 : 100) * kHeapifyCapacitySize;
static bool constexpr kAlwaysHasCapacity =
kHasInlineCapacity || kMustTrackHeapifiedCapacity;
typedef typename std:: typedef typename std::
conditional<kHasInlineCapacity, HeapPtrWithCapacity, HeapPtr>::type conditional<kHasInlineCapacity, HeapPtrWithCapacity, HeapPtr>::type
...@@ -1261,7 +1288,7 @@ class small_vector : public detail::small_vector_base< ...@@ -1261,7 +1288,7 @@ class small_vector : public detail::small_vector_base<
} }
bool hasCapacity() const { bool hasCapacity() const {
return kHasInlineCapacity || detail::pointerFlagGet(pdata_.heap_); return kAlwaysHasCapacity || detail::pointerFlagGet(pdata_.heap_);
} }
InternalSizeType getCapacity() const { InternalSizeType getCapacity() const {
return pdata_.getCapacity(); return pdata_.getCapacity();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment