* move `ExecuteTimings` from `runtime::bank` to `program_runtime::timings` (cherry picked from commit7d32909e17
) # Conflicts: # core/Cargo.toml # ledger/Cargo.toml # programs/bpf/Cargo.lock * Add execute metrics (cherry picked from commitb25e4a200b
) * Add metrics for executor creation (cherry picked from commit848b6dfbdd
) * Add helper macro for `AddAssign`ing with saturating arithmetic (cherry picked from commitdeb9344e49
) * Use saturating_add_assign macro (cherry picked from commit72fc6096a0
) * Consolidate process instruction execution timings to own struct (cherry picked from commit390ef0fbcd
) Co-authored-by: Trent Nelson <trent@solana.com> Co-authored-by: Carl Lin <carl@solana.com>
This commit is contained in:
@@ -51,6 +51,7 @@ use {
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
rent::Rent,
|
||||
saturating_add_assign,
|
||||
system_instruction::{self, MAX_PERMITTED_DATA_LENGTH},
|
||||
},
|
||||
std::{cell::RefCell, fmt::Debug, pin::Pin, rc::Rc, sync::Arc},
|
||||
@@ -85,7 +86,14 @@ pub fn create_executor(
|
||||
use_jit: bool,
|
||||
reject_deployment_of_broken_elfs: bool,
|
||||
) -> Result<Arc<BpfExecutor>, InstructionError> {
|
||||
let syscall_registry = syscalls::register_syscalls(invoke_context).map_err(|e| {
|
||||
let mut register_syscalls_time = Measure::start("register_syscalls_time");
|
||||
let register_syscall_result = syscalls::register_syscalls(invoke_context);
|
||||
register_syscalls_time.stop();
|
||||
invoke_context.timings.create_executor_register_syscalls_us = invoke_context
|
||||
.timings
|
||||
.create_executor_register_syscalls_us
|
||||
.saturating_add(register_syscalls_time.as_us());
|
||||
let syscall_registry = register_syscall_result.map_err(|e| {
|
||||
ic_msg!(invoke_context, "Failed to register syscalls: {}", e);
|
||||
InstructionError::ProgramEnvironmentSetupFailure
|
||||
})?;
|
||||
@@ -116,20 +124,40 @@ pub fn create_executor(
|
||||
let mut executable = {
|
||||
let keyed_accounts = invoke_context.get_keyed_accounts()?;
|
||||
let programdata = keyed_account_at_index(keyed_accounts, programdata_account_index)?;
|
||||
Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
||||
let mut load_elf_time = Measure::start("load_elf_time");
|
||||
let executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
|
||||
&programdata.try_account_ref()?.data()[programdata_offset..],
|
||||
None,
|
||||
config,
|
||||
syscall_registry,
|
||||
)
|
||||
);
|
||||
load_elf_time.stop();
|
||||
invoke_context.timings.create_executor_load_elf_us = invoke_context
|
||||
.timings
|
||||
.create_executor_load_elf_us
|
||||
.saturating_add(load_elf_time.as_us());
|
||||
executable
|
||||
}
|
||||
.map_err(|e| map_ebpf_error(invoke_context, e))?;
|
||||
let text_bytes = executable.get_text_bytes().1;
|
||||
let mut verify_code_time = Measure::start("verify_code_time");
|
||||
verifier::check(text_bytes, &config)
|
||||
.map_err(|e| map_ebpf_error(invoke_context, EbpfError::UserError(e.into())))?;
|
||||
verify_code_time.stop();
|
||||
invoke_context.timings.create_executor_verify_code_us = invoke_context
|
||||
.timings
|
||||
.create_executor_verify_code_us
|
||||
.saturating_add(verify_code_time.as_us());
|
||||
if use_jit {
|
||||
if let Err(err) = Executable::<BpfError, ThisInstructionMeter>::jit_compile(&mut executable)
|
||||
{
|
||||
let mut jit_compile_time = Measure::start("jit_compile_time");
|
||||
let jit_compile_result =
|
||||
Executable::<BpfError, ThisInstructionMeter>::jit_compile(&mut executable);
|
||||
jit_compile_time.stop();
|
||||
invoke_context.timings.create_executor_jit_compile_us = invoke_context
|
||||
.timings
|
||||
.create_executor_jit_compile_us
|
||||
.saturating_add(jit_compile_time.as_us());
|
||||
if let Err(err) = jit_compile_result {
|
||||
ic_msg!(invoke_context, "Failed to compile program {:?}", err);
|
||||
return Err(InstructionError::ProgramFailedToCompile);
|
||||
}
|
||||
@@ -291,6 +319,7 @@ fn process_instruction_common(
|
||||
0
|
||||
};
|
||||
|
||||
let mut get_or_create_executor_time = Measure::start("get_or_create_executor_time");
|
||||
let executor = match invoke_context.get_executor(program_id) {
|
||||
Some(executor) => executor,
|
||||
None => {
|
||||
@@ -306,6 +335,12 @@ fn process_instruction_common(
|
||||
executor
|
||||
}
|
||||
};
|
||||
get_or_create_executor_time.stop();
|
||||
saturating_add_assign!(
|
||||
invoke_context.timings.get_or_create_executor_us,
|
||||
get_or_create_executor_time.as_us()
|
||||
);
|
||||
|
||||
executor.execute(
|
||||
next_first_instruction_account,
|
||||
instruction_data,
|
||||
|
@@ -7,6 +7,7 @@ use {
|
||||
ic_logger_msg, ic_msg,
|
||||
invoke_context::{ComputeMeter, InvokeContext},
|
||||
stable_log,
|
||||
timings::ExecuteTimings,
|
||||
},
|
||||
solana_rbpf::{
|
||||
aligned_memory::AlignedMemory,
|
||||
@@ -2371,6 +2372,7 @@ fn call<'a, 'b: 'a>(
|
||||
&program_indices,
|
||||
&account_indices,
|
||||
&caller_write_privileges,
|
||||
&mut ExecuteTimings::default(),
|
||||
)
|
||||
.result
|
||||
.map_err(SyscallError::InstructionError)?;
|
||||
|
Reference in New Issue
Block a user