blob: 446c4fd02b0cc061563c31f88e6f6101588580a2 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Benchmarks for a reference encoder / decoder specialized to
// Table1Struct, Table16Struct and Table63Struct as defined in
// the fidl benchmark suite.
#include <lib/fit/function.h>
#include <zircon/fidl.h>
#include <algorithm>
#include <cstdint>
#include "builder.h"
#include "decode_benchmark_util.h"
#include "encode_benchmark_util.h"
#ifdef __Fuchsia__
#include <zircon/syscalls.h>
#endif
namespace {
template <size_t N>
bool EncodeUint8TableStruct(void* value, const char** error,
fit::function<void(const uint8_t*, size_t)> callback) {
uint8_t out_buf[sizeof(fidl_vector_t) + sizeof(fidl_envelope_t) * N];
fidl_vector_t* table_vec = reinterpret_cast<fidl_vector_t*>(value);
size_t count = table_vec->count;
void* data = table_vec->data;
if (unlikely(data == nullptr && count != 0)) {
*error = "table with null data had non-zero element count";
return false;
}
*reinterpret_cast<fidl_vector_t*>(out_buf) = fidl_vector_t{
.count = count,
.data = reinterpret_cast<void*>(FIDL_ALLOC_PRESENT),
};
memcpy(out_buf + sizeof(fidl_vector_t), data, sizeof(fidl_envelope_t) * N);
callback(out_buf, sizeof out_buf);
return true;
}
template <size_t N>
bool DecodeUint8TableStruct(uint8_t* bytes, size_t bytes_size, zx_handle_t* handles,
size_t handles_size, const char** error) {
if (handles_size != 0) {
*error = "no handles expected";
return false;
}
fidl_vector_t* table_vec = reinterpret_cast<fidl_vector_t*>(bytes);
if (unlikely(table_vec->data == nullptr && table_vec->count != 0)) {
*error = "table with null data had non-zero element count";
return false;
}
fidl_envelope_t* start_envelopes =
reinterpret_cast<fidl_envelope_t*>(bytes + sizeof(fidl_vector_t));
table_vec->data = start_envelopes;
fidl_envelope_t* end_known_envelopes = start_envelopes + std::min(N, table_vec->count);
fidl_envelope_t* end_all_envelopes = start_envelopes + table_vec->count;
uint8_t* next_out_of_line = reinterpret_cast<uint8_t*>(end_all_envelopes);
if (unlikely(next_out_of_line - bytes > static_cast<int64_t>(bytes_size))) {
*error = "byte size exceeds available size";
return false;
}
for (fidl_envelope_t* envelope = start_envelopes; envelope != end_known_envelopes; envelope++) {
if (unlikely(envelope->num_handles != 0)) {
*error = "incorrect num_handles in envelope";
return false;
}
if (unlikely(envelope->flags != FIDL_ENVELOPE_FLAGS_INLINING_MASK)) {
*error = "invalid envelope flags";
return false;
}
}
// Unknown envelopes
uint32_t num_handles = 0;
for (fidl_envelope_t* envelope = end_known_envelopes; envelope != end_all_envelopes; envelope++) {
uint16_t flags = envelope->flags;
if (flags == FIDL_ENVELOPE_FLAGS_INLINING_MASK) {
continue;
}
if (unlikely(flags != 0)) {
*error = "invalid envelope flags";
return false;
}
size_t num_bytes = envelope->num_bytes;
if (unlikely(num_bytes % 8 != 0)) {
*error = "incorrect num_bytes in envelope";
return false;
}
num_handles += envelope->num_handles;
auto envelope_as_ptr = reinterpret_cast<uint8_t**>(envelope);
*envelope_as_ptr = next_out_of_line;
next_out_of_line += num_bytes;
if (unlikely(next_out_of_line - bytes > static_cast<int64_t>(bytes_size))) {
*error = "byte size exceeds available size";
return false;
}
}
#ifdef __Fuchsia__
zx_handle_close_many(handles, num_handles);
#endif
return true;
}
bool BenchmarkEncodeTableAllSet1(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(state, benchmark_suite::Build_Table_AllSet_1,
EncodeUint8TableStruct<1>);
}
bool BenchmarkEncodeTableAllSet16(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(state, benchmark_suite::Build_Table_AllSet_16,
EncodeUint8TableStruct<16>);
}
bool BenchmarkEncodeTableAllSet63(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(state, benchmark_suite::Build_Table_AllSet_63,
EncodeUint8TableStruct<63>);
}
bool BenchmarkEncodeTableUnset1(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(state, benchmark_suite::Build_Table_Unset_1,
EncodeUint8TableStruct<1>);
}
bool BenchmarkEncodeTableUnset16(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(state, benchmark_suite::Build_Table_Unset_16,
EncodeUint8TableStruct<16>);
}
bool BenchmarkEncodeTableUnset63(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(state, benchmark_suite::Build_Table_Unset_63,
EncodeUint8TableStruct<63>);
}
bool BenchmarkEncodeTableSingleSet_1_of_1(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_1_of_1, EncodeUint8TableStruct<1>);
}
bool BenchmarkEncodeTableSingleSet_1_of_16(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_1_of_16, EncodeUint8TableStruct<16>);
}
bool BenchmarkEncodeTableSingleSet_16_of_16(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_16_of_16, EncodeUint8TableStruct<16>);
}
bool BenchmarkEncodeTableSingleSet_1_of_63(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_1_of_63, EncodeUint8TableStruct<63>);
}
bool BenchmarkEncodeTableSingleSet_16_of_63(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_16_of_63, EncodeUint8TableStruct<63>);
}
bool BenchmarkEncodeTableSingleSet_63_of_63(perftest::RepeatState* state) {
return encode_benchmark_util::EncodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_63_of_63, EncodeUint8TableStruct<63>);
}
bool BenchmarkDecodeTableAllSet1(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(state, benchmark_suite::Build_Table_AllSet_1,
DecodeUint8TableStruct<1>);
}
bool BenchmarkDecodeTableAllSet16(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(state, benchmark_suite::Build_Table_AllSet_16,
DecodeUint8TableStruct<16>);
}
bool BenchmarkDecodeTableAllSet63(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(state, benchmark_suite::Build_Table_AllSet_63,
DecodeUint8TableStruct<63>);
}
bool BenchmarkDecodeTableUnset1(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(state, benchmark_suite::Build_Table_Unset_1,
DecodeUint8TableStruct<1>);
}
bool BenchmarkDecodeTableUnset16(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(state, benchmark_suite::Build_Table_Unset_16,
DecodeUint8TableStruct<16>);
}
bool BenchmarkDecodeTableUnset63(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(state, benchmark_suite::Build_Table_Unset_63,
DecodeUint8TableStruct<63>);
}
bool BenchmarkDecodeTableSingleSet_1_of_1(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_1_of_1, DecodeUint8TableStruct<1>);
}
bool BenchmarkDecodeTableSingleSet_1_of_16(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_1_of_16, DecodeUint8TableStruct<16>);
}
bool BenchmarkDecodeTableSingleSet_16_of_16(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_16_of_16, DecodeUint8TableStruct<16>);
}
bool BenchmarkDecodeTableSingleSet_1_of_63(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_1_of_63, DecodeUint8TableStruct<63>);
}
bool BenchmarkDecodeTableSingleSet_16_of_63(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_16_of_63, DecodeUint8TableStruct<63>);
}
bool BenchmarkDecodeTableSingleSet_63_of_63(perftest::RepeatState* state) {
return decode_benchmark_util::DecodeBenchmark(
state, benchmark_suite::Build_Table_SingleSet_63_of_63, DecodeUint8TableStruct<63>);
}
void RegisterTests() {
perftest::RegisterTest("Reference/Encode/Table/AllSet/1/Steps", BenchmarkEncodeTableAllSet1);
perftest::RegisterTest("Reference/Encode/Table/AllSet/16/Steps", BenchmarkEncodeTableAllSet16);
perftest::RegisterTest("Reference/Encode/Table/AllSet/63/Steps", BenchmarkEncodeTableAllSet63);
perftest::RegisterTest("Reference/Encode/Table/Unset/1/Steps", BenchmarkEncodeTableUnset1);
perftest::RegisterTest("Reference/Encode/Table/Unset/16/Steps", BenchmarkEncodeTableUnset16);
perftest::RegisterTest("Reference/Encode/Table/Unset/63/Steps", BenchmarkEncodeTableUnset63);
perftest::RegisterTest("Reference/Encode/Table/SingleSet/1_of_1/Steps",
BenchmarkEncodeTableSingleSet_1_of_1);
perftest::RegisterTest("Reference/Encode/Table/SingleSet/1_of_16/Steps",
BenchmarkEncodeTableSingleSet_1_of_16);
perftest::RegisterTest("Reference/Encode/Table/SingleSet/16_of_16/Steps",
BenchmarkEncodeTableSingleSet_16_of_16);
perftest::RegisterTest("Reference/Encode/Table/SingleSet/1_of_63/Steps",
BenchmarkEncodeTableSingleSet_1_of_63);
perftest::RegisterTest("Reference/Encode/Table/SingleSet/16_of_63/Steps",
BenchmarkEncodeTableSingleSet_16_of_63);
perftest::RegisterTest("Reference/Encode/Table/SingleSet/63_of_63/Steps",
BenchmarkEncodeTableSingleSet_63_of_63);
perftest::RegisterTest("Reference/Decode/Table/AllSet/1/Steps", BenchmarkDecodeTableAllSet1);
perftest::RegisterTest("Reference/Decode/Table/AllSet/16/Steps", BenchmarkDecodeTableAllSet16);
perftest::RegisterTest("Reference/Decode/Table/AllSet/63/Steps", BenchmarkDecodeTableAllSet63);
perftest::RegisterTest("Reference/Decode/Table/Unset/1/Steps", BenchmarkDecodeTableUnset1);
perftest::RegisterTest("Reference/Decode/Table/Unset/16/Steps", BenchmarkDecodeTableUnset16);
perftest::RegisterTest("Reference/Decode/Table/Unset/63/Steps", BenchmarkDecodeTableUnset63);
perftest::RegisterTest("Reference/Decode/Table/SingleSet/1_of_1/Steps",
BenchmarkDecodeTableSingleSet_1_of_1);
perftest::RegisterTest("Reference/Decode/Table/SingleSet/1_of_16/Steps",
BenchmarkDecodeTableSingleSet_1_of_16);
perftest::RegisterTest("Reference/Decode/Table/SingleSet/16_of_16/Steps",
BenchmarkDecodeTableSingleSet_16_of_16);
perftest::RegisterTest("Reference/Decode/Table/SingleSet/1_of_63/Steps",
BenchmarkDecodeTableSingleSet_1_of_63);
perftest::RegisterTest("Reference/Decode/Table/SingleSet/16_of_63/Steps",
BenchmarkDecodeTableSingleSet_16_of_63);
perftest::RegisterTest("Reference/Decode/Table/SingleSet/63_of_63/Steps",
BenchmarkDecodeTableSingleSet_63_of_63);
}
PERFTEST_CTOR(RegisterTests)
} // namespace