Merge pull request #3604 from rtfeldman/use-instant-over-system-time

Use Instant over SystemTime to record timings
This commit is contained in:
Richard Feldman 2022-07-23 08:29:43 -04:00 committed by GitHub
commit 8096bb4021
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 114 additions and 118 deletions

View file

@ -10,7 +10,7 @@ use roc_module::symbol::{Interns, ModuleId};
use roc_mono::ir::OptLevel; use roc_mono::ir::OptLevel;
use roc_reporting::report::RenderTarget; use roc_reporting::report::RenderTarget;
use roc_target::TargetInfo; use roc_target::TargetInfo;
use std::time::{Duration, SystemTime}; use std::time::{Duration, Instant};
use std::{path::PathBuf, thread::JoinHandle}; use std::{path::PathBuf, thread::JoinHandle};
use target_lexicon::Triple; use target_lexicon::Triple;
use tempfile::Builder; use tempfile::Builder;
@ -49,7 +49,7 @@ pub fn build_file<'a>(
target_valgrind: bool, target_valgrind: bool,
threading: Threading, threading: Threading,
) -> Result<BuiltFile, LoadingProblem<'a>> { ) -> Result<BuiltFile, LoadingProblem<'a>> {
let compilation_start = SystemTime::now(); let compilation_start = Instant::now();
let target_info = TargetInfo::from(target); let target_info = TargetInfo::from(target);
// Step 1: compile the app and generate the .o file // Step 1: compile the app and generate the .o file
@ -255,7 +255,7 @@ pub fn build_file<'a>(
); );
report_timing(buf, "Emit .o file", code_gen_timing.emit_o_file); report_timing(buf, "Emit .o file", code_gen_timing.emit_o_file);
let compilation_end = compilation_start.elapsed().unwrap(); let compilation_end = compilation_start.elapsed();
let size = std::fs::metadata(&app_o_file) let size = std::fs::metadata(&app_o_file)
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
@ -290,7 +290,7 @@ pub fn build_file<'a>(
} }
// Step 2: link the precompiled host and compiled app // Step 2: link the precompiled host and compiled app
let link_start = SystemTime::now(); let link_start = Instant::now();
let problems = match (linking_strategy, link_type) { let problems = match (linking_strategy, link_type) {
(LinkingStrategy::Surgical, _) => { (LinkingStrategy::Surgical, _) => {
roc_linker::link_preprocessed_host(target, &host_input_path, app_o_file, &binary_path); roc_linker::link_preprocessed_host(target, &host_input_path, app_o_file, &binary_path);
@ -339,13 +339,13 @@ pub fn build_file<'a>(
} }
}; };
let linking_time = link_start.elapsed().unwrap(); let linking_time = link_start.elapsed();
if emit_timings { if emit_timings {
println!("Finished linking in {} ms\n", linking_time.as_millis()); println!("Finished linking in {} ms\n", linking_time.as_millis());
} }
let total_time = compilation_start.elapsed().unwrap(); let total_time = compilation_start.elapsed();
Ok(BuiltFile { Ok(BuiltFile {
binary_path, binary_path,
@ -375,7 +375,7 @@ fn spawn_rebuild_thread(
println!("🔨 Rebuilding host..."); println!("🔨 Rebuilding host...");
} }
let rebuild_host_start = SystemTime::now(); let rebuild_host_start = Instant::now();
if !precompiled { if !precompiled {
match linking_strategy { match linking_strategy {
@ -416,7 +416,7 @@ fn spawn_rebuild_thread(
// Copy preprocessed host to executable location. // Copy preprocessed host to executable location.
std::fs::copy(preprocessed_host_path, binary_path.as_path()).unwrap(); std::fs::copy(preprocessed_host_path, binary_path.as_path()).unwrap();
} }
let rebuild_host_end = rebuild_host_start.elapsed().unwrap(); let rebuild_host_end = rebuild_host_start.elapsed();
rebuild_host_end.as_millis() rebuild_host_end.as_millis()
}) })
@ -429,7 +429,7 @@ pub fn check_file(
emit_timings: bool, emit_timings: bool,
threading: Threading, threading: Threading,
) -> Result<(program::Problems, Duration), LoadingProblem> { ) -> Result<(program::Problems, Duration), LoadingProblem> {
let compilation_start = SystemTime::now(); let compilation_start = Instant::now();
// only used for generating errors. We don't do code generation, so hardcoding should be fine // only used for generating errors. We don't do code generation, so hardcoding should be fine
// we need monomorphization for when exhaustiveness checking // we need monomorphization for when exhaustiveness checking
@ -480,7 +480,7 @@ pub fn check_file(
} }
} }
let compilation_end = compilation_start.elapsed().unwrap(); let compilation_end = compilation_start.elapsed();
if emit_timings { if emit_timings {
println!( println!(

View file

@ -5,7 +5,7 @@ use roc_module::symbol::{Interns, ModuleId};
use roc_mono::ir::OptLevel; use roc_mono::ir::OptLevel;
use roc_region::all::LineInfo; use roc_region::all::LineInfo;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::time::{Duration, SystemTime}; use std::time::{Duration, Instant};
use roc_collections::all::MutMap; use roc_collections::all::MutMap;
#[cfg(feature = "target-wasm32")] #[cfg(feature = "target-wasm32")]
@ -199,7 +199,7 @@ pub fn gen_from_mono_module_llvm(
use inkwell::module::Linkage; use inkwell::module::Linkage;
use inkwell::targets::{FileType, RelocMode}; use inkwell::targets::{FileType, RelocMode};
let code_gen_start = SystemTime::now(); let code_gen_start = Instant::now();
// Generate the binary // Generate the binary
let target_info = roc_target::TargetInfo::from(target); let target_info = roc_target::TargetInfo::from(target);
@ -292,8 +292,8 @@ pub fn gen_from_mono_module_llvm(
// Uncomment this to see the module's optimized LLVM instruction output: // Uncomment this to see the module's optimized LLVM instruction output:
// env.module.print_to_stderr(); // env.module.print_to_stderr();
let code_gen = code_gen_start.elapsed().unwrap(); let code_gen = code_gen_start.elapsed();
let emit_o_file_start = SystemTime::now(); let emit_o_file_start = Instant::now();
// annotate the LLVM IR output with debug info // annotate the LLVM IR output with debug info
// so errors are reported with the line number of the LLVM source // so errors are reported with the line number of the LLVM source
@ -389,7 +389,7 @@ pub fn gen_from_mono_module_llvm(
} }
} }
let emit_o_file = emit_o_file_start.elapsed().unwrap(); let emit_o_file = emit_o_file_start.elapsed();
CodeGenTiming { CodeGenTiming {
code_gen, code_gen,
@ -442,7 +442,7 @@ fn gen_from_mono_module_dev_wasm32(
app_o_file: &Path, app_o_file: &Path,
preprocessed_host_path: &Path, preprocessed_host_path: &Path,
) -> CodeGenTiming { ) -> CodeGenTiming {
let code_gen_start = SystemTime::now(); let code_gen_start = Instant::now();
let MonomorphizedModule { let MonomorphizedModule {
module_id, module_id,
procedures, procedures,
@ -482,8 +482,8 @@ fn gen_from_mono_module_dev_wasm32(
let final_binary_bytes = let final_binary_bytes =
roc_gen_wasm::build_app_binary(&env, &mut interns, host_module, procedures); roc_gen_wasm::build_app_binary(&env, &mut interns, host_module, procedures);
let code_gen = code_gen_start.elapsed().unwrap(); let code_gen = code_gen_start.elapsed();
let emit_o_file_start = SystemTime::now(); let emit_o_file_start = Instant::now();
// The app_o_file is actually the final binary // The app_o_file is actually the final binary
std::fs::write(&app_o_file, &final_binary_bytes).unwrap_or_else(|e| { std::fs::write(&app_o_file, &final_binary_bytes).unwrap_or_else(|e| {
@ -494,7 +494,7 @@ fn gen_from_mono_module_dev_wasm32(
) )
}); });
let emit_o_file = emit_o_file_start.elapsed().unwrap(); let emit_o_file = emit_o_file_start.elapsed();
CodeGenTiming { CodeGenTiming {
code_gen, code_gen,
@ -508,7 +508,7 @@ fn gen_from_mono_module_dev_assembly(
target: &target_lexicon::Triple, target: &target_lexicon::Triple,
app_o_file: &Path, app_o_file: &Path,
) -> CodeGenTiming { ) -> CodeGenTiming {
let code_gen_start = SystemTime::now(); let code_gen_start = Instant::now();
let lazy_literals = true; let lazy_literals = true;
let generate_allocators = false; // provided by the platform let generate_allocators = false; // provided by the platform
@ -531,15 +531,15 @@ fn gen_from_mono_module_dev_assembly(
let module_object = roc_gen_dev::build_module(&env, &mut interns, target, procedures); let module_object = roc_gen_dev::build_module(&env, &mut interns, target, procedures);
let code_gen = code_gen_start.elapsed().unwrap(); let code_gen = code_gen_start.elapsed();
let emit_o_file_start = SystemTime::now(); let emit_o_file_start = Instant::now();
let module_out = module_object let module_out = module_object
.write() .write()
.expect("failed to build output object"); .expect("failed to build output object");
std::fs::write(&app_o_file, module_out).expect("failed to write object to file"); std::fs::write(&app_o_file, module_out).expect("failed to write object to file");
let emit_o_file = emit_o_file_start.elapsed().unwrap(); let emit_o_file = emit_o_file_start.elapsed();
CodeGenTiming { CodeGenTiming {
code_gen, code_gen,

View file

@ -61,9 +61,9 @@ use crate::work::Dependencies;
pub use crate::work::Phase; pub use crate::work::Phase;
#[cfg(target_family = "wasm")] #[cfg(target_family = "wasm")]
use crate::wasm_system_time::{Duration, SystemTime}; use crate::wasm_instant::{Duration, Instant};
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
use std::time::{Duration, SystemTime}; use std::time::{Duration, Instant};
/// Default name for the binary generated for an app, if an invalid one was specified. /// Default name for the binary generated for an app, if an invalid one was specified.
const DEFAULT_APP_OUTPUT_PATH: &str = "app"; const DEFAULT_APP_OUTPUT_PATH: &str = "app";
@ -462,7 +462,7 @@ fn start_phase<'a>(
Subs::default(), Subs::default(),
ProcsBase::default(), ProcsBase::default(),
LayoutCache::new(state.target_info), LayoutCache::new(state.target_info),
ModuleTiming::new(SystemTime::now()), ModuleTiming::new(Instant::now()),
) )
} else if state.make_specializations_pass.current_pass() == 1 { } else if state.make_specializations_pass.current_pass() == 1 {
let found_specializations = state let found_specializations = state
@ -958,12 +958,12 @@ pub struct ModuleTiming {
// TODO pub monomorphize: Duration, // TODO pub monomorphize: Duration,
/// Total duration will always be more than the sum of the other fields, due /// Total duration will always be more than the sum of the other fields, due
/// to things like state lookups in between phases, waiting on other threads, etc. /// to things like state lookups in between phases, waiting on other threads, etc.
start_time: SystemTime, start_time: Instant,
end_time: SystemTime, end_time: Instant,
} }
impl ModuleTiming { impl ModuleTiming {
pub fn new(start_time: SystemTime) -> Self { pub fn new(start_time: Instant) -> Self {
ModuleTiming { ModuleTiming {
read_roc_file: Duration::default(), read_roc_file: Duration::default(),
parse_header: Duration::default(), parse_header: Duration::default(),
@ -979,7 +979,7 @@ impl ModuleTiming {
} }
pub fn total(&self) -> Duration { pub fn total(&self) -> Duration {
self.end_time.duration_since(self.start_time).unwrap() self.end_time.duration_since(self.start_time)
} }
/// Subtract all the other fields from total_start_to_finish /// Subtract all the other fields from total_start_to_finish
@ -997,10 +997,10 @@ impl ModuleTiming {
end_time, end_time,
} = self; } = self;
let calculate = |t: Result<Duration, _>| -> Option<Duration> { let calculate = |d: Option<Duration>| -> Option<Duration> {
make_specializations make_specializations
.iter() .iter()
.fold(t.ok(), |t, pass_time| t?.checked_sub(*pass_time))? .fold(d, |d, pass_time| d?.checked_sub(*pass_time))?
.checked_sub(*find_specializations)? .checked_sub(*find_specializations)?
.checked_sub(*solve)? .checked_sub(*solve)?
.checked_sub(*constrain)? .checked_sub(*constrain)?
@ -1010,7 +1010,7 @@ impl ModuleTiming {
.checked_sub(*read_roc_file) .checked_sub(*read_roc_file)
}; };
calculate(end_time.duration_since(*start_time)).unwrap_or_default() calculate(Some(end_time.duration_since(*start_time))).unwrap_or_default()
} }
} }
@ -1186,7 +1186,7 @@ impl<'a> LoadStart<'a> {
// Load the root module synchronously; we can't proceed until we have its id. // Load the root module synchronously; we can't proceed until we have its id.
let (root_id, root_msg) = { let (root_id, root_msg) = {
let root_start_time = SystemTime::now(); let root_start_time = Instant::now();
let res_loaded = load_filename( let res_loaded = load_filename(
arena, arena,
@ -1273,7 +1273,7 @@ impl<'a> LoadStart<'a> {
// Load the root module synchronously; we can't proceed until we have its id. // Load the root module synchronously; we can't proceed until we have its id.
let (root_id, root_msg) = { let (root_id, root_msg) = {
let root_start_time = SystemTime::now(); let root_start_time = Instant::now();
load_from_str( load_from_str(
arena, arena,
@ -2291,7 +2291,7 @@ fn update<'a>(
loc_expects, loc_expects,
} => { } => {
log!("solved types for {:?}", module_id); log!("solved types for {:?}", module_id);
module_timing.end_time = SystemTime::now(); module_timing.end_time = Instant::now();
state state
.module_cache .module_cache
@ -2907,18 +2907,18 @@ fn load_platform_module<'a>(
module_ids: Arc<Mutex<PackageModuleIds<'a>>>, module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: SharedIdentIdsByModule, ident_ids_by_module: SharedIdentIdsByModule,
) -> Result<Msg<'a>, LoadingProblem<'a>> { ) -> Result<Msg<'a>, LoadingProblem<'a>> {
let module_start_time = SystemTime::now(); let module_start_time = Instant::now();
let file_io_start = SystemTime::now(); let file_io_start = Instant::now();
let file = fs::read(&filename); let file = fs::read(&filename);
let file_io_duration = file_io_start.elapsed().unwrap(); let file_io_duration = file_io_start.elapsed();
match file { match file {
Ok(bytes_vec) => { Ok(bytes_vec) => {
let parse_start = SystemTime::now(); let parse_start = Instant::now();
let bytes = arena.alloc(bytes_vec); let bytes = arena.alloc(bytes_vec);
let parse_state = roc_parse::state::State::new(bytes); let parse_state = roc_parse::state::State::new(bytes);
let parsed = roc_parse::module::parse_header(arena, parse_state.clone()); let parsed = roc_parse::module::parse_header(arena, parse_state.clone());
let parse_header_duration = parse_start.elapsed().unwrap(); let parse_header_duration = parse_start.elapsed();
// Insert the first entries for this module's timings // Insert the first entries for this module's timings
let mut pkg_module_timing = ModuleTiming::new(module_start_time); let mut pkg_module_timing = ModuleTiming::new(module_start_time);
@ -3047,10 +3047,10 @@ fn load_module<'a>(
arc_shorthands: Arc<Mutex<MutMap<&'a str, PackageName<'a>>>>, arc_shorthands: Arc<Mutex<MutMap<&'a str, PackageName<'a>>>>,
ident_ids_by_module: SharedIdentIdsByModule, ident_ids_by_module: SharedIdentIdsByModule,
) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> { ) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> {
let module_start_time = SystemTime::now(); let module_start_time = Instant::now();
let parse_start = SystemTime::now(); let parse_start = Instant::now();
let parse_header_duration = parse_start.elapsed().unwrap(); let parse_header_duration = parse_start.elapsed();
// Insert the first entries for this module's timings // Insert the first entries for this module's timings
let mut module_timing = ModuleTiming::new(module_start_time); let mut module_timing = ModuleTiming::new(module_start_time);
@ -3188,12 +3188,12 @@ fn parse_header<'a>(
module_ids: Arc<Mutex<PackageModuleIds<'a>>>, module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: SharedIdentIdsByModule, ident_ids_by_module: SharedIdentIdsByModule,
src_bytes: &'a [u8], src_bytes: &'a [u8],
start_time: SystemTime, start_time: Instant,
) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> { ) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> {
let parse_start = SystemTime::now(); let parse_start = Instant::now();
let parse_state = roc_parse::state::State::new(src_bytes); let parse_state = roc_parse::state::State::new(src_bytes);
let parsed = roc_parse::module::parse_header(arena, parse_state.clone()); let parsed = roc_parse::module::parse_header(arena, parse_state.clone());
let parse_header_duration = parse_start.elapsed().unwrap(); let parse_header_duration = parse_start.elapsed();
// Insert the first entries for this module's timings // Insert the first entries for this module's timings
let mut module_timing = ModuleTiming::new(start_time); let mut module_timing = ModuleTiming::new(start_time);
@ -3375,11 +3375,11 @@ fn load_filename<'a>(
opt_shorthand: Option<&'a str>, opt_shorthand: Option<&'a str>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>, module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: SharedIdentIdsByModule, ident_ids_by_module: SharedIdentIdsByModule,
module_start_time: SystemTime, module_start_time: Instant,
) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> { ) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> {
let file_io_start = SystemTime::now(); let file_io_start = Instant::now();
let file = fs::read(&filename); let file = fs::read(&filename);
let file_io_duration = file_io_start.elapsed().unwrap(); let file_io_duration = file_io_start.elapsed();
match file { match file {
Ok(bytes) => parse_header( Ok(bytes) => parse_header(
@ -3409,10 +3409,10 @@ fn load_from_str<'a>(
src: &'a str, src: &'a str,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>, module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: SharedIdentIdsByModule, ident_ids_by_module: SharedIdentIdsByModule,
module_start_time: SystemTime, module_start_time: Instant,
) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> { ) -> Result<(ModuleId, Msg<'a>), LoadingProblem<'a>> {
let file_io_start = SystemTime::now(); let file_io_start = Instant::now();
let file_io_duration = file_io_start.elapsed().unwrap(); let file_io_duration = file_io_start.elapsed();
parse_header( parse_header(
arena, arena,
@ -4218,7 +4218,7 @@ fn run_solve<'a>(
cached_subs: CachedSubs, cached_subs: CachedSubs,
derived_module: SharedDerivedModule, derived_module: SharedDerivedModule,
) -> Msg<'a> { ) -> Msg<'a> {
let solve_start = SystemTime::now(); let solve_start = Instant::now();
let module_id = module.module_id; let module_id = module.module_id;
@ -4284,8 +4284,8 @@ fn run_solve<'a>(
}; };
// Record the final timings // Record the final timings
let solve_end = SystemTime::now(); let solve_end = Instant::now();
module_timing.solve = solve_end.duration_since(solve_start).unwrap(); module_timing.solve = solve_end.duration_since(solve_start);
// Send the subs to the main thread for processing, // Send the subs to the main thread for processing,
Msg::SolvedTypes { Msg::SolvedTypes {
@ -4363,7 +4363,7 @@ fn canonicalize_and_constrain<'a>(
parsed: ParsedModule<'a>, parsed: ParsedModule<'a>,
skip_constraint_gen: bool, skip_constraint_gen: bool,
) -> CanAndCon { ) -> CanAndCon {
let canonicalize_start = SystemTime::now(); let canonicalize_start = Instant::now();
let ParsedModule { let ParsedModule {
module_id, module_id,
@ -4412,9 +4412,9 @@ fn canonicalize_and_constrain<'a>(
_after _after
); );
let canonicalize_end = SystemTime::now(); let canonicalize_end = Instant::now();
module_timing.canonicalize = canonicalize_end.duration_since(canonicalize_start).unwrap(); module_timing.canonicalize = canonicalize_end.duration_since(canonicalize_start);
// Generate documentation information // Generate documentation information
// TODO: store timing information? // TODO: store timing information?
@ -4522,7 +4522,7 @@ fn canonicalize_and_constrain<'a>(
fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, LoadingProblem<'a>> { fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, LoadingProblem<'a>> {
let mut module_timing = header.module_timing; let mut module_timing = header.module_timing;
let parse_start = SystemTime::now(); let parse_start = Instant::now();
let source = header.parse_state.original_bytes(); let source = header.parse_state.original_bytes();
let parse_state = header.parse_state; let parse_state = header.parse_state;
let parsed_defs = match module_defs().parse(arena, parse_state) { let parsed_defs = match module_defs().parse(arena, parse_state) {
@ -4536,9 +4536,9 @@ fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, Loadi
// Record the parse end time once, to avoid checking the time a second time // Record the parse end time once, to avoid checking the time a second time
// immediately afterward (for the beginning of canonicalization). // immediately afterward (for the beginning of canonicalization).
let parse_end = SystemTime::now(); let parse_end = Instant::now();
module_timing.parse_body = parse_end.duration_since(parse_start).unwrap(); module_timing.parse_body = parse_end.duration_since(parse_start);
let imported_modules = header.imported_modules; let imported_modules = header.imported_modules;
@ -4632,7 +4632,7 @@ fn make_specializations<'a>(
exposed_by_module: &ExposedByModule, exposed_by_module: &ExposedByModule,
derived_module: SharedDerivedModule, derived_module: SharedDerivedModule,
) -> Msg<'a> { ) -> Msg<'a> {
let make_specializations_start = SystemTime::now(); let make_specializations_start = Instant::now();
let mut update_mode_ids = UpdateModeIds::new(); let mut update_mode_ids = UpdateModeIds::new();
// do the thing // do the thing
let mut mono_env = roc_mono::ir::Env { let mut mono_env = roc_mono::ir::Env {
@ -4676,12 +4676,10 @@ fn make_specializations<'a>(
// Turn `Bytes.Decode.IdentId(238)` into `Bytes.Decode.238`, we rely on this in mono tests // Turn `Bytes.Decode.IdentId(238)` into `Bytes.Decode.238`, we rely on this in mono tests
mono_env.home.register_debug_idents(mono_env.ident_ids); mono_env.home.register_debug_idents(mono_env.ident_ids);
let make_specializations_end = SystemTime::now(); let make_specializations_end = Instant::now();
module_timing.make_specializations.push( module_timing
make_specializations_end .make_specializations
.duration_since(make_specializations_start) .push(make_specializations_end.duration_since(make_specializations_start));
.unwrap(),
);
Msg::MadeSpecializations { Msg::MadeSpecializations {
module_id: home, module_id: home,
@ -4712,7 +4710,7 @@ fn build_pending_specializations<'a>(
abilities_store: AbilitiesStore, abilities_store: AbilitiesStore,
derived_module: SharedDerivedModule, derived_module: SharedDerivedModule,
) -> Msg<'a> { ) -> Msg<'a> {
let find_specializations_start = SystemTime::now(); let find_specializations_start = Instant::now();
let mut module_thunks = bumpalo::collections::Vec::new_in(arena); let mut module_thunks = bumpalo::collections::Vec::new_in(arena);
let mut toplevel_expects = VecMap::default(); let mut toplevel_expects = VecMap::default();
@ -5028,10 +5026,9 @@ fn build_pending_specializations<'a>(
procs_base.module_thunks = module_thunks.into_bump_slice(); procs_base.module_thunks = module_thunks.into_bump_slice();
let find_specializations_end = SystemTime::now(); let find_specializations_end = Instant::now();
module_timing.find_specializations = find_specializations_end module_timing.find_specializations =
.duration_since(find_specializations_start) find_specializations_end.duration_since(find_specializations_start);
.unwrap();
Msg::FoundSpecializations { Msg::FoundSpecializations {
module_id: home, module_id: home,
@ -5064,7 +5061,7 @@ fn load_derived_partial_procs<'a>(
) { ) {
debug_assert_eq!(home, ModuleId::DERIVED_GEN); debug_assert_eq!(home, ModuleId::DERIVED_GEN);
let load_derived_procs_start = SystemTime::now(); let load_derived_procs_start = Instant::now();
let mut new_module_thunks = bumpalo::collections::Vec::new_in(arena); let mut new_module_thunks = bumpalo::collections::Vec::new_in(arena);
@ -5132,11 +5129,10 @@ fn load_derived_partial_procs<'a>(
procs_base.module_thunks = new_module_thunks.into_bump_slice(); procs_base.module_thunks = new_module_thunks.into_bump_slice();
} }
let load_derived_procs_end = SystemTime::now(); let load_derived_procs_end = Instant::now();
module_timing.find_specializations = load_derived_procs_end module_timing.find_specializations =
.duration_since(load_derived_procs_start) load_derived_procs_end.duration_since(load_derived_procs_start);
.unwrap();
} }
fn run_task<'a>( fn run_task<'a>(

View file

@ -6,4 +6,4 @@ pub mod file;
mod work; mod work;
#[cfg(target_family = "wasm")] #[cfg(target_family = "wasm")]
mod wasm_system_time; mod wasm_instant;

View file

@ -1,24 +1,24 @@
#![cfg(target_family = "wasm")] #![cfg(target_family = "wasm")]
/* /*
For the Web REPL (repl_www), we build the compiler as a Wasm module. For the Web REPL (repl_www), we build the compiler as a Wasm module.
SystemTime is the only thing in the compiler that would need a special implementation for this. Instant is the only thing in the compiler that would need a special implementation for this.
There is a WASI implementation for it, but we are targeting the browser, not WASI! There is a WASI implementation for it, but we are targeting the browser, not WASI!
It's possible to write browser versions of WASI's low-level ABI but we'd rather avoid it. It's possible to write browser versions of WASI's low-level ABI but we'd rather avoid it.
Instead we use these dummy implementations, which should just disappear at compile time. Instead we use these dummy implementations, which should just disappear at compile time.
*/ */
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct SystemTime; pub struct Instant;
impl SystemTime { impl Instant {
pub fn now() -> Self { pub fn now() -> Self {
SystemTime Instant
} }
pub fn duration_since(&self, _: SystemTime) -> Result<Duration, String> { pub fn duration_since(&self, _: Instant) -> Duration {
Ok(Duration) Duration
} }
pub fn elapsed(&self) -> Result<Duration, String> { pub fn elapsed(&self) -> Duration {
Ok(Duration) Duration
} }
} }

View file

@ -22,7 +22,7 @@ use std::mem;
use std::os::raw::c_char; use std::os::raw::c_char;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::time::{Duration, SystemTime}; use std::time::{Duration, Instant};
use target_lexicon::Triple; use target_lexicon::Triple;
use tempfile::Builder; use tempfile::Builder;
@ -255,7 +255,7 @@ pub fn preprocess(
println!("Targeting: {}", target); println!("Targeting: {}", target);
} }
let total_start = SystemTime::now(); let total_start = Instant::now();
let exec_parsing_start = total_start; let exec_parsing_start = total_start;
let exec_file = fs::File::open(exec_filename).unwrap_or_else(|e| internal_error!("{}", e)); let exec_file = fs::File::open(exec_filename).unwrap_or_else(|e| internal_error!("{}", e));
let exec_mmap = unsafe { Mmap::map(&exec_file).unwrap_or_else(|e| internal_error!("{}", e)) }; let exec_mmap = unsafe { Mmap::map(&exec_file).unwrap_or_else(|e| internal_error!("{}", e)) };
@ -306,10 +306,10 @@ pub fn preprocess(
); );
} }
let exec_parsing_duration = exec_parsing_start.elapsed().unwrap(); let exec_parsing_duration = exec_parsing_start.elapsed();
// Extract PLT related information for app functions. // Extract PLT related information for app functions.
let symbol_and_plt_processing_start = SystemTime::now(); let symbol_and_plt_processing_start = Instant::now();
let plt_section_name = match target.binary_format { let plt_section_name = match target.binary_format {
target_lexicon::BinaryFormat::Elf => ".plt", target_lexicon::BinaryFormat::Elf => ".plt",
target_lexicon::BinaryFormat::Macho => "__stubs", target_lexicon::BinaryFormat::Macho => "__stubs",
@ -550,9 +550,9 @@ pub fn preprocess(
println!(); println!();
println!("App Function Address Map: {:+x?}", app_func_addresses); println!("App Function Address Map: {:+x?}", app_func_addresses);
} }
let symbol_and_plt_processing_duration = symbol_and_plt_processing_start.elapsed().unwrap(); let symbol_and_plt_processing_duration = symbol_and_plt_processing_start.elapsed();
let text_disassembly_start = SystemTime::now(); let text_disassembly_start = Instant::now();
let text_sections: Vec<Section> = exec_obj let text_sections: Vec<Section> = exec_obj
.sections() .sections()
.filter(|sec| sec.kind() == SectionKind::Text) .filter(|sec| sec.kind() == SectionKind::Text)
@ -688,7 +688,7 @@ pub fn preprocess(
} }
} }
} }
let text_disassembly_duration = text_disassembly_start.elapsed().unwrap(); let text_disassembly_duration = text_disassembly_start.elapsed();
let scanning_dynamic_deps_duration; let scanning_dynamic_deps_duration;
let platform_gen_start; let platform_gen_start;
@ -699,7 +699,7 @@ pub fn preprocess(
.unwrap_or(target_lexicon::Endianness::Little) .unwrap_or(target_lexicon::Endianness::Little)
{ {
target_lexicon::Endianness::Little => { target_lexicon::Endianness::Little => {
let scanning_dynamic_deps_start = SystemTime::now(); let scanning_dynamic_deps_start = Instant::now();
let ElfDynamicDeps { let ElfDynamicDeps {
got_app_syms, got_app_syms,
@ -710,9 +710,9 @@ pub fn preprocess(
&exec_obj, &mut md, &app_syms, shared_lib, exec_data, verbose, &exec_obj, &mut md, &app_syms, shared_lib, exec_data, verbose,
); );
scanning_dynamic_deps_duration = scanning_dynamic_deps_start.elapsed().unwrap(); scanning_dynamic_deps_duration = scanning_dynamic_deps_start.elapsed();
platform_gen_start = SystemTime::now(); platform_gen_start = Instant::now();
// TODO little endian // TODO little endian
gen_elf_le( gen_elf_le(
@ -739,7 +739,7 @@ pub fn preprocess(
.unwrap_or(target_lexicon::Endianness::Little) .unwrap_or(target_lexicon::Endianness::Little)
{ {
target_lexicon::Endianness::Little => { target_lexicon::Endianness::Little => {
let scanning_dynamic_deps_start = SystemTime::now(); let scanning_dynamic_deps_start = Instant::now();
// let ElfDynamicDeps { // let ElfDynamicDeps {
// got_app_syms, // got_app_syms,
@ -750,9 +750,9 @@ pub fn preprocess(
// &exec_obj, &mut md, &app_syms, shared_lib, exec_data, verbose, // &exec_obj, &mut md, &app_syms, shared_lib, exec_data, verbose,
// ); // );
scanning_dynamic_deps_duration = scanning_dynamic_deps_start.elapsed().unwrap(); scanning_dynamic_deps_duration = scanning_dynamic_deps_start.elapsed();
platform_gen_start = SystemTime::now(); platform_gen_start = Instant::now();
// TODO little endian // TODO little endian
let macho_load_so_offset = match macho_load_so_offset { let macho_load_so_offset = match macho_load_so_offset {
@ -802,14 +802,14 @@ pub fn preprocess(
} }
}; };
let platform_gen_duration = platform_gen_start.elapsed().unwrap(); let platform_gen_duration = platform_gen_start.elapsed();
if verbose { if verbose {
println!(); println!();
println!("{:+x?}", md); println!("{:+x?}", md);
} }
let saving_metadata_start = SystemTime::now(); let saving_metadata_start = Instant::now();
// This block ensure that the metadata is fully written and timed before continuing. // This block ensure that the metadata is fully written and timed before continuing.
{ {
let output = let output =
@ -819,18 +819,18 @@ pub fn preprocess(
internal_error!("Failed to serialize metadata: {}", err); internal_error!("Failed to serialize metadata: {}", err);
}; };
} }
let saving_metadata_duration = saving_metadata_start.elapsed().unwrap(); let saving_metadata_duration = saving_metadata_start.elapsed();
let flushing_data_start = SystemTime::now(); let flushing_data_start = Instant::now();
out_mmap out_mmap
.flush() .flush()
.unwrap_or_else(|e| internal_error!("{}", e)); .unwrap_or_else(|e| internal_error!("{}", e));
// Also drop files to to ensure data is fully written here. // Also drop files to to ensure data is fully written here.
drop(out_mmap); drop(out_mmap);
drop(out_file); drop(out_file);
let flushing_data_duration = flushing_data_start.elapsed().unwrap(); let flushing_data_duration = flushing_data_start.elapsed();
let total_duration = total_start.elapsed().unwrap(); let total_duration = total_start.elapsed();
if verbose || time { if verbose || time {
println!(); println!();
@ -1929,7 +1929,7 @@ pub fn surgery(
time: bool, time: bool,
target: &Triple, target: &Triple,
) { ) {
let total_start = SystemTime::now(); let total_start = Instant::now();
let loading_metadata_start = total_start; let loading_metadata_start = total_start;
let md: metadata::Metadata = { let md: metadata::Metadata = {
let input = fs::File::open(metadata_filename).unwrap_or_else(|e| internal_error!("{}", e)); let input = fs::File::open(metadata_filename).unwrap_or_else(|e| internal_error!("{}", e));
@ -1941,9 +1941,9 @@ pub fn surgery(
} }
} }
}; };
let loading_metadata_duration = loading_metadata_start.elapsed().unwrap(); let loading_metadata_duration = loading_metadata_start.elapsed();
let app_parsing_start = SystemTime::now(); let app_parsing_start = Instant::now();
let app_file = fs::File::open(app_filename).unwrap_or_else(|e| internal_error!("{}", e)); let app_file = fs::File::open(app_filename).unwrap_or_else(|e| internal_error!("{}", e));
let app_mmap = unsafe { Mmap::map(&app_file).unwrap_or_else(|e| internal_error!("{}", e)) }; let app_mmap = unsafe { Mmap::map(&app_file).unwrap_or_else(|e| internal_error!("{}", e)) };
let app_data = &*app_mmap; let app_data = &*app_mmap;
@ -1953,9 +1953,9 @@ pub fn surgery(
internal_error!("Failed to parse application file: {}", err); internal_error!("Failed to parse application file: {}", err);
} }
}; };
let app_parsing_duration = app_parsing_start.elapsed().unwrap(); let app_parsing_duration = app_parsing_start.elapsed();
let load_and_mmap_start = SystemTime::now(); let load_and_mmap_start = Instant::now();
let exec_file = fs::OpenOptions::new() let exec_file = fs::OpenOptions::new()
.read(true) .read(true)
.write(true) .write(true)
@ -1970,8 +1970,8 @@ pub fn surgery(
let mut exec_mmap = let mut exec_mmap =
unsafe { MmapMut::map_mut(&exec_file).unwrap_or_else(|e| internal_error!("{}", e)) }; unsafe { MmapMut::map_mut(&exec_file).unwrap_or_else(|e| internal_error!("{}", e)) };
let load_and_mmap_duration = load_and_mmap_start.elapsed().unwrap(); let load_and_mmap_duration = load_and_mmap_start.elapsed();
let out_gen_start = SystemTime::now(); let out_gen_start = Instant::now();
let mut offset = 0; let mut offset = 0;
let output = match target.binary_format { let output = match target.binary_format {
@ -1995,8 +1995,8 @@ pub fn surgery(
} }
}; };
let out_gen_duration = out_gen_start.elapsed().unwrap(); let out_gen_duration = out_gen_start.elapsed();
let flushing_data_start = SystemTime::now(); let flushing_data_start = Instant::now();
// TODO investigate using the async version of flush - might be faster due to not having to block on that // TODO investigate using the async version of flush - might be faster due to not having to block on that
exec_mmap exec_mmap
@ -2009,7 +2009,7 @@ pub fn surgery(
.set_len(offset as u64 + 1) .set_len(offset as u64 + 1)
.unwrap_or_else(|e| internal_error!("{}", e)); .unwrap_or_else(|e| internal_error!("{}", e));
drop(exec_file); drop(exec_file);
let flushing_data_duration = flushing_data_start.elapsed().unwrap(); let flushing_data_duration = flushing_data_start.elapsed();
// Make sure the final executable has permision to execute. // Make sure the final executable has permision to execute.
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
@ -2023,7 +2023,7 @@ pub fn surgery(
fs::set_permissions(out_filename, perms).unwrap_or_else(|e| internal_error!("{}", e)); fs::set_permissions(out_filename, perms).unwrap_or_else(|e| internal_error!("{}", e));
} }
let total_duration = total_start.elapsed().unwrap(); let total_duration = total_start.elapsed();
if verbose || time { if verbose || time {
println!("\nTimings"); println!("\nTimings");