Updates rbpf to v0.2.0, (#12951)
which unifies the interfaces of the interpreter and the JIT. However, the JIT is not enabled yet.
This commit is contained in:
committed by
GitHub
parent
7b3f96ab30
commit
6606590b81
4
programs/bpf/Cargo.lock
generated
4
programs/bpf/Cargo.lock
generated
@ -2301,9 +2301,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "solana_rbpf"
|
||||
version = "0.1.32"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a95dbe2b00920ac4e1524b7442cf5319f01e8fa5742930ac60148882fd7738b"
|
||||
checksum = "09e18fa1e1b6cac20a5f2571882b7580a65ae685b1413fc498f975d07d4c968f"
|
||||
dependencies = [
|
||||
"byteorder 1.3.4",
|
||||
"combine",
|
||||
|
@ -27,7 +27,7 @@ solana-logger = { path = "../../logger", version = "1.5.0" }
|
||||
solana-measure = { path = "../../measure", version = "1.5.0" }
|
||||
solana-runtime = { path = "../../runtime", version = "1.5.0" }
|
||||
solana-sdk = { path = "../../sdk", version = "1.5.0" }
|
||||
solana_rbpf = "=0.1.32"
|
||||
solana_rbpf = "=0.2.0"
|
||||
|
||||
[[bench]]
|
||||
name = "bpf_loader"
|
||||
|
@ -6,15 +6,16 @@ extern crate test;
|
||||
extern crate solana_bpf_loader_program;
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
|
||||
use solana_bpf_loader_program::ThisInstructionMeter;
|
||||
use solana_measure::measure::Measure;
|
||||
use solana_rbpf::vm::{EbpfVm, InstructionMeter};
|
||||
use solana_rbpf::vm::{Executable, InstructionMeter};
|
||||
use solana_runtime::{
|
||||
bank::Bank,
|
||||
bank_client::BankClient,
|
||||
bpf_test_utils::MockInvokeContext,
|
||||
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
||||
loader_utils::load_program,
|
||||
process_instruction::{ComputeMeter, InvokeContext},
|
||||
process_instruction::InvokeContext,
|
||||
};
|
||||
use solana_sdk::{
|
||||
account::Account,
|
||||
@ -26,7 +27,7 @@ use solana_sdk::{
|
||||
pubkey::Pubkey,
|
||||
signature::{Keypair, Signer},
|
||||
};
|
||||
use std::{cell::RefCell, env, fs::File, io::Read, mem, path::PathBuf, rc::Rc, sync::Arc};
|
||||
use std::{cell::RefCell, env, fs::File, io::Read, mem, path::PathBuf, sync::Arc};
|
||||
use test::Bencher;
|
||||
|
||||
/// BPF program file extension
|
||||
@ -72,9 +73,7 @@ fn bench_program_create_executable(bencher: &mut Bencher) {
|
||||
let elf = load_elf("bench_alu").unwrap();
|
||||
|
||||
bencher.iter(|| {
|
||||
let _ =
|
||||
EbpfVm::<solana_bpf_loader_program::BPFError>::create_executable_from_elf(&elf, None)
|
||||
.unwrap();
|
||||
let _ = Executable::<solana_bpf_loader_program::BPFError>::from_elf(&elf, None).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
@ -92,11 +91,13 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||
|
||||
let elf = load_elf("bench_alu").unwrap();
|
||||
let executable =
|
||||
EbpfVm::<solana_bpf_loader_program::BPFError>::create_executable_from_elf(&elf, None)
|
||||
.unwrap();
|
||||
let (mut vm, _) = solana_bpf_loader_program::create_vm(
|
||||
Executable::<solana_bpf_loader_program::BPFError>::from_elf(&elf, None).unwrap();
|
||||
let compute_meter = invoke_context.get_compute_meter();
|
||||
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
||||
let mut vm = solana_bpf_loader_program::create_vm(
|
||||
&loader_id,
|
||||
executable.as_ref(),
|
||||
&mut inner_iter,
|
||||
&[],
|
||||
&mut invoke_context,
|
||||
)
|
||||
@ -105,7 +106,8 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||
println!("Interpreted:");
|
||||
assert_eq!(
|
||||
SUCCESS,
|
||||
vm.execute_program(&mut inner_iter, &[], &[]).unwrap()
|
||||
vm.execute_program_interpreted(&mut instruction_meter)
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
||||
assert_eq!(
|
||||
@ -114,7 +116,8 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||
);
|
||||
|
||||
bencher.iter(|| {
|
||||
vm.execute_program(&mut inner_iter, &[], &[]).unwrap();
|
||||
vm.execute_program_interpreted(&mut instruction_meter)
|
||||
.unwrap();
|
||||
});
|
||||
let instructions = vm.get_total_instruction_count();
|
||||
let summary = bencher.bench(|_bencher| {}).unwrap();
|
||||
@ -125,31 +128,30 @@ fn bench_program_alu(bencher: &mut Bencher) {
|
||||
println!(" {:?} MIPS", mips);
|
||||
println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_interpreted_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
|
||||
|
||||
// JIT disabled until address translation support is added
|
||||
// println!("JIT to native:");
|
||||
// vm.jit_compile().unwrap();
|
||||
// unsafe {
|
||||
// assert_eq!(
|
||||
// 0, /*success*/
|
||||
// vm.execute_program_jit(&mut inner_iter).unwrap()
|
||||
// );
|
||||
// }
|
||||
// assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
||||
// assert_eq!(
|
||||
// ARMSTRONG_EXPECTED,
|
||||
// LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
|
||||
// );
|
||||
println!("JIT to native:");
|
||||
vm.jit_compile().unwrap();
|
||||
unsafe {
|
||||
assert_eq!(
|
||||
SUCCESS,
|
||||
vm.execute_program_jit(&mut instruction_meter).unwrap()
|
||||
);
|
||||
}
|
||||
assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
|
||||
assert_eq!(
|
||||
ARMSTRONG_EXPECTED,
|
||||
LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
|
||||
);
|
||||
|
||||
// bencher.iter(|| unsafe {
|
||||
// vm.execute_program_jit(&mut inner_iter).unwrap();
|
||||
// });
|
||||
// let summary = bencher.bench(|_bencher| {}).unwrap();
|
||||
// println!(" {:?} instructions", instructions);
|
||||
// println!(" {:?} ns/iter median", summary.median as u64);
|
||||
// assert!(0f64 != summary.median);
|
||||
// let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
|
||||
// println!(" {:?} MIPS", mips);
|
||||
// println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_jit_to_native_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
|
||||
bencher.iter(|| unsafe {
|
||||
vm.execute_program_jit(&mut instruction_meter).unwrap();
|
||||
});
|
||||
let summary = bencher.bench(|_bencher| {}).unwrap();
|
||||
println!(" {:?} instructions", instructions);
|
||||
println!(" {:?} ns/iter median", summary.median as u64);
|
||||
assert!(0f64 != summary.median);
|
||||
let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
|
||||
println!(" {:?} MIPS", mips);
|
||||
println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_jit_to_native_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
@ -192,22 +194,6 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||
let loader_id = bpf_loader::id();
|
||||
let mut invoke_context = MockInvokeContext::default();
|
||||
invoke_context.compute_meter.remaining = BUDGET;
|
||||
let compute_meter = invoke_context.get_compute_meter();
|
||||
|
||||
let elf = load_elf("tuner").unwrap();
|
||||
let executable =
|
||||
EbpfVm::<solana_bpf_loader_program::BPFError>::create_executable_from_elf(&elf, None)
|
||||
.unwrap();
|
||||
let (mut vm, _) = solana_bpf_loader_program::create_vm(
|
||||
&loader_id,
|
||||
executable.as_ref(),
|
||||
&[],
|
||||
&mut invoke_context,
|
||||
)
|
||||
.unwrap();
|
||||
let instruction_meter = MockInstructionMeter { compute_meter };
|
||||
|
||||
let mut measure = Measure::start("tune");
|
||||
|
||||
let accounts = [RefCell::new(Account::new(
|
||||
1,
|
||||
@ -223,7 +209,7 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||
let instruction_data = vec![0u8];
|
||||
|
||||
// Serialize account data
|
||||
let mut serialized = solana_bpf_loader_program::serialization::serialize_parameters(
|
||||
let serialized = solana_bpf_loader_program::serialization::serialize_parameters(
|
||||
&bpf_loader::id(),
|
||||
&solana_sdk::pubkey::new_rand(),
|
||||
&keyed_accounts,
|
||||
@ -231,8 +217,24 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let _ = vm.execute_program_metered(&mut serialized, &[], &[], instruction_meter.clone());
|
||||
let elf = load_elf("tuner").unwrap();
|
||||
let executable =
|
||||
Executable::<solana_bpf_loader_program::BPFError>::from_elf(&elf, None).unwrap();
|
||||
let compute_meter = invoke_context.get_compute_meter();
|
||||
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
||||
let mut vm = solana_bpf_loader_program::create_vm(
|
||||
&loader_id,
|
||||
executable.as_ref(),
|
||||
&serialized,
|
||||
&[],
|
||||
&mut invoke_context,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut measure = Measure::start("tune");
|
||||
let _ = vm.execute_program_interpreted(&mut instruction_meter);
|
||||
measure.stop();
|
||||
|
||||
assert_eq!(
|
||||
0,
|
||||
instruction_meter.get_remaining(),
|
||||
@ -245,19 +247,3 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||
vm.get_total_instruction_count(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Passed to the VM to enforce the compute budget
|
||||
#[derive(Clone)]
|
||||
struct MockInstructionMeter {
|
||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||
}
|
||||
impl InstructionMeter for MockInstructionMeter {
|
||||
fn consume(&mut self, amount: u64) {
|
||||
// 1 to 1 instruction to compute unit mapping
|
||||
// ignore error, Ebpf will bail if exceeded
|
||||
let _ = self.compute_meter.borrow_mut().consume(amount);
|
||||
}
|
||||
fn get_remaining(&self) -> u64 {
|
||||
self.compute_meter.borrow().get_remaining()
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,16 @@ extern crate solana_bpf_loader_program;
|
||||
use solana_bpf_loader_program::{
|
||||
create_vm,
|
||||
serialization::{deserialize_parameters, serialize_parameters},
|
||||
ThisInstructionMeter,
|
||||
};
|
||||
use solana_rbpf::vm::EbpfVm;
|
||||
use solana_rbpf::vm::Executable;
|
||||
use solana_runtime::{
|
||||
bank::Bank,
|
||||
bank_client::BankClient,
|
||||
bpf_test_utils::MockInvokeContext,
|
||||
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
||||
loader_utils::load_program,
|
||||
process_instruction::ComputeBudget,
|
||||
process_instruction::{ComputeBudget, InvokeContext},
|
||||
};
|
||||
use solana_sdk::{
|
||||
account::Account,
|
||||
@ -75,25 +76,29 @@ fn run_program(
|
||||
file.read_to_end(&mut data).unwrap();
|
||||
let loader_id = bpf_loader::id();
|
||||
let mut invoke_context = MockInvokeContext::default();
|
||||
|
||||
let executable = EbpfVm::create_executable_from_elf(&data, None).unwrap();
|
||||
let (mut vm, heap_region) = create_vm(
|
||||
&loader_id,
|
||||
executable.as_ref(),
|
||||
parameter_accounts,
|
||||
&mut invoke_context,
|
||||
)
|
||||
.unwrap();
|
||||
let mut parameter_bytes = serialize_parameters(
|
||||
let parameter_bytes = serialize_parameters(
|
||||
&bpf_loader::id(),
|
||||
program_id,
|
||||
parameter_accounts,
|
||||
&instruction_data,
|
||||
)
|
||||
.unwrap();
|
||||
let compute_meter = invoke_context.get_compute_meter();
|
||||
let mut instruction_meter = ThisInstructionMeter { compute_meter };
|
||||
|
||||
let executable = Executable::from_elf(&data, None).unwrap();
|
||||
let mut vm = create_vm(
|
||||
&loader_id,
|
||||
executable.as_ref(),
|
||||
¶meter_bytes,
|
||||
parameter_accounts,
|
||||
&mut invoke_context,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
SUCCESS,
|
||||
vm.execute_program(parameter_bytes.as_mut_slice(), &[], &[heap_region.clone()])
|
||||
vm.execute_program_interpreted(&mut instruction_meter)
|
||||
.unwrap()
|
||||
);
|
||||
deserialize_parameters(&bpf_loader::id(), parameter_accounts, ¶meter_bytes).unwrap();
|
||||
@ -812,7 +817,6 @@ fn test_program_bpf_instruction_introspection() {
|
||||
Some(&mint_keypair.pubkey()),
|
||||
);
|
||||
let result = bank_client.send_and_confirm_message(&[&mint_keypair], message);
|
||||
println!("result: {:?}", result);
|
||||
assert!(result.is_ok());
|
||||
|
||||
// writable special instructions11111 key, should not be allowed
|
||||
|
Reference in New Issue
Block a user