Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
evict wasm_cache entries once the last block they are used in becomes…
Browse files Browse the repository at this point in the history
… irreversible

the wasm_cache needs to be periodically pruned of old entries. controller will now note to wasm_interface when the reference count of some code_hash goes to 0 and wasm_interface will then evict those entries once that block becomes irreversible. Unfortunately there are still many corner cases that can cause items in the cache to never be evicted or evicted too soon, but some reasonably accurate eviction is direly needed for long replays so this is considered good enough for now
  • Loading branch information
spoonincode committed Apr 22, 2019
1 parent 60db0ae commit 097e745
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 0 deletions.
4 changes: 4 additions & 0 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,10 @@ struct controller_impl {
set_activation_handler<builtin_protocol_feature_t::replace_deferred>();
set_activation_handler<builtin_protocol_feature_t::get_sender>();

self.irreversible_block.connect([this](const block_state_ptr& bsp) {
wasmif.current_lib(bsp->block_num);
});


#define SET_APP_HANDLER( receiver, contract, action) \
set_apply_handler( #receiver, #contract, #action, &BOOST_PP_CAT(apply_, BOOST_PP_CAT(contract, BOOST_PP_CAT(_,action) ) ) )
Expand Down
1 change: 1 addition & 0 deletions libraries/chain/eosio_contract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ void apply_eosio_setcode(apply_context& context) {
old_size = (int64_t)old_code_entry.code.size() * config::setcode_ram_bytes_multiplier;
if( old_code_entry.code_ref_count == 1 ) {
db.remove(old_code_entry);
context.control.get_wasm_interface().code_block_num_last_used(account.code_hash, account.vm_type, account.vm_version, context.control.head_block_num() + 1);
} else {
db.modify(old_code_entry, [](code_object& o) {
--o.code_ref_count;
Expand Down
6 changes: 6 additions & 0 deletions libraries/chain/include/eosio/chain/wasm_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ namespace eosio { namespace chain {
//validates code -- does a WASM validation pass and checks the wasm against EOSIO specific constraints
static void validate(const controller& control, const bytes& code);

//indicate that a particular code probably won't be used after given block_num
void code_block_num_last_used(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version, const uint32_t& block_num);

//indicate the current LIB. evicts old cache entries
void current_lib(const uint32_t lib);

//Calls apply or error on a given code
void apply(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version, apply_context& context);

Expand Down
13 changes: 13 additions & 0 deletions libraries/chain/include/eosio/chain/wasm_interface_private.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ namespace eosio { namespace chain {
return mem_image;
}

void code_block_num_last_used(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version, const uint32_t& block_num) {
wasm_cache_index::iterator it = wasm_instantiation_cache.find(boost::make_tuple(code_hash, vm_type, vm_version));
if(it != wasm_instantiation_cache.end())
wasm_instantiation_cache.modify(it, [block_num](wasm_cache_entry& e) {
e.last_block_num_used = block_num;
});
}

void current_lib(uint32_t lib) {
//anything last used before or on the LIB can be evicted
wasm_instantiation_cache.get<by_last_block_num>().erase(wasm_instantiation_cache.get<by_last_block_num>().begin(), wasm_instantiation_cache.get<by_last_block_num>().upper_bound(lib));
}

const std::unique_ptr<wasm_instantiated_module_interface>& get_instantiated_module( const digest_type& code_hash, const uint8_t& vm_type,
const uint8_t& vm_version, transaction_context& trx_context )
{
Expand Down
8 changes: 8 additions & 0 deletions libraries/chain/wasm_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ namespace eosio { namespace chain {
//Hard: Kick off instantiation in a separate thread at this location
}

void wasm_interface::code_block_num_last_used(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version, const uint32_t& block_num) {
my->code_block_num_last_used(code_hash, vm_type, vm_version, block_num);
}

void wasm_interface::current_lib(const uint32_t lib) {
my->current_lib(lib);
}

void wasm_interface::apply( const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version, apply_context& context ) {
my->get_instantiated_module(code_hash, vm_type, vm_version, context.trx_context)->apply(context);
}
Expand Down

0 comments on commit 097e745

Please sign in to comment.