Skip to content

Commit

Permalink
Feature gating
Browse files Browse the repository at this point in the history
  • Loading branch information
georgemitenkov committed Nov 12, 2024
1 parent 63040f3 commit f190968
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 29 deletions.
31 changes: 20 additions & 11 deletions aptos-move/aptos-vm/src/block_executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,17 +432,26 @@ impl BlockAptosVM {

BLOCK_EXECUTOR_CONCURRENCY.set(config.local.concurrency_level as i64);

if !module_cache_manager.mark_ready(parent_block, current_block) {
return Err(VMStatus::error(
StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR,
Some("Unable to mark module caches for block execution as ready".to_string()),
));
}
let (environment, module_cache) = module_cache_manager
.check_ready_and_get_caches(state_view, &config.local.module_cache_config)?;
let environment =
AptosEnvironment::new_with_delayed_field_optimization_enabled(&state_view);
let is_loader_v2_enabled = environment.features().is_loader_v2_enabled();

let (environment, module_cache) = if is_loader_v2_enabled {
if !module_cache_manager.mark_ready(parent_block, current_block) {
return Err(VMStatus::error(
StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR,
Some("Unable to mark module caches for block execution as ready".to_string()),
));
}
module_cache_manager
.check_ready_and_get_caches(environment, &config.local.module_cache_config)?
} else {
(environment, Arc::new(GlobalModuleCache::empty()))
};

// Finally, to avoid cold starts, fetch the framework code prior to block execution.
if module_cache.num_modules() == 0
if is_loader_v2_enabled
&& module_cache.num_modules() == 0
&& config.local.module_cache_config.prefetch_framework_code
{
let code_storage = state_view.as_aptos_code_storage(environment.clone());
Expand All @@ -465,14 +474,14 @@ impl BlockAptosVM {
transaction_commit_listener,
);

if !module_cache_manager.mark_executing() {
if is_loader_v2_enabled && !module_cache_manager.mark_executing() {
return Err(VMStatus::error(
StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR,
Some("Unable to mark block execution start".to_string()),
));
}
let ret = executor.execute_block(environment, signature_verified_block, state_view);
if !module_cache_manager.mark_done() {
if is_loader_v2_enabled && !module_cache_manager.mark_done() {
return Err(VMStatus::error(
StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR,
Some("Unable to mark block execution as done".to_string()),
Expand Down
42 changes: 24 additions & 18 deletions aptos-move/block-executor/src/code_cache_global_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

use crate::{code_cache_global::GlobalModuleCache, explicit_sync_wrapper::ExplicitSyncWrapper};
use aptos_types::{
block_executor::config::BlockExecutorModuleCacheLocalConfig, state_store::StateView,
};
use aptos_types::block_executor::config::BlockExecutorModuleCacheLocalConfig;
use aptos_vm_environment::environment::AptosEnvironment;
use move_binary_format::errors::Location;
use move_core_types::vm_status::{StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR, VMStatus};
Expand Down Expand Up @@ -128,7 +126,7 @@ where
/// The final environment and module caches are returned.
pub fn check_ready_and_get_caches(
&self,
state_view: &impl StateView,
storage_environment: AptosEnvironment,
config: &BlockExecutorModuleCacheLocalConfig,
) -> Result<(AptosEnvironment, Arc<GlobalModuleCache<K, DC, VC, E>>), VMStatus> {
let state = self.state.lock();
Expand All @@ -143,7 +141,7 @@ where
));
}

let environment = self.get_or_initialize_environment(state_view);
let environment = self.get_or_initialize_environment(storage_environment);
let module_cache = self.module_cache.clone();

// Check 1: struct re-indexing map is not too large. If it is, we flush the cache. Also, we
Expand Down Expand Up @@ -196,18 +194,18 @@ where
/// Returns the cached global environment if it already exists, and matches the one in storage.
/// If it does not exist, or does not match, the new environment is initialized from the given
/// state, cached, and returned. Should be called when in [State::Ready] state, under lock.
fn get_or_initialize_environment(&self, state_view: &impl StateView) -> AptosEnvironment {
let new_environment =
AptosEnvironment::new_with_delayed_field_optimization_enabled(state_view);

fn get_or_initialize_environment(
&self,
storage_environment: AptosEnvironment,
) -> AptosEnvironment {
let mut guard = self.environment.acquire();
let existing_environment = guard.deref_mut();

let environment_requires_update = existing_environment
.as_ref()
.map_or(true, |environment| environment != &new_environment);
.map_or(true, |environment| environment != &storage_environment);
if environment_requires_update {
*existing_environment = Some(new_environment);
*existing_environment = Some(storage_environment);

// If this environment has been (re-)initialized, we need to flush the module cache
// because it can contain now out-dated code.
Expand Down Expand Up @@ -287,7 +285,9 @@ mod test {

// Set up the state and the environment.
*module_cache_manager.state.lock() = State::Ready(None);
let environment = module_cache_manager.get_or_initialize_environment(&state_view);
let environment = module_cache_manager.get_or_initialize_environment(
AptosEnvironment::new_with_delayed_field_optimization_enabled(&state_view),
);

module_cache_manager
.module_cache
Expand All @@ -309,7 +309,7 @@ mod test {

// Module cache size in bytes is too large, should be flushed (but not struct types).
assert!(module_cache_manager
.check_ready_and_get_caches(&state_view, &config)
.check_ready_and_get_caches(environment.clone(), &config)
.is_ok());
assert_eq!(module_cache_manager.module_cache.num_modules(), 0);
assert_eq!(
Expand All @@ -323,7 +323,7 @@ mod test {

// This time size is less than the one specified in config. No flushing.
assert!(module_cache_manager
.check_ready_and_get_caches(&state_view, &config)
.check_ready_and_get_caches(environment.clone(), &config)
.is_ok());
assert_eq!(module_cache_manager.module_cache.num_modules(), 1);
assert_eq!(
Expand Down Expand Up @@ -353,7 +353,7 @@ mod test {

// Too many struct names cached.
assert!(module_cache_manager
.check_ready_and_get_caches(&state_view, &config)
.check_ready_and_get_caches(environment.clone(), &config)
.is_ok());
assert_eq!(module_cache_manager.module_cache.num_modules(), 0);
assert_eq!(
Expand Down Expand Up @@ -527,7 +527,9 @@ mod test {

// Environment has to be set to the same value, cache flushed.
let state_view = state_view_with_changed_feature_flag(None);
let environment = module_cache_manager.get_or_initialize_environment(&state_view);
let environment = module_cache_manager.get_or_initialize_environment(
AptosEnvironment::new_with_delayed_field_optimization_enabled(&state_view),
);
assert_eq!(module_cache_manager.module_cache.num_modules(), 0);
assert!(module_cache_manager
.environment
Expand All @@ -544,7 +546,9 @@ mod test {
// Environment has to be re-set to the new value, cache flushed.
let state_view =
state_view_with_changed_feature_flag(Some(FeatureFlag::CODE_DEPENDENCY_CHECK));
let environment = module_cache_manager.get_or_initialize_environment(&state_view);
let environment = module_cache_manager.get_or_initialize_environment(
AptosEnvironment::new_with_delayed_field_optimization_enabled(&state_view),
);
assert_eq!(module_cache_manager.module_cache.num_modules(), 0);
assert!(module_cache_manager
.environment
Expand All @@ -559,7 +563,9 @@ mod test {
assert!(module_cache_manager.environment.acquire().is_some());

// Environment is kept, and module caches are not flushed.
let new_environment = module_cache_manager.get_or_initialize_environment(&state_view);
let new_environment = module_cache_manager.get_or_initialize_environment(
AptosEnvironment::new_with_delayed_field_optimization_enabled(&state_view),
);
assert_eq!(module_cache_manager.module_cache.num_modules(), 1);
assert!(environment == new_environment);
}
Expand Down

0 comments on commit f190968

Please sign in to comment.