mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-09 13:14:55 +00:00
Implement Container V2 for folly::small_vector
This commit is contained in:
parent
465303cb99
commit
331c47705c
@ -1,28 +1,27 @@
|
||||
includes = ["folly/small_vector.h", "vector"]
|
||||
[cases]
|
||||
[cases.int_default_empty]
|
||||
oil_skip = 'not implemented for treebuilder v2' # https://github.com/facebookexperimental/object-introspection/issues/321
|
||||
param_types = ["const folly::small_vector<int>&"]
|
||||
setup = "return {};"
|
||||
expect_json = '[{"staticSize":16, "dynamicSize":0, "exclusiveSize":16, "length":0, "capacity":2, "elementStaticSize":4}]'
|
||||
expect_json_v2 = '[{"staticSize":16, "exclusiveSize":16, "length":0, "capacity":2}]'
|
||||
[cases.int_default_inlined]
|
||||
oil_skip = 'not implemented for treebuilder v2' # https://github.com/facebookexperimental/object-introspection/issues/321
|
||||
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}]'
|
||||
expect_json_v2 = '[{"staticSize":16, "exclusiveSize":8, "length":2, "capacity":2}]'
|
||||
[cases.int_default_overflow]
|
||||
oil_skip = 'not implemented for treebuilder v2' # https://github.com/facebookexperimental/object-introspection/issues/321
|
||||
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}]'
|
||||
expect_json_v2 = '[{"staticSize":16, "exclusiveSize":24, "length":4, "capacity":6}]'
|
||||
|
||||
[cases.vector_3_empty]
|
||||
oil_skip = 'not implemented for treebuilder v2' # https://github.com/facebookexperimental/object-introspection/issues/321
|
||||
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}]'
|
||||
expect_json_v2 = '[{"staticSize":80, "exclusiveSize":80, "length":0, "capacity":3}]'
|
||||
[cases.vector_3_inlined]
|
||||
oil_skip = 'not implemented for treebuilder v2' # https://github.com/facebookexperimental/object-introspection/issues/321
|
||||
param_types = ["const folly::small_vector<std::vector<int>, 3>&"]
|
||||
setup = "return {{ {1,2,3}, {4}, {5,6} }};"
|
||||
expect_json = '''[
|
||||
@ -31,8 +30,13 @@ includes = ["folly/small_vector.h", "vector"]
|
||||
{"staticSize":24, "dynamicSize":4, "exclusiveSize":28, "length":1, "capacity":1, "elementStaticSize":4},
|
||||
{"staticSize":24, "dynamicSize":8, "exclusiveSize":32, "length":2, "capacity":2, "elementStaticSize":4}
|
||||
]}]'''
|
||||
expect_json_v2 = '''[
|
||||
{"staticSize":80, "length":3, "exclusiveSize":8, "capacity":3, "members":[
|
||||
{"staticSize":24, "exclusiveSize":24, "length":3, "capacity":3},
|
||||
{"staticSize":24, "exclusiveSize":24, "length":1, "capacity":1},
|
||||
{"staticSize":24, "exclusiveSize":24, "length":2, "capacity":2}
|
||||
]}]'''
|
||||
[cases.vector_3_overflow]
|
||||
oil_skip = 'not implemented for treebuilder v2' # https://github.com/facebookexperimental/object-introspection/issues/321
|
||||
param_types = ["const folly::small_vector<std::vector<int>, 3>&"]
|
||||
setup = "return {{ {1,2,3}, {4}, {5,6}, {7} }};"
|
||||
expect_json = '''[
|
||||
@ -42,9 +46,16 @@ includes = ["folly/small_vector.h", "vector"]
|
||||
{"staticSize":24, "dynamicSize":8, "exclusiveSize":32, "length":2, "capacity":2, "elementStaticSize":4},
|
||||
{"staticSize":24, "dynamicSize":4, "exclusiveSize":28, "length":1, "capacity":1, "elementStaticSize":4}
|
||||
]}]'''
|
||||
expect_json_v2 = '''[
|
||||
{"staticSize":80, "exclusiveSize":104, "length":4, "capacity":5, "members":[
|
||||
{"staticSize":24, "exclusiveSize":24, "length":3, "capacity":3},
|
||||
{"staticSize":24, "exclusiveSize":24, "length":1, "capacity":1},
|
||||
{"staticSize":24, "exclusiveSize":24, "length":2, "capacity":2},
|
||||
{"staticSize":24, "exclusiveSize":24, "length":1, "capacity":1}
|
||||
]}]'''
|
||||
|
||||
[cases.int_always_heap]
|
||||
oil_skip = 'not implemented for treebuilder v2' # https://github.com/facebookexperimental/object-introspection/issues/321
|
||||
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}]'
|
||||
expect_json_v2 = '[{"staticSize":16, "exclusiveSize":16, "length":1, "capacity":1}]'
|
||||
|
@ -41,6 +41,7 @@ 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>> {
|
||||
@ -67,3 +68,63 @@ struct TypeHandler<DB, %1%<T0, N0, T1>> {
|
||||
}
|
||||
};
|
||||
"""
|
||||
|
||||
traversal_func = """
|
||||
// If `container.data()` pointer is within the container struct,
|
||||
// then the container's storage is inlined and doesn't uses the heap.
|
||||
// TODO: Is there an API to get this information?
|
||||
bool uses_intern_storage =
|
||||
(uintptr_t)&container <= (uintptr_t)container.data() &&
|
||||
(uintptr_t)container.data() < ((uintptr_t)&container + sizeof(container));
|
||||
|
||||
auto tail = returnArg
|
||||
.write((uintptr_t)uses_intern_storage)
|
||||
.write(container.capacity())
|
||||
.write(container.size());
|
||||
|
||||
for (auto &&it: container) {
|
||||
tail = tail.delegate([&it](typename TypeHandler<DB, T0>::type ret) {
|
||||
return OIInternal::getSizeType<DB>(it, ret);
|
||||
});
|
||||
}
|
||||
|
||||
return tail.finish();
|
||||
"""
|
||||
|
||||
[[codegen.processor]]
|
||||
type = "types::st::VarInt<DB>"
|
||||
func = """
|
||||
// Using the container's pointer to temporarily store the uses_intern_storage boolean.
|
||||
// TODO: Is there another way to pass a value across processors?
|
||||
el.pointer = std::get<ParsedData::VarInt>(d.val).value;
|
||||
"""
|
||||
|
||||
[[codegen.processor]]
|
||||
type = "types::st::VarInt<DB>"
|
||||
func = """
|
||||
el.container_stats.emplace(result::Element::ContainerStats {
|
||||
.capacity = std::get<ParsedData::VarInt>(d.val).value,
|
||||
});
|
||||
"""
|
||||
|
||||
[[codegen.processor]]
|
||||
type = "types::st::List<DB, typename TypeHandler<DB, T0>::type>"
|
||||
func = """
|
||||
// Reading the `uses_intern_storage` boolean that was stored in `pointer` by the processor above.
|
||||
bool uses_intern_storage = std::exchange(el.pointer.value(), (uintptr_t)0);
|
||||
|
||||
auto list = std::get<ParsedData::List>(d.val);
|
||||
el.container_stats->length = list.length;
|
||||
|
||||
if (uses_intern_storage) {
|
||||
// The storage is inlined, so don't double count for items using the intern storage.
|
||||
el.exclusive_size -= list.length * sizeof(T0);
|
||||
} else {
|
||||
// The storage is heap allocated, so add any unused capacity.
|
||||
el.exclusive_size += (el.container_stats->capacity - el.container_stats->length) * sizeof(T0);
|
||||
}
|
||||
|
||||
static constexpr auto childField = make_field<DB, T0>("[]");
|
||||
for (size_t i = 0; i < list.length; i++)
|
||||
ins.emplace(childField);
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user