Types: Fix folly::small_vector and folly::sorted_vector_map

folly::sorted_vector_map's results are not completely accurate, but at
least CodeGen v2 matches CodeGen v1 for it now.
This commit is contained in:
Alastair Robertson 2023-07-25 09:14:59 -07:00 committed by Alastair Robertson
parent e1496354de
commit 99462b2132
6 changed files with 145 additions and 1 deletions

View File

@ -798,7 +798,12 @@ void TreeBuilder::processContainer(const Variable& variable, Node& node) {
containerStats.length = containerStats.capacity = next();
break;
case SMALL_VEC_TYPE: {
size_t maxInline = next();
size_t requestedMaxInline = next();
size_t maxInline =
requestedMaxInline == 0
? 0
: std::max(sizeof(uintptr_t) / containerStats.elementStaticSize,
requestedMaxInline);
containerStats.capacity = next();
containerStats.length = next();
contentsStoredInline = containerStats.capacity <= maxInline;

View File

@ -1,3 +1,4 @@
#include <folly/ScopeGuard.h>
#include <folly/lang/SafeAssert.h>
namespace folly {
@ -18,5 +19,9 @@ void safe_assert_terminate<true>(safe_assert_arg const* /*arg*/, ...) noexcept {
abort();
}
void ScopeGuardImplBase::terminate() noexcept {
abort();
}
} // namespace detail
} // namespace folly

View File

@ -0,0 +1,43 @@
includes = ["folly/small_vector.h", "vector"]
[cases]
[cases.int_default_empty]
param_types = ["const folly::small_vector<int>&"]
setup = "return {};"
expect_json = '[{"staticSize":16, "dynamicSize":0, "exclusiveSize":16, "length":0, "capacity":2, "elementStaticSize":4}]'
[cases.int_default_inlined]
param_types = ["const folly::small_vector<int>&"]
setup = "return {{1,2}};"
expect_json = '[{"staticSize":16, "dynamicSize":0, "exclusiveSize":16, "length":2, "capacity":2, "elementStaticSize":4}]'
[cases.int_default_overflow]
param_types = ["const folly::small_vector<int>&"]
setup = "return {{1,2,3,4}};"
expect_json = '[{"staticSize":16, "dynamicSize":24, "exclusiveSize":40, "length":4, "capacity":6, "elementStaticSize":4}]'
[cases.vector_3_empty]
param_types = ["const folly::small_vector<std::vector<int>, 3>&"]
setup = "return {};"
expect_json = '[{"staticSize":80, "dynamicSize":0, "exclusiveSize":80, "length":0, "capacity":3, "elementStaticSize":24}]'
[cases.vector_3_inlined]
param_types = ["const folly::small_vector<std::vector<int>, 3>&"]
setup = "return {{ {1,2,3}, {4}, {5,6} }};"
expect_json = '''[
{"staticSize":80, "dynamicSize":24, "length":3, "exclusiveSize":8, "capacity":3, "elementStaticSize":24, "members":[
{"staticSize":24, "dynamicSize":12, "exclusiveSize":36, "length":3, "capacity":3, "elementStaticSize":4},
{"staticSize":24, "dynamicSize":4, "exclusiveSize":28, "length":1, "capacity":1, "elementStaticSize":4},
{"staticSize":24, "dynamicSize":8, "exclusiveSize":32, "length":2, "capacity":2, "elementStaticSize":4}
]}]'''
[cases.vector_3_overflow]
param_types = ["const folly::small_vector<std::vector<int>, 3>&"]
setup = "return {{ {1,2,3}, {4}, {5,6}, {7} }};"
expect_json = '''[
{"staticSize":80, "dynamicSize":148, "length":4, "exclusiveSize":104, "capacity":5, "elementStaticSize":24, "members":[
{"staticSize":24, "dynamicSize":12, "exclusiveSize":36, "length":3, "capacity":3, "elementStaticSize":4},
{"staticSize":24, "dynamicSize":4, "exclusiveSize":28, "length":1, "capacity":1, "elementStaticSize":4},
{"staticSize":24, "dynamicSize":8, "exclusiveSize":32, "length":2, "capacity":2, "elementStaticSize":4},
{"staticSize":24, "dynamicSize":4, "exclusiveSize":28, "length":1, "capacity":1, "elementStaticSize":4}
]}]'''
[cases.int_always_heap]
param_types = ["const folly::small_vector<int, 0>&"]
setup = "return {{1}};"
expect_json = '[{"staticSize":16, "dynamicSize":4, "exclusiveSize":20, "length":1, "capacity":1, "elementStaticSize":4}]'

View File

@ -0,0 +1,21 @@
includes = ["folly/sorted_vector_types.h", "vector"]
[cases]
[cases.int_int_empty]
param_types = ["const folly::sorted_vector_map<int, int>&"]
setup = "return {};"
expect_json = '[{"staticSize":24, "dynamicSize":0, "exclusiveSize":24, "length":0, "capacity":0, "elementStaticSize":8}]'
[cases.int_int_some]
param_types = ["const folly::sorted_vector_map<int, int>&"]
setup = "return {{ {1,2}, {3,4} }};"
expect_json = '[{"staticSize":24, "dynamicSize":16, "exclusiveSize":40, "length":2, "capacity":2, "elementStaticSize":8}]'
[cases.int_vector_empty]
skip = "Wrong results" # https://github.com/facebookexperimental/object-introspection/issues/258
param_types = ["const folly::sorted_vector_map<int, std::vector<int>>&"]
setup = "return {};"
expect_json = '[{"staticSize":24, "dynamicSize":0, "exclusiveSize":24, "length":0, "capacity":0, "elementStaticSize":32}]'
[cases.int_vector_some]
skip = "Wrong results" # https://github.com/facebookexperimental/object-introspection/issues/258
param_types = ["const folly::sorted_vector_map<int, std::vector<int>>&"]
setup = "return {{ {1,{2,3}}, {4,{5,6,7}} }};"
#expect_json = "TODO"

View File

@ -2,6 +2,7 @@
type_name = "folly::sorted_vector_map"
ctype = "MAP_SEQ_TYPE"
header = "folly/sorted_vector_types.h"
stub_template_params = [2,3]
# Old:
typeName = "folly::sorted_vector_map<"
@ -34,3 +35,34 @@ void getSizeType(const %1%<Key, Value, Compare, Allocator, GrowthPolicy, Contain
}
}
"""
handler = """
template <typename DB, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
struct TypeHandler<DB, %1%<T0, T1, T2, T3, T4, T5>> {
using type = types::st::Pair<DB,
types::st::VarInt<DB>,
types::st::Pair<DB,
types::st::VarInt<DB>,
types::st::List<DB, types::st::Pair<DB,
typename TypeHandler<DB, T0>::type,
typename TypeHandler<DB, T1>::type
>>>>;
static types::st::Unit<DB> getSizeType(
const %1%<T0, T1, T2, T3, T4, T5>& container,
typename TypeHandler<DB, %1%<T0, T1, T2, T3, T4, T5>>::type returnArg) {
auto tail = returnArg.write((uintptr_t)&container)
.write(container.capacity())
.write(container.size());
for (const auto& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it.second, ret.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it.first, ret);
}));
});
}
return tail.finish();
}
};
"""

View File

@ -2,6 +2,7 @@
type_name = "folly::small_vector"
ctype = "SMALL_VEC_TYPE"
header = "folly/small_vector.h"
stub_template_params = [2]
# Old:
typeName = "folly::small_vector<"
@ -20,6 +21,17 @@ template <class V, std::size_t N, class P>
void getSizeType(const %1%<V, N, P> &container, size_t& returnArg)
{
SAVE_SIZE(sizeof(%1%<V, N, P>));
bool dataInlined = ((uintptr_t)container.data() >= (uintptr_t)&container) &&
((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<V, N, P>)));
if (dataInlined) {
// Don't double count inlined elements
SAVE_SIZE(-(container.size() * sizeof(V)));
} else {
// Account for wasted space in the buffer
SAVE_SIZE((container.capacity() - container.size()) * sizeof(V));
}
SAVE_DATA((uintptr_t)(N));
SAVE_DATA((uintptr_t)container.capacity());
SAVE_DATA((uintptr_t)container.size());
@ -29,3 +41,29 @@ void getSizeType(const %1%<V, N, P> &container, size_t& returnArg)
}
}
"""
handler = """
template <typename DB, typename T0, std::size_t N0, typename T1>
struct TypeHandler<DB, %1%<T0, N0, T1>> {
using type = types::st::Pair<
DB, types::st::VarInt<DB>,
types::st::Pair<
DB, types::st::VarInt<DB>,
types::st::List<DB, typename TypeHandler<DB, T0>::type>>>;
static types::st::Unit<DB> getSizeType(
const %1%<T0, N0, T1> & container,
typename TypeHandler<DB, %1%<T0, N0, T1>>::type returnArg) {
auto tail = returnArg.write(N0)
.write(container.capacity())
.write(container.size());
for (auto& it : container) {
tail = tail.delegate([&it](auto ret) {
return OIInternal::getSizeType<DB>(it, ret);
});
}
return tail.finish();
}
};
"""