difftreelog
perf use mimalloc instead of jemalloc
in: master
3 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -36,9 +36,9 @@
[[package]]
name = "cc"
-version = "1.0.54"
+version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311"
+checksum = "b1be3409f94d7bdceeb5f5fac551039d9b3f00e25da7a74fc4d33400a0d96368"
[[package]]
name = "clap"
@@ -76,12 +76,6 @@
checksum = "d6173fd61b610d15a7566dd7b7620775627441c4ab9dac8906e17cb93a24b782"
[[package]]
-name = "fs_extra"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
-
-[[package]]
name = "heck"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -97,27 +91,6 @@
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
dependencies = [
"autocfg",
-]
-
-[[package]]
-name = "jemalloc-sys"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45"
-dependencies = [
- "cc",
- "fs_extra",
- "libc",
-]
-
-[[package]]
-name = "jemallocator"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43ae63fcfc45e99ab3d1b29a46782ad679e98436c3169d15a167a1108a724b69"
-dependencies = [
- "jemalloc-sys",
- "libc",
]
[[package]]
@@ -126,9 +99,9 @@
dependencies = [
"annotate-snippets",
"clap",
- "jemallocator",
"jrsonnet-evaluator",
"jrsonnet-parser",
+ "mimallocator",
]
[[package]]
@@ -189,6 +162,25 @@
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
[[package]]
+name = "mimalloc-sys"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4aa3cefb626f6ae3d0b2f71c5378c89d2b1d4d7bc246b0ca9a7ee61a4daad291"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "mimallocator"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d44fe4ebf6b538fcf39d9975c2b90bb3232d1ba8e8bffeacd004f27b20c577a"
+dependencies = [
+ "mimalloc-sys",
+]
+
+[[package]]
name = "os_str_bytes"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
cmds/jrsonnet/Cargo.tomldiffbeforeafterboth--- a/cmds/jrsonnet/Cargo.toml
+++ b/cmds/jrsonnet/Cargo.toml
@@ -12,7 +12,8 @@
jrsonnet-evaluator = { path = "../../crates/jrsonnet-evaluator", version = "1.0.0" }
jrsonnet-parser = { path = "../../crates/jrsonnet-parser", version = "1.0.0" }
annotate-snippets = "0.8.0"
-jemallocator = "0.3.2"
+# TODO: Fix mimalloc compile errors, and use them
+mimallocator = "0.1.3"
[dependencies.clap]
version = "3.0.0-beta.1"
cmds/jrsonnet/src/main.rsdiffbeforeafterboth1pub mod location;23use clap::Clap;4use jrsonnet_evaluator::{EvaluationState, LocError, StackTrace, Val};5use jrsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParserSettings};6use location::{offset_to_location, CodeLocation};7use std::env::current_dir;8use std::{collections::HashMap, path::PathBuf, rc::Rc, str::FromStr};910#[global_allocator]11static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;1213enum Format {14 None,15 Json,16 Yaml,17}1819impl FromStr for Format {20 type Err = &'static str;21 fn from_str(s: &str) -> Result<Self, Self::Err> {22 Ok(match s {23 "none" => Format::None,24 "json" => Format::Json,25 "yaml" => Format::Yaml,26 _ => return Err("no such format"),27 })28 }29}3031#[derive(PartialEq)]32enum TraceFormat {33 CppJsonnet,34 GoJsonnet,35 Custom,36}37impl FromStr for TraceFormat {38 type Err = &'static str;39 fn from_str(s: &str) -> Result<Self, Self::Err> {40 Ok(match s {41 "cpp" => TraceFormat::CppJsonnet,42 "go" => TraceFormat::GoJsonnet,43 "default" => TraceFormat::Custom,44 _ => return Err("no such format"),45 })46 }47}4849#[derive(Clone)]50struct ExtStr {51 name: String,52 value: String,53}54impl FromStr for ExtStr {55 type Err = &'static str;56 fn from_str(s: &str) -> Result<Self, Self::Err> {57 let out: Vec<_> = s.split('=').collect();58 match out.len() {59 1 => Ok(ExtStr {60 name: out[0].to_owned(),61 value: std::env::var(out[0]).or(Err("missing env var"))?,62 }),63 2 => Ok(ExtStr {64 name: out[0].to_owned(),65 value: out[1].to_owned(),66 }),67 _ => Err("bad ext-str syntax"),68 }69 }70}7172#[derive(Clap)]73#[clap(version = "0.1.0", author = "Lach <iam@lach.pw>")]74struct Opts {75 #[clap(long, about = "Disable global std variable")]76 no_stdlib: bool,77 #[clap(long, about = "Add external string")]78 ext_str: Vec<ExtStr>,79 #[clap(long, about = "Add external string from code")]80 ext_code: Vec<ExtStr>,81 #[clap(long, about = "Add TLA")]82 tla_str: Vec<ExtStr>,83 #[clap(long, about = "Add TLA from code")]84 tla_code: Vec<ExtStr>,85 #[clap(long, short = "f", default_value = "json", possible_values = &["none", "json", "yaml"], about = "Output format, wraps resulting value to corresponding std.manifest call")]86 format: Format,87 #[clap(long, default_value = "default", possible_values = &["cpp", "go", "default"], about = "Emulated needed stacktrace display")]88 trace_format: TraceFormat,8990 #[clap(91 long,92 short = "s",93 default_value = "200",94 about = "Number of allowed stack frames"95 )]96 max_stack: usize,97 #[clap(98 long,99 short = "t",100 default_value = "20",101 about = "Max length of stack trace before cropping"102 )]103 max_trace: usize,104105 #[clap(long, short = "J", about = "Library search dir")]106 jpath: Vec<PathBuf>,107108 #[clap(109 long,110 default_value = "3",111 about = "When using --format, this option specifies string to pad output with"112 )]113 line_padding: usize,114115 #[clap(about = "File to compile", index = 1)]116 input: String,117}118119fn main() {120 let opts: Opts = Opts::parse();121 let evaluator = jrsonnet_evaluator::EvaluationState::default();122 evaluator.set_max_trace(opts.max_trace);123 evaluator.set_max_stack(opts.max_stack);124 evaluator.set_import_resolver(Box::new(jrsonnet_evaluator::FileImportResolver {125 library_paths: opts.jpath.clone(),126 }));127 if !opts.no_stdlib {128 evaluator.with_stdlib();129 }130 for ExtStr { name, value } in opts.ext_str.iter().cloned() {131 evaluator.add_ext_var(name.into(), Val::Str(value.into()));132 }133 for ExtStr { name, value } in opts.ext_code.iter().cloned() {134 evaluator.add_ext_var(name.into(), evaluator.parse_evaluate_raw(&value).unwrap());135 }136 let mut input = current_dir().unwrap();137 input.push(opts.input.clone());138 let code_string = String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap();139 if let Err(e) = evaluator.add_file(Rc::new(input.clone()), code_string.clone().into()) {140 print_syntax_error(e, &input, &code_string);141 std::process::exit(1);142 }143 let result = evaluator.evaluate_file(&input);144 match result {145 Ok(v) => {146 let v = match v {147 Val::Func(f) => {148 let mut desc_map = HashMap::new();149 for ExtStr { name, value } in opts.tla_str.iter().cloned() {150 desc_map.insert(name, el!(Expr::Str(value.into())));151 }152 for ExtStr { name, value } in opts.tla_code.iter().cloned() {153 desc_map.insert(154 name,155 jrsonnet_parser::parse(156 &value,157 &ParserSettings {158 file_name: Rc::new(PathBuf::new()),159 loc_data: false,160 },161 )162 .unwrap(),163 );164 }165 evaluator.add_global("__tmp__tlf__".into(), Val::Func(f));166 evaluator167 .evaluate_raw(el!(Expr::Apply(168 el!(Expr::Var("__tmp__tlf__".into())),169 ArgsDesc(desc_map.into_iter().map(|(k, v)| Arg(Some(k), v)).collect()),170 false,171 )))172 .unwrap()173 }174 v => v,175 };176 let v = evaluator.run_in_state(|| match opts.format {177 Format::Json => Ok(Val::Str(v.into_json(opts.line_padding)?)),178 Format::Yaml => {179 evaluator.add_global("__tmp__to_yaml__".into(), v);180 evaluator.parse_evaluate_raw("std.manifestYamlDoc(__tmp__to_yaml__, \" \")")181 }182 _ => Ok(v),183 });184 let v = match v {185 Ok(v) => v,186 Err(err) => {187 print_error(&err, evaluator, &opts);188 std::process::exit(1);189 }190 };191 match v {192 Val::Str(s) => println!("{}", s),193 Val::Num(n) => println!("{}", n),194 _v => eprintln!(195 "jsonnet output is not a string.\nDid you forgot to set --format, or wrap your data with std.manifestJson?"196 ),197 }198 }199 Err(err) => {200 print_error(&err, evaluator, &opts);201 std::process::exit(1);202 }203 }204}205206fn print_error(err: &LocError, evaluator: EvaluationState, opts: &Opts) {207 println!("Error: {:?}", err.0);208 print_trace(&(err.1), evaluator, &opts);209}210211fn print_syntax_error(error: jrsonnet_parser::ParseError, file: &PathBuf, code: &str) {212 use annotate_snippets::{213 display_list::{DisplayList, FormatOptions},214 snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},215 };216 //&("Expected: ".to_owned() + error.expected)217 let origin = file.to_str().unwrap();218 let error_message = format!("Expected: {}", error.expected);219 let snippet = Snippet {220 opt: FormatOptions {221 color: true,222 ..Default::default()223 },224 title: Some(Annotation {225 label: Some(&error_message),226 id: None,227 annotation_type: AnnotationType::Error,228 }),229 footer: vec![],230 slices: vec![Slice {231 source: &code,232 line_start: 1,233 origin: Some(origin),234 fold: false,235 annotations: vec![SourceAnnotation {236 label: "At this position",237 annotation_type: AnnotationType::Error,238 range: (error.location.offset, error.location.offset + 1),239 }],240 }],241 };242243 let dl = DisplayList::from(snippet);244 println!("{}", dl);245}246247fn print_trace(trace: &StackTrace, evaluator: EvaluationState, opts: &Opts) {248 use annotate_snippets::{249 display_list::{DisplayList, FormatOptions},250 snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},251 };252 for item in trace.0.iter() {253 let desc = &item.1;254 let source = item.0.clone();255 let code = evaluator.get_source(&source.0);256 if code.is_none() {257 continue;258 }259 let code = code.unwrap();260 let start_end = offset_to_location(&code, &[source.1, source.2]);261 if opts.trace_format == TraceFormat::Custom {262 let source_fragment: String = code263 .chars()264 .skip(start_end[0].line_start_offset)265 .take(start_end[1].line_end_offset - start_end[0].line_start_offset)266 .collect();267 let snippet = Snippet {268 opt: FormatOptions {269 color: true,270 ..Default::default()271 },272 title: Some(Annotation {273 label: Some(&item.1),274 id: None,275 annotation_type: AnnotationType::Error,276 }),277 footer: vec![],278 slices: vec![Slice {279 source: &source_fragment,280 line_start: start_end[0].line,281 origin: Some(&source.0.to_str().unwrap()),282 fold: false,283 annotations: vec![SourceAnnotation {284 label: desc,285 annotation_type: AnnotationType::Error,286 range: (287 source.1 - start_end[0].line_start_offset,288 source.2 - start_end[0].line_start_offset,289 ),290 }],291 }],292 };293294 let dl = DisplayList::from(snippet);295 println!("{}", dl);296 } else {297 print_jsonnet_pair(298 source.0.to_str().unwrap(),299 &start_end[0],300 &start_end[1],301 opts.trace_format == TraceFormat::GoJsonnet,302 );303 }304 }305}306307fn print_jsonnet_pair(file: &str, start: &CodeLocation, end: &CodeLocation, is_go: bool) {308 if is_go {309 print!(" ");310 } else {311 print!(" ");312 }313 print!("{}:", file);314 if start.line == end.line {315 // IDK why, but this is the behavior original jsonnet cpp impl shows316 if start.column == end.column || !is_go && start.column + 1 == end.column {317 println!("{}:{}", start.line, end.column)318 } else {319 println!("{}:{}-{}", start.line, start.column, end.column);320 }321 } else {322 println!(323 "({}:{})-({}:{})",324 start.line, end.column, start.line, end.column325 );326 }327}