2023-01-13 02:51:32 -05:00
|
|
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
|
|
|
|
|
|
use std::path::Path;
|
|
|
|
use std::path::PathBuf;
|
2023-02-13 20:46:32 -05:00
|
|
|
use std::time::Instant;
|
2023-01-13 02:51:32 -05:00
|
|
|
|
2023-03-08 06:44:54 -05:00
|
|
|
use crate::ExtModuleLoaderCb;
|
2022-11-21 08:36:26 -05:00
|
|
|
use crate::Extension;
|
|
|
|
use crate::JsRuntime;
|
|
|
|
use crate::RuntimeOptions;
|
|
|
|
use crate::Snapshot;
|
|
|
|
|
|
|
|
pub type CompressionCb = dyn Fn(&mut Vec<u8>, &[u8]);
|
|
|
|
|
|
|
|
pub struct CreateSnapshotOptions {
|
|
|
|
pub cargo_manifest_dir: &'static str,
|
|
|
|
pub snapshot_path: PathBuf,
|
|
|
|
pub startup_snapshot: Option<Snapshot>,
|
|
|
|
pub extensions: Vec<Extension>,
|
|
|
|
pub compression_cb: Option<Box<CompressionCb>>,
|
2023-03-08 06:44:54 -05:00
|
|
|
pub snapshot_module_load_cb: Option<ExtModuleLoaderCb>,
|
2022-11-21 08:36:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn create_snapshot(create_snapshot_options: CreateSnapshotOptions) {
|
2023-02-13 20:46:32 -05:00
|
|
|
let mut mark = Instant::now();
|
|
|
|
|
2023-02-08 16:40:18 -05:00
|
|
|
let js_runtime = JsRuntime::new(RuntimeOptions {
|
2022-11-21 08:36:26 -05:00
|
|
|
will_snapshot: true,
|
|
|
|
startup_snapshot: create_snapshot_options.startup_snapshot,
|
|
|
|
extensions: create_snapshot_options.extensions,
|
2023-02-08 16:40:18 -05:00
|
|
|
snapshot_module_load_cb: create_snapshot_options.snapshot_module_load_cb,
|
2022-11-21 08:36:26 -05:00
|
|
|
..Default::default()
|
|
|
|
});
|
2023-02-20 15:45:34 -05:00
|
|
|
println!(
|
|
|
|
"JsRuntime for snapshot prepared, took {:#?} ({})",
|
|
|
|
Instant::now().saturating_duration_since(mark),
|
|
|
|
create_snapshot_options.snapshot_path.display()
|
|
|
|
);
|
|
|
|
mark = Instant::now();
|
2022-11-21 08:36:26 -05:00
|
|
|
|
|
|
|
let snapshot = js_runtime.snapshot();
|
|
|
|
let snapshot_slice: &[u8] = &snapshot;
|
2023-02-13 18:43:53 -05:00
|
|
|
println!(
|
2023-02-13 20:46:32 -05:00
|
|
|
"Snapshot size: {}, took {:#?} ({})",
|
2023-02-13 18:43:53 -05:00
|
|
|
snapshot_slice.len(),
|
2023-02-13 20:46:32 -05:00
|
|
|
Instant::now().saturating_duration_since(mark),
|
2023-02-13 18:43:53 -05:00
|
|
|
create_snapshot_options.snapshot_path.display()
|
|
|
|
);
|
2023-02-13 20:46:32 -05:00
|
|
|
mark = Instant::now();
|
2022-11-21 08:36:26 -05:00
|
|
|
|
|
|
|
let maybe_compressed_snapshot: Box<dyn AsRef<[u8]>> =
|
|
|
|
if let Some(compression_cb) = create_snapshot_options.compression_cb {
|
|
|
|
let mut vec = vec![];
|
|
|
|
|
|
|
|
vec.extend_from_slice(
|
|
|
|
&u32::try_from(snapshot.len())
|
|
|
|
.expect("snapshot larger than 4gb")
|
|
|
|
.to_le_bytes(),
|
|
|
|
);
|
|
|
|
|
|
|
|
(compression_cb)(&mut vec, snapshot_slice);
|
|
|
|
|
2023-02-13 18:43:53 -05:00
|
|
|
println!(
|
2023-02-13 20:46:32 -05:00
|
|
|
"Snapshot compressed size: {}, took {:#?} ({})",
|
2023-02-13 18:43:53 -05:00
|
|
|
vec.len(),
|
2023-02-13 20:46:32 -05:00
|
|
|
Instant::now().saturating_duration_since(mark),
|
2023-02-13 18:43:53 -05:00
|
|
|
create_snapshot_options.snapshot_path.display()
|
|
|
|
);
|
2023-02-13 20:46:32 -05:00
|
|
|
mark = std::time::Instant::now();
|
2022-11-21 08:36:26 -05:00
|
|
|
|
|
|
|
Box::new(vec)
|
|
|
|
} else {
|
|
|
|
Box::new(snapshot_slice)
|
|
|
|
};
|
|
|
|
|
|
|
|
std::fs::write(
|
|
|
|
&create_snapshot_options.snapshot_path,
|
|
|
|
&*maybe_compressed_snapshot,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
println!(
|
2023-02-13 20:46:32 -05:00
|
|
|
"Snapshot written, took: {:#?} ({})",
|
|
|
|
Instant::now().saturating_duration_since(mark),
|
2023-02-13 18:43:53 -05:00
|
|
|
create_snapshot_options.snapshot_path.display(),
|
2022-11-21 08:36:26 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-02-07 14:22:46 -05:00
|
|
|
pub type FilterFn = Box<dyn Fn(&PathBuf) -> bool>;
|
|
|
|
|
2022-11-21 08:36:26 -05:00
|
|
|
pub fn get_js_files(
|
|
|
|
cargo_manifest_dir: &'static str,
|
|
|
|
directory: &str,
|
2023-02-07 14:22:46 -05:00
|
|
|
filter: Option<FilterFn>,
|
2022-11-21 08:36:26 -05:00
|
|
|
) -> Vec<PathBuf> {
|
|
|
|
let manifest_dir = Path::new(cargo_manifest_dir);
|
|
|
|
let mut js_files = std::fs::read_dir(directory)
|
|
|
|
.unwrap()
|
|
|
|
.map(|dir_entry| {
|
|
|
|
let file = dir_entry.unwrap();
|
|
|
|
manifest_dir.join(file.path())
|
|
|
|
})
|
|
|
|
.filter(|path| {
|
|
|
|
path.extension().unwrap_or_default() == "js"
|
2023-02-07 14:22:46 -05:00
|
|
|
&& filter.as_ref().map(|filter| filter(path)).unwrap_or(true)
|
2022-11-21 08:36:26 -05:00
|
|
|
})
|
|
|
|
.collect::<Vec<PathBuf>>();
|
|
|
|
js_files.sort();
|
|
|
|
js_files
|
|
|
|
}
|