From d2092fe73ecb32969afd15abf83bcfa3ee41b29f Mon Sep 17 00:00:00 2001 From: evoskuil Date: Mon, 5 Aug 2024 12:29:38 -0400 Subject: [PATCH 1/3] Track allocations. --- include/bitcoin/system/retainer.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/bitcoin/system/retainer.hpp b/include/bitcoin/system/retainer.hpp index 298fa08969..2ef6566c59 100644 --- a/include/bitcoin/system/retainer.hpp +++ b/include/bitcoin/system/retainer.hpp @@ -36,23 +36,23 @@ class BC_API retainer final DELETE_COPY_MOVE_DESTRUCT(retainer); inline retainer() NOEXCEPT - : /*allocation_{},*/ shared_lock_{} + : allocation_{}, shared_lock_{} { } - inline retainer(std::shared_mutex& mutex, size_t=0) NOEXCEPT - : /*allocation_{ allocation },*/ shared_lock_{ mutex } + inline retainer(std::shared_mutex& mutex, size_t allocation=0) NOEXCEPT + : allocation_{ allocation }, shared_lock_{ mutex } { } inline size_t allocation() const NOEXCEPT { - return {};//// allocation_; + return allocation_; } private: // These are thread safe. - ////size_t allocation_; + size_t allocation_; std::shared_lock shared_lock_; }; From 03a13a342a7682716be4a580ce03eae6c6b63495 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Tue, 6 Aug 2024 00:43:19 -0400 Subject: [PATCH 2/3] Replace arena::do_get_capacity() with require(). --- include/bitcoin/system/arena.hpp | 10 +++------- src/arena.cpp | 6 ++---- test/test.hpp | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/include/bitcoin/system/arena.hpp b/include/bitcoin/system/arena.hpp index 19e175112f..b71dedcd30 100644 --- a/include/bitcoin/system/arena.hpp +++ b/include/bitcoin/system/arena.hpp @@ -51,17 +51,13 @@ class arena return do_is_equal(other); } - /// Get the remaining area memory capacity (additional to std::pmr). - NODISCARD size_t get_capacity() const NOEXCEPT - { - return do_get_capacity(); - } + /// Require memory capacity, return current or nullptr (custom interface). + virtual void* require(size_t bytes) NOEXCEPT = 0; private: virtual void* do_allocate(size_t bytes, size_t align) THROWS = 0; virtual void do_deallocate(void* ptr, size_t bytes, size_t align) NOEXCEPT = 0; virtual bool do_is_equal(const arena& other) const NOEXCEPT = 0; - virtual size_t do_get_capacity() const NOEXCEPT = 0; }; /// Left can deallocate memory allocated by right and vice versa. @@ -86,12 +82,12 @@ class BC_API default_arena final { public: static arena* get() NOEXCEPT; + void* require(size_t bytes) NOEXCEPT override; private: void* do_allocate(size_t bytes, size_t align) THROWS override; void do_deallocate(void* ptr, size_t bytes, size_t align) NOEXCEPT override; bool do_is_equal(const arena& other) const NOEXCEPT override; - size_t do_get_capacity() const NOEXCEPT override; }; } // namespace libbitcoin diff --git a/src/arena.cpp b/src/arena.cpp index 95e6c088f2..4e9c9f7a50 100644 --- a/src/arena.cpp +++ b/src/arena.cpp @@ -41,7 +41,6 @@ void* default_arena::do_allocate(size_t bytes, size_t) THROWS { ////if (align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) //// return ::operator new(bytes, std::align_val_t{ align }); - return ::operator new(bytes); } @@ -49,7 +48,6 @@ void default_arena::do_deallocate(void* ptr, size_t, size_t) NOEXCEPT { ////if (align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) //// ::operator delete(ptr, std::align_val_t{ align }); - ::operator delete(ptr); } @@ -59,9 +57,9 @@ bool default_arena::do_is_equal(const arena& other) const NOEXCEPT return &other == this; } -size_t default_arena::do_get_capacity() const NOEXCEPT +void* default_arena::require(size_t) NOEXCEPT { - return max_size_t; + return nullptr; } BC_POP_WARNING() diff --git a/test/test.hpp b/test/test.hpp index 49ba03031e..dbd9e7f7b3 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -127,6 +127,11 @@ class reporting_arena size_t dec_count{}; size_t dec_bytes{}; + void* require(size_t) NOEXCEPT override + { + return nullptr; + } + private: void* do_allocate(size_t bytes, size_t align) override { @@ -157,11 +162,6 @@ class reporting_arena return &other == this; } - size_t do_get_capacity() const NOEXCEPT override - { - return {}; - } - void report(void* ptr, size_t bytes, bool allocate) const NOEXCEPT { if constexpr (Report) @@ -189,6 +189,11 @@ class mock_arena size_t do_deallocate_align{}; mutable const arena* do_is_equal_address{}; + void* require(size_t) NOEXCEPT override + { + return nullptr; + } + private: void* do_allocate(size_t bytes, size_t align) THROWS override { @@ -209,11 +214,6 @@ class mock_arena do_is_equal_address = &other; return false; } - - size_t do_get_capacity() const NOEXCEPT override - { - return {}; - } }; template From 16a90b5e12ee3e386139480e716873c4ea548147 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Tue, 6 Aug 2024 00:43:24 -0400 Subject: [PATCH 3/3] Style. --- src/chain/block.cpp | 21 ++++++--------------- src/chain/input.cpp | 24 ++++++++---------------- src/chain/operation.cpp | 3 +-- src/chain/output.cpp | 3 +-- src/chain/transaction.cpp | 32 ++++++++++---------------------- src/chain/witness.cpp | 6 ++---- 6 files changed, 28 insertions(+), 61 deletions(-) diff --git a/src/chain/block.cpp b/src/chain/block.cpp index ecafee6701..a7b69a9803 100644 --- a/src/chain/block.cpp +++ b/src/chain/block.cpp @@ -104,11 +104,9 @@ block::block(reader&& source, bool witness) NOEXCEPT } block::block(reader& source, bool witness) NOEXCEPT - : header_( - source.get_allocator().new_object(source), + : header_(source.get_allocator().new_object(source), source.get_allocator().deleter(source.get_arena())), - txs_( - source.get_allocator().new_object(), + txs_(source.get_allocator().new_object(), source.get_allocator().deleter(source.get_arena())) { assign_data(source, witness); @@ -150,8 +148,7 @@ void block::assign_data(reader& source, bool witness) NOEXCEPT txs->reserve(count); for (size_t tx = 0; tx < count; ++tx) - txs->emplace_back( - allocator.new_object(source, witness), + txs->emplace_back(allocator.new_object(source, witness), allocator.deleter(source.get_arena())); size_ = serialized_size(*txs_); @@ -284,17 +281,11 @@ block::sizes block::serialized_size( size.witnessed = ceilinged_add(size.witnessed, tx->serialized_size(true)); }); - const auto common_size = ceilinged_add( - header::serialized_size(), + const auto common_size = ceilinged_add(header::serialized_size(), variable_size(txs.size())); - const auto nominal_size = ceilinged_add( - common_size, - size.nominal); - - const auto witnessed_size = ceilinged_add( - common_size, - size.witnessed); + const auto nominal_size = ceilinged_add(common_size, size.nominal); + const auto witnessed_size = ceilinged_add(common_size, size.witnessed); return { nominal_size, witnessed_size }; } diff --git a/src/chain/input.cpp b/src/chain/input.cpp index d00bdc58fd..bc37e64f10 100644 --- a/src/chain/input.cpp +++ b/src/chain/input.cpp @@ -176,11 +176,9 @@ input::input(reader&& source) NOEXCEPT // Witness is deserialized and assigned by transaction. input::input(reader& source) NOEXCEPT - : point_( - source.get_allocator().new_object(source), + : point_(source.get_allocator().new_object(source), source.get_allocator().deleter(source.get_arena())), - script_( - source.get_allocator().new_object(source, true), + script_(source.get_allocator().new_object(source, true), source.get_allocator().deleter(source.get_arena())), witness_(nullptr), sequence_(source.read_4_bytes_little_endian()), @@ -248,12 +246,10 @@ void input::to_data(writer& sink) const NOEXCEPT // static/private input::sizes input::serialized_size(const chain::script& script) NOEXCEPT { - constexpr auto const_size = ceilinged_add( - point::serialized_size(), + constexpr auto const_size = ceilinged_add(point::serialized_size(), sizeof(sequence_)); - const auto nominal_size = ceilinged_add( - const_size, + const auto nominal_size = ceilinged_add(const_size, script.serialized_size(true)); return { nominal_size, zero }; @@ -263,16 +259,13 @@ input::sizes input::serialized_size(const chain::script& script) NOEXCEPT input::sizes input::serialized_size(const chain::script& script, const chain::witness& witness) NOEXCEPT { - constexpr auto const_size = ceilinged_add( - point::serialized_size(), + constexpr auto const_size = ceilinged_add(point::serialized_size(), sizeof(sequence_)); - const auto nominal_size = ceilinged_add( - const_size, + const auto nominal_size = ceilinged_add(const_size, script.serialized_size(true)); - const auto witnessed_size = ceilinged_add( - nominal_size, + const auto witnessed_size = ceilinged_add(nominal_size, witness.serialized_size(true)); return { nominal_size, witnessed_size }; @@ -311,8 +304,7 @@ void input::set_witness(reader& source) NOEXCEPT { auto& allocator = source.get_allocator(); - witness_.reset( - allocator.new_object(source, true), + witness_.reset(allocator.new_object(source, true), allocator.deleter(source.get_arena())); size_.witnessed = ceilinged_add(size_.nominal, diff --git a/src/chain/operation.cpp b/src/chain/operation.cpp index 3d07dc93a3..a3e09530ea 100644 --- a/src/chain/operation.cpp +++ b/src/chain/operation.cpp @@ -221,8 +221,7 @@ void operation::assign_data(reader& source) NOEXCEPT source.invalidate(); // An invalid source.read_bytes_raw returns nullptr. - allocator.construct(&data_, - source.read_bytes_raw(size), + allocator.construct(&data_, source.read_bytes_raw(size), allocator.deleter(source.get_arena())); underflow_ = !source; diff --git a/src/chain/output.cpp b/src/chain/output.cpp index 6d895278f8..7daefbe995 100644 --- a/src/chain/output.cpp +++ b/src/chain/output.cpp @@ -92,8 +92,7 @@ output::output(reader&& source) NOEXCEPT output::output(reader& source) NOEXCEPT : value_(source.read_8_bytes_little_endian()), - script_( - source.get_allocator().new_object(source, true), + script_(source.get_allocator().new_object(source, true), source.get_allocator().deleter(source.get_arena())), valid_(source), size_(serialized_size(*script_, value_)) diff --git a/src/chain/transaction.cpp b/src/chain/transaction.cpp index c8262ce78a..186805322f 100644 --- a/src/chain/transaction.cpp +++ b/src/chain/transaction.cpp @@ -158,11 +158,9 @@ transaction::transaction(reader&& source, bool witness) NOEXCEPT transaction::transaction(reader& source, bool witness) NOEXCEPT : version_(source.read_4_bytes_little_endian()), - inputs_( - source.get_allocator().new_object(), + inputs_(source.get_allocator().new_object(), source.get_allocator().deleter(source.get_arena())), - outputs_( - source.get_allocator().new_object(), + outputs_(source.get_allocator().new_object(), source.get_allocator().deleter(source.get_arena())) { assign_data(source, witness); @@ -262,16 +260,14 @@ void transaction::assign_data(reader& source, bool witness) NOEXCEPT count = source.read_size(max_block_size); ins->reserve(count); for (size_t in = 0; in < count; ++in) - ins->emplace_back( - allocator.new_object(source), + ins->emplace_back(allocator.new_object(source), allocator.deleter(source.get_arena())); auto outs = to_non_const_raw_ptr(outputs_); count = source.read_size(max_block_size); outs->reserve(count); for (size_t out = 0; out < count; ++out) - outs->emplace_back( - allocator.new_object(source), + outs->emplace_back(allocator.new_object(source), allocator.deleter(source.get_arena())); // Read or skip witnesses as specified. @@ -293,8 +289,7 @@ void transaction::assign_data(reader& source, bool witness) NOEXCEPT count = source.read_size(max_block_size); outs->reserve(count); for (size_t out = 0; out < count; ++out) - outs->emplace_back( - allocator.new_object(source), + outs->emplace_back(allocator.new_object(source), allocator.deleter(source.get_arena())); } @@ -386,26 +381,19 @@ transaction::sizes transaction::serialized_size( return ceilinged_add(total, output->serialized_size()); }; - constexpr auto base_const_size = ceilinged_add( - sizeof(version_), + constexpr auto base_const_size = ceilinged_add(sizeof(version_), sizeof(locktime_)); - constexpr auto witness_const_size = ceilinged_add( - sizeof(witness_marker), + constexpr auto witness_const_size = ceilinged_add(sizeof(witness_marker), sizeof(witness_enabled)); const auto base_size = ceilinged_add(ceilinged_add(ceilinged_add( - base_const_size, - variable_size(inputs.size())), + base_const_size, variable_size(inputs.size())), variable_size(outputs.size())), std::accumulate(outputs.begin(), outputs.end(), zero, outs)); - const auto nominal_size = ceilinged_add( - base_size, - size.nominal); - - const auto witnessed_size = ceilinged_add(ceilinged_add( - base_size, + const auto nominal_size = ceilinged_add(base_size, size.nominal); + const auto witnessed_size = ceilinged_add(ceilinged_add(base_size, witness_const_size), size.witnessed); diff --git a/src/chain/witness.cpp b/src/chain/witness.cpp index 03c96dbd98..210ddd7113 100644 --- a/src/chain/witness.cpp +++ b/src/chain/witness.cpp @@ -177,8 +177,7 @@ void witness::assign_data(reader& source, bool prefix) NOEXCEPT for (size_t element = 0; element < count; ++element) { const auto size = source.read_size(max_block_weight); - stack_.emplace_back( - source.read_bytes_raw(size), + stack_.emplace_back(source.read_bytes_raw(size), allocator.deleter(source.get_arena())); size_ = element_size(size_, stack_.back()); } @@ -188,8 +187,7 @@ void witness::assign_data(reader& source, bool prefix) NOEXCEPT while (!source.is_exhausted()) { const auto size = source.read_size(max_block_weight); - stack_.emplace_back( - source.read_bytes_raw(size), + stack_.emplace_back(source.read_bytes_raw(size), allocator.deleter(source.get_arena())); size_ = element_size(size_, stack_.back()); }