From f7b9e2e0ad95acbef51532e6e9975e15913c6890 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 1 Nov 2019 13:21:41 -0700 Subject: [PATCH 1/2] Update to criterion 0.3 --- Cargo.lock | 523 +++++++++++++++++++++++++-------------------- Cargo.toml | 2 +- benches/benches.rs | 124 +++-------- 3 files changed, 328 insertions(+), 321 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e9734f..cad86b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,51 +2,61 @@ # It is not intended for manual editing. [[package]] name = "aho-corasick" -version = "0.7.3" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "arrayvec" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "atty" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "autocfg" -version = "0.1.2" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "1.0.4" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bstr" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bumpalo" version = "2.6.0" dependencies = [ - "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "quickcheck 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "byteorder" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -56,7 +66,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -64,9 +74,9 @@ name = "clap" version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -74,107 +84,113 @@ name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "criterion" -version = "0.2.11" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "csv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "tinytemplate 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "criterion-plot" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-deque" -version = "0.2.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" -version = "0.3.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-queue" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-utils" -version = "0.2.2" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "csv" -version = "1.0.7" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "csv-core" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "either" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "env_logger" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -182,93 +198,118 @@ name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "getrandom" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hermit-abi" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itertools" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itoa" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.51" +version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "log" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "memchr" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "memoffset" -version = "0.2.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "nodrop" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num-traits" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "num_cpus" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro2" -version = "0.4.27" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quickcheck" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quote" -version = "0.6.12" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -276,17 +317,17 @@ name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -294,7 +335,7 @@ name = "rand_chacha" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -303,14 +344,22 @@ name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_hc" version = "0.1.0" @@ -329,12 +378,12 @@ dependencies = [ [[package]] name = "rand_jitter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -344,10 +393,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_os" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -355,8 +413,8 @@ name = "rand_pcg" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -369,32 +427,32 @@ dependencies = [ [[package]] name = "rand_xoshiro" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon" -version = "1.0.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -406,46 +464,45 @@ dependencies = [ ] [[package]] -name = "redox_syscall" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_termios" -version = "0.1.1" +name = "regex" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "regex" -version = "1.1.6" +name = "regex-automata" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.6.6" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ryu" -version = "0.2.7" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "same-file" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -453,52 +510,55 @@ dependencies = [ [[package]] name = "scopeguard" -version = "0.3.3" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.90" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.90" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.39" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "0.15.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termion" -version = "1.5.1" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -506,7 +566,7 @@ name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -514,51 +574,46 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tinytemplate" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ucd-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-width" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "utf8-ranges" -version = "1.0.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "walkdir" -version = "2.2.7" +version = "2.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wasi" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -575,7 +630,7 @@ name = "winapi-util" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -584,74 +639,80 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" -"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" -"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" +"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" +"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" -"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" -"checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" -"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum csv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9044e25afb0924b5a5fc5511689b0918629e85d68ea591e5e87fbf1e85ea1b3b" -"checksum csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5cdef62f37e6ffe7d1f07a381bc0db32b7a3ff1cac0de56cb0d81e71f53d65" -"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" -"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a" +"checksum criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "938703e165481c8d612ea3479ac8342e5615185db37765162e762ec3523e2fc6" +"checksum criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eccdc6ce8bbe352ca89025bee672aa6d24f4eb8c53e3a8b5d1bc58011da072a2" +"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" +"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" +"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" +"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" +"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" +"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" +"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" -"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" -"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" -"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" -"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" -"checksum quickcheck 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3568ae5409428feef71bf062778bf5acfadc3d496b7696afa829f9eef70e17dc" -"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" +"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" +"checksum itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87fa75c9dea7b07be3138c49abbb83fd4bea199b5cdc76f9804458edc5da0d6e" +"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a85c1a8c329f11437034d7313dca647c79096523533a1c79e86f1d0f657c7cc" +"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" +"checksum num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "155394f924cdddf08149da25bfb932d226b4a593ca7468b08191ff6335941af5" +"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" +"checksum quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9c35d9c36a562f37eca96e79f66d5fd56eefbc22560dacc4a864cabd2d277456" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" +"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +"checksum rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a788ae3edb696cfcba1c19bfd388cc4b8c21f8a408432b199c072825084da58a" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" -"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" +"checksum rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e18c91676f670f6f0312764c759405f13afb98d5d73819840cf72a518487bff" +"checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" +"checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58" -"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" -"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" -"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4" -"checksum serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "58fc82bec244f168b23d1963b45c8bf5726e9a15a9d146a067f9081aeed2de79" -"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" -"checksum syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)" = "846620ec526c1599c070eff393bfeeeb88a93afa2513fc3b49f1fea84cf7b0ed" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" +"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" +"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" +"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" +"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" +"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8" +"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" +"checksum syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7bedb3320d0f3035594b0b723c8a28d7d336a3eda3881db79e61d676fb644c" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum tinytemplate 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7655088894274afb52b807bd3c87072daa1fedd155068b8705cabfd628956115" -"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" -"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" -"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20" +"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" +"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index 21b9d66..2cf0b99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ harness = false [dev-dependencies] quickcheck = "0.8.2" -criterion = "0.2.10" +criterion = "0.3.0" [features] default = ["collections"] diff --git a/benches/benches.rs b/benches/benches.rs index dfe7907..5f1415f 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -1,4 +1,4 @@ -use criterion::{criterion_group, criterion_main, Criterion, ParameterizedBenchmark, Throughput}; +use criterion::*; #[derive(Default)] struct Small(u8); @@ -6,27 +6,21 @@ struct Small(u8); #[derive(Default)] struct Big([usize; 32]); -struct Huge([usize; 1024]); - -impl Default for Huge { - fn default() -> Huge { - Huge([0; 1024]) - } -} - fn alloc(n: usize) { - let arena = bumpalo::Bump::new(); + let arena = bumpalo::Bump::with_capacity(n * std::mem::size_of::()); for _ in 0..n { - let val: &mut T = arena.alloc(Default::default()); - criterion::black_box(val); + let arena = black_box(&arena); + let val: &mut T = arena.alloc(black_box(Default::default())); + black_box(val); } } fn alloc_with(n: usize) { - let arena = bumpalo::Bump::new(); + let arena = bumpalo::Bump::with_capacity(n * std::mem::size_of::()); for _ in 0..n { - let val: &mut T = arena.alloc_with(Default::default); - criterion::black_box(val); + let arena = black_box(&arena); + let val: &mut T = arena.alloc_with(|| black_box(Default::default())); + black_box(val); } } @@ -37,84 +31,36 @@ fn format_realloc(bump: &bumpalo::Bump, n: usize) { criterion::black_box(s); } -fn criterion_benchmark(c: &mut Criterion) { - c.bench( - "alloc", - ParameterizedBenchmark::new( - "small", - |b, n| b.iter(|| alloc::(*n)), - (1..3).map(|n| n * 1000).collect::>(), - ) - .throughput(|n| Throughput::Elements(*n as u32)), - ); - - c.bench( - "alloc", - ParameterizedBenchmark::new( - "big", - |b, n| b.iter(|| alloc::(*n)), - (1..3).map(|n| n * 1000).collect::>(), - ) - .throughput(|n| Throughput::Elements(*n as u32)), - ); +const ALLOCATIONS: usize = 10_000; - c.bench( - "alloc", - ParameterizedBenchmark::new( - "huge", - |b, n| b.iter(|| alloc::(*n)), - (1..3).map(|n| n * 1000).collect::>(), - ) - .throughput(|n| Throughput::Elements(*n as u32)), - ); - - c.bench( - "alloc_with", - ParameterizedBenchmark::new( - "small", - |b, n| b.iter(|| alloc_with::(*n)), - (1..3).map(|n| n * 1000).collect::>(), - ) - .throughput(|n| Throughput::Elements(*n as u32)), - ); +fn bench_alloc(c: &mut Criterion) { + let mut group = c.benchmark_group("alloc"); + group.throughput(Throughput::Elements(ALLOCATIONS as u64)); + group.bench_function("small", |b| b.iter(|| alloc::(ALLOCATIONS))); + group.bench_function("big", |b| b.iter(|| alloc::(ALLOCATIONS))); +} - c.bench( - "alloc_with", - ParameterizedBenchmark::new( - "big", - |b, n| b.iter(|| alloc_with::(*n)), - (1..3).map(|n| n * 1000).collect::>(), - ) - .throughput(|n| Throughput::Elements(*n as u32)), - ); +fn bench_alloc_with(c: &mut Criterion) { + let mut group = c.benchmark_group("alloc-with"); + group.throughput(Throughput::Elements(ALLOCATIONS as u64)); + group.bench_function("small", |b| b.iter(|| alloc_with::(ALLOCATIONS))); + group.bench_function("big", |b| b.iter(|| alloc_with::(ALLOCATIONS))); +} - c.bench( - "alloc_with", - ParameterizedBenchmark::new( - "huge", - |b, n| b.iter(|| alloc_with::(*n)), - (1..3).map(|n| n * 1000).collect::>(), - ) - .throughput(|n| Throughput::Elements(*n as u32)), - ); +fn bench_format_realloc(c: &mut Criterion) { + let mut group = c.benchmark_group("format-realloc"); - #[cfg(feature = "collections")] - c.bench( - "format-realloc", - ParameterizedBenchmark::new( - "hello {someone}", - |b, n| { - let mut bump = bumpalo::Bump::new(); - b.iter(|| { - bump.reset(); - format_realloc(&bump, *n); - }); - }, - (1..5).map(|n| n * n * n * 10).collect::>(), - ) - .throughput(|n| Throughput::Elements(*n as u32)), - ); + for n in (1..5).map(|n| n * n * n * 10) { + group.throughput(Throughput::Elements(n as u64)); + group.bench_with_input(BenchmarkId::new("format-realloc", n), &n, |b, n| { + let mut bump = bumpalo::Bump::new(); + b.iter(|| { + bump.reset(); + format_realloc(&bump, *n); + }); + }); + } } -criterion_group!(benches, criterion_benchmark); +criterion_group!(benches, bench_alloc, bench_alloc_with, bench_format_realloc); criterion_main!(benches); From 2f33d058e0d560e105e960d828a03b0cb2c792e9 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 1 Nov 2019 13:43:10 -0700 Subject: [PATCH 2/2] Bump downwards This changes `bumpalo`'s implementation from * initializing the bump pointer at the start of the chunk, and * incrementing the bump pointer to allocate an object to * initializing the bump pointer at the end of the chunk, and * decrementing the bump pointer to allocate an object This means that we are now rounding down to align the pointer, which is just masking the bottom bits. Rounding up, what we used to have to do, required an addition which could overflow, which meant that we had an extra conditional branch in the generated code. Furthermore, once the bump pointer is decremented, it is now pointing directly at the allocated space. Previously, we had to save a copy of the original pointer in a temporary, update the bump pointer, and then return the temporary. That requires the use of an extra register, so the new approach should help lower register pressure at call sites, producing slightly better code. The decrement also requirers fewer instructions to implement, which is better for code size, and all else being equal should also imply a speed up in its own right as well. Put all this together and it looks like allocation speeds up 3-19% depending on the work load! See the benchmark results below. Note that there is a ~4% regression in `realloc` performance. This is because the new, decrementing-the-bump-pointer implementation cannot grow the last allocation in place by only updating the bump pointer. It has to do a copy since the beginning of the allocation moves, even when we get to reuse the original allocation's space. I think this is worth the trade off for the speed up to allocation, however. -------------------------------------------------------------------------------- alloc/small time: [26.129 us 26.168 us 26.208 us] thrpt: [381.56 Melem/s 382.15 Melem/s 382.71 Melem/s] change: time: [-9.2069% -8.7900% -8.3936%] (p = 0.00 < 0.05) thrpt: [+9.1627% +9.6372% +10.141%] Performance has improved. Found 123 outliers among 1000 measurements (12.30%) 51 (5.10%) high mild 72 (7.20%) high severe alloc/big time: [348.03 us 348.21 us 348.41 us] thrpt: [28.702 Melem/s 28.718 Melem/s 28.733 Melem/s] change: time: [-3.1144% -3.0057% -2.8915%] (p = 0.00 < 0.05) thrpt: [+2.9776% +3.0989% +3.2145%] Performance has improved. Found 150 outliers among 1000 measurements (15.00%) 58 (5.80%) low mild 46 (4.60%) high mild 46 (4.60%) high severe alloc-with/small time: [26.446 us 26.477 us 26.508 us] thrpt: [377.25 Melem/s 377.69 Melem/s 378.12 Melem/s] change: time: [-16.499% -16.191% -15.898%] (p = 0.00 < 0.05) thrpt: [+18.904% +19.318% +19.759%] Performance has improved. Found 57 outliers among 1000 measurements (5.70%) 43 (4.30%) high mild 14 (1.40%) high severe alloc-with/big time: [313.26 us 313.75 us 314.35 us] thrpt: [31.811 Melem/s 31.872 Melem/s 31.922 Melem/s] change: time: [-6.5853% -6.2957% -6.0163%] (p = 0.00 < 0.05) thrpt: [+6.4014% +6.7187% +7.0495%] Performance has improved. Found 166 outliers among 1000 measurements (16.60%) 70 (7.00%) low mild 44 (4.40%) high mild 52 (5.20%) high severe format-realloc/format-realloc/10 time: [84.850 ns 85.002 ns 85.162 ns] thrpt: [117.42 Melem/s 117.64 Melem/s 117.86 Melem/s] change: time: [+4.8825% +5.4527% +6.2553%] (p = 0.00 < 0.05) thrpt: [-5.8870% -5.1707% -4.6552%] Performance has regressed. Found 299 outliers among 1000 measurements (29.90%) 1 (0.10%) low severe 78 (7.80%) low mild 22 (2.20%) high mild 198 (19.80%) high severe format-realloc/format-realloc/80 time: [85.144 ns 85.353 ns 85.571 ns] thrpt: [934.89 Melem/s 937.29 Melem/s 939.58 Melem/s] change: time: [+4.6040% +5.5085% +6.1615%] (p = 0.00 < 0.05) thrpt: [-5.8039% -5.2209% -4.4014%] Performance has regressed. Found 168 outliers among 1000 measurements (16.80%) 40 (4.00%) high mild 128 (12.80%) high severe format-realloc/format-realloc/270 time: [84.940 ns 85.080 ns 85.225 ns] thrpt: [3.1681 Gelem/s 3.1735 Gelem/s 3.1787 Gelem/s] change: time: [+3.7967% +4.2268% +4.6452%] (p = 0.00 < 0.05) thrpt: [-4.4390% -4.0554% -3.6579%] Performance has regressed. Found 229 outliers among 1000 measurements (22.90%) 8 (0.80%) low severe 2 (0.20%) low mild 11 (1.10%) high mild 208 (20.80%) high severe format-realloc/format-realloc/640 time: [85.917 ns 86.199 ns 86.497 ns] thrpt: [7.3991 Gelem/s 7.4247 Gelem/s 7.4490 Gelem/s] change: time: [+2.2676% +3.1780% +3.8626%] (p = 0.00 < 0.05) thrpt: [-3.7190% -3.0801% -2.2173%] Performance has regressed. Found 169 outliers among 1000 measurements (16.90%) 62 (6.20%) high mild 107 (10.70%) high severe --- src/lib.rs | 294 +++++++++++++++++++++++++++++++++++++------------ tests/tests.rs | 29 +++-- tests/vec.rs | 92 ---------------- 3 files changed, 239 insertions(+), 176 deletions(-) mode change 100644 => 100755 tests/vec.rs diff --git a/src/lib.rs b/src/lib.rs index a52cd99..3a43f6b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -327,15 +327,22 @@ impl Bump { }); let size = layout.size(); - debug_assert!(layout.align() % mem::align_of::() == 0); + debug_assert_eq!(layout.align() % mem::align_of::(), 0); let data = alloc(layout); let data = NonNull::new(data).unwrap_or_else(|| oom()); let next = Cell::new(None); - let ptr = Cell::new(data); + + // The `ChunkFooter` is at the end of the chunk. let footer_ptr = data.as_ptr() as usize + size - mem::size_of::(); + debug_assert_eq!(footer_ptr % mem::align_of::(), 0); let footer_ptr = footer_ptr as *mut ChunkFooter; + + // The bump pointer is initialized to the end of the range we will + // bump out of. + let ptr = Cell::new(NonNull::new_unchecked(footer_ptr as *mut u8)); + ptr::write( footer_ptr, ChunkFooter { @@ -345,6 +352,7 @@ impl Bump { ptr, }, ); + NonNull::new_unchecked(footer_ptr) } } @@ -393,8 +401,8 @@ impl Bump { cur_chunk = next_chunk; } - // Reset the bump finger to the start of the chunk. - cur_chunk.as_ref().ptr.set(cur_chunk.as_ref().data); + // Reset the bump finger to the end of the chunk. + cur_chunk.as_ref().ptr.set(cur_chunk.cast()); self.all_chunk_footers.set(cur_chunk); self.current_chunk_footer.set(cur_chunk); @@ -415,7 +423,7 @@ impl Bump { ); debug_assert_eq!( self.current_chunk_footer.get().as_ref().ptr.get(), - self.current_chunk_footer.get().as_ref().data, + self.current_chunk_footer.get().cast(), "Our chunk's bump finger should be reset to the start of its allocation" ); } @@ -607,20 +615,17 @@ impl Bump { let footer = self.current_chunk_footer.get(); let footer = footer.as_ref(); let ptr = footer.ptr.get().as_ptr() as usize; - let end = footer as *const _ as usize; - debug_assert!(ptr <= end); - - // If the pointer overflows, the allocation definitely doesn't fit into the current - // chunk, so we try to get a new one. - let aligned_ptr = round_up_to(ptr, layout.align())?; - let new_ptr = aligned_ptr.checked_add(layout.size())?; - - if new_ptr <= end { - debug_assert!(aligned_ptr <= end); - let p = aligned_ptr as *mut u8; - debug_assert!(new_ptr <= footer as *const _ as usize); - footer.ptr.set(NonNull::new_unchecked(new_ptr as *mut u8)); - Some(NonNull::new_unchecked(p)) + let start = footer.data.as_ptr() as usize; + debug_assert!(start <= ptr); + debug_assert!(ptr <= footer as *const _ as usize); + + let ptr = ptr.checked_sub(layout.size())?; + let aligned_ptr = ptr & !(layout.align() - 1); + + if aligned_ptr >= start { + let aligned_ptr = NonNull::new_unchecked(aligned_ptr as *mut u8); + footer.ptr.set(aligned_ptr); + Some(aligned_ptr) } else { None } @@ -648,19 +653,23 @@ impl Bump { // Set the new chunk as our new current chunk. self.current_chunk_footer.set(footer); - // Move the bump ptr finger ahead to allocate room for `val`. let footer = footer.as_ref(); - let ptr = footer.ptr.get().as_ptr() as usize + size; + + // Move the bump ptr finger down to allocate room for `val`. We know + // this can't overflow because we successfully allocated a chunk of + // at least the requested size. + let ptr = footer.ptr.get().as_ptr() as usize - size; debug_assert!( ptr <= footer as *const _ as usize, - "{} <= {}", + "{:#x} <= {:#x}", ptr, footer as *const _ as usize ); - footer.ptr.set(NonNull::new_unchecked(ptr as *mut u8)); + let ptr = NonNull::new_unchecked(ptr as *mut u8); + footer.ptr.set(ptr); - // Return a pointer to the start of this chunk. - footer.data.cast::() + // Return a pointer to the freshly allocated region in this chunk. + ptr } } @@ -781,13 +790,10 @@ impl Bump { } #[inline] - unsafe fn is_last_allocation(&self, ptr: NonNull, layout: Layout) -> bool { - let old_size = layout.size(); + unsafe fn is_last_allocation(&self, ptr: NonNull) -> bool { let footer = self.current_chunk_footer.get(); let footer = footer.as_ref(); - let footer_ptr = footer.ptr.get(); - let footer_usize = footer_ptr.as_ptr() as usize; - footer_usize.checked_sub(old_size) == Some(ptr.as_ptr() as usize) + footer.ptr.get() == ptr } } @@ -811,18 +817,13 @@ impl<'a> Iterator for ChunkIter<'a> { unsafe { let foot = self.footer?; let foot = foot.as_ref(); - let start = foot.data.as_ptr() as usize; - let end_of_allocated_region = foot.ptr.get().as_ptr() as usize; - debug_assert!(end_of_allocated_region <= foot as *const _ as usize); - debug_assert!( - end_of_allocated_region >= start, - "end_of_allocated_region (0x{:x}) >= start (0x{:x})", - end_of_allocated_region, - start - ); + let data = foot.data.as_ptr() as usize; + let ptr = foot.ptr.get().as_ptr() as usize; + debug_assert!(data <= ptr); + debug_assert!(ptr <= foot as *const _ as usize); - let len = end_of_allocated_region - start; - let slice = slice::from_raw_parts(start as *const mem::MaybeUninit, len); + let len = foot as *const _ as usize - ptr; + let slice = slice::from_raw_parts(ptr as *const mem::MaybeUninit, len); self.footer = foot.next.get(); Some(slice) } @@ -847,7 +848,8 @@ unsafe impl<'a> alloc::Alloc for &'a Bump { unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { // If the pointer is the last allocation we made, we can reuse the bytes, // otherwise they are simply leaked -- at least until somebody calls reset(). - if self.is_last_allocation(ptr, layout) { + if self.is_last_allocation(ptr) { + let ptr = NonNull::new_unchecked(ptr.as_ptr().add(layout.size())); self.current_chunk_footer.get().as_ref().ptr.set(ptr); } } @@ -862,41 +864,189 @@ unsafe impl<'a> alloc::Alloc for &'a Bump { let old_size = layout.size(); if new_size <= old_size { - // Shrinking an allocation is easy: Just give the same pointer back - // If it's the last allocation, we can reclaim some of the bytes, otherwise - // they are simply leaked. - if self.is_last_allocation(ptr, layout) { - let new_end = NonNull::new_unchecked(ptr.as_ptr().add(new_size)); - self.current_chunk_footer.get().as_ref().ptr.set(new_end); + if self.is_last_allocation(ptr) + // Only reclaim the excess space (which requires a copy) if it + // is worth it: we are actually going to recover "enough" space + // and we can do a non-overlapping copy. + && new_size <= old_size / 2 + { + let delta = old_size - new_size; + let footer = self.current_chunk_footer.get(); + let footer = footer.as_ref(); + footer + .ptr + .set(NonNull::new_unchecked(footer.ptr.get().as_ptr().add(delta))); + let new_ptr = footer.ptr.get(); + // NB: we know it is non-overlapping because of the size check + // in the `if` condition. + ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), new_size); + return Ok(new_ptr); + } else { + return Ok(ptr); } + } - Ok(ptr) - } else { - // Increasing an allocation is harder. If it is the last allocation, we - // can *try* increasing it, but we might not have enough space in the - // current chunk. If this does not work, we must fall back to alloc+copy - if self.is_last_allocation(ptr, layout) { - // Since the old pointer is already aligned, we can simple request the - // remaining bytes without any alignment. - let delta = new_size - old_size; - if self - .try_alloc_layout_fast(layout_from_size_align(delta, 1)) - .is_some() - { - return Ok(ptr); - } + if self.is_last_allocation(ptr) { + // Try to allocate the delta size within this same block so we can + // reuse the currently allocated space. + let delta = new_size - old_size; + if let Some(p) = + self.try_alloc_layout_fast(layout_from_size_align(delta, layout.align())) + { + ptr::copy(ptr.as_ptr(), p.as_ptr(), new_size); + return Ok(p); } - - // Fallback: alloc+copy - let new_layout = layout_from_size_align(new_size, layout.align()); - let new_ptr = self.alloc_layout(new_layout); - ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), old_size); - Ok(new_ptr) } + + // Fallback: do a fresh allocation and copy the existing data into it. + let new_layout = layout_from_size_align(new_size, layout.align()); + let new_ptr = self.alloc_layout(new_layout); + ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), old_size); + Ok(new_ptr) } } -#[test] -fn chunk_footer_is_five_words() { - assert_eq!(mem::size_of::(), mem::size_of::() * 5); +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn chunk_footer_is_five_words() { + assert_eq!(mem::size_of::(), mem::size_of::() * 5); + } + + #[test] + #[allow(clippy::cognitive_complexity)] + fn test_realloc() { + use crate::alloc::Alloc; + + unsafe { + const CAPACITY: usize = 1000; + let mut b = Bump::with_capacity(CAPACITY); + + // `realloc` doesn't shrink allocations that aren't "worth it". + let layout = Layout::from_size_align(100, 1).unwrap(); + let p = b.alloc_layout(layout); + let q = (&b).realloc(p, layout, 51).unwrap(); + assert_eq!(p, q); + b.reset(); + + // `realloc` will shrink allocations that are "worth it". + let layout = Layout::from_size_align(100, 1).unwrap(); + let p = b.alloc_layout(layout); + let q = (&b).realloc(p, layout, 50).unwrap(); + assert!(p != q); + b.reset(); + + // `realloc` will reuse the last allocation when growing. + let layout = Layout::from_size_align(10, 1).unwrap(); + let p = b.alloc_layout(layout); + let q = (&b).realloc(p, layout, 11).unwrap(); + assert_eq!(q.as_ptr() as usize, p.as_ptr() as usize - 1); + b.reset(); + + // `realloc` will allocate a new chunk when growing the last + // allocation, if need be. + let layout = Layout::from_size_align(1, 1).unwrap(); + let p = b.alloc_layout(layout); + let q = (&b).realloc(p, layout, CAPACITY + 1).unwrap(); + assert!(q.as_ptr() as usize != p.as_ptr() as usize - CAPACITY); + b = Bump::with_capacity(CAPACITY); + + // `realloc` will allocate and copy when reallocating anything that + // wasn't the last allocation. + let layout = Layout::from_size_align(1, 1).unwrap(); + let p = b.alloc_layout(layout); + let _ = b.alloc_layout(layout); + let q = (&b).realloc(p, layout, 2).unwrap(); + assert!(q.as_ptr() as usize != p.as_ptr() as usize - 1); + b.reset(); + } + // let v1_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + // let v2_data = [41, 42, 43, 44, 45, 46, 47, 48, 49, 50]; + // let mut v1 = bumpalo::vec![in &b; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + // v1.reserve(90); + // let v1_ptr = v1.as_ptr(); + // assert!(10 <= v1.capacity() && v1.capacity() < 20); + + // // Shift the size up and down a few times and see that it stays in place + // v1.reserve(100); + // assert!(v1.capacity() >= 100); + // assert_eq!(v1.as_ptr(), v1_ptr); + // assert_eq!(v1, v1_data); + + // v1.shrink_to_fit(); + // assert!(10 <= v1.capacity() && v1.capacity() < 20); + // assert_eq!(v1.as_ptr(), v1_ptr); + // assert_eq!(v1, v1_data); + + // v1.reserve(100); + // assert!(v1.capacity() >= 100); + // assert_eq!(v1.as_ptr(), v1_ptr); + // assert_eq!(v1, v1_data); + + // v1.shrink_to_fit(); + // assert!(10 <= v1.capacity() && v1.capacity() < 20); + // assert_eq!(v1.as_ptr(), v1_ptr); + // assert_eq!(v1, v1_data); + + // // Allocate just after our buffer, to see that it blocks in-place expansion + // let mut v2 = bumpalo::vec![in &b; 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]; + // let v2_ptr = v2.as_ptr(); + // assert!(10 <= v2.capacity() && v2.capacity() < 20); + // assert_eq!(unsafe { v1_ptr.add(v1.capacity()) }, v2_ptr); + + // v1.reserve(100); + // assert!(v1.capacity() >= 100); + // assert_ne!(v1.as_ptr(), v1_ptr); + // assert_eq!(v1, v1_data); + + // // Our chunk is now [old, dead v1] [current v2] [current v1] + // let v1_ptr = v1.as_ptr(); + // assert_eq!(unsafe { v2_ptr.add(v2.capacity()) }, v1_ptr); + + // // See that we can still shrink at the new location as well + // v1.shrink_to_fit(); + // assert!(10 <= v1.capacity() && v1.capacity() < 20); + // assert_eq!(v1.as_ptr(), v1_ptr); + // assert_eq!(v1, v1_data); + + // // And see that we get a new chunk if we expand too much + // v1.reserve(10_000); + // assert!(v1.capacity() >= 10_000); + // assert_ne!(v1.as_ptr(), v1_ptr); + // assert_eq!(v1, v1_data); + + // // See that we can deallocate and re-use the existing memory + // let v1_ptr = v1.as_ptr(); + // mem::drop(v1); + + // let mut v1 = bumpalo::vec![in &b; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + // assert!(10 <= v1.capacity() && v1.capacity() < 20); + // assert_eq!(v1.as_ptr(), v1_ptr); + + // // At this point, the old chunk is [old, dead v1] [current v2] [old, dead v1] + // // See that we can still shrink buffers that are not at the end without moving them + // v2.truncate(5); + // v2.shrink_to_fit(); + // assert!(v2.capacity() < 10); + // assert_eq!(v2.as_ptr(), v2_ptr); + // assert_eq!(v2, &v2_data[..5]); + + // // However we cannot increase their size back up again without moving + // v2.extend_from_slice(&[46, 47, 48, 49, 50]); + // assert!(10 <= v2.capacity() && v2.capacity() < 20); + // assert_ne!(v2.as_ptr(), v2_ptr); + // assert_eq!(v2, v2_data); + // let v2_ptr = v2.as_ptr(); + + // // At this point, our new chunk should be [current v1][current v2] + // assert_eq!(unsafe { v1_ptr.add(v1.capacity()) }, v2_ptr); + + // // If we free v2, we should be able to extend v1 inplace + // mem::drop(v2); + // v1.reserve(100); + // assert!(v1.capacity() >= 100); + // assert_eq!(v1.as_ptr(), v1_ptr); + } } diff --git a/tests/tests.rs b/tests/tests.rs index 316d300..a07f785 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -9,7 +9,7 @@ fn can_iterate_over_allocated_things() { const MAX: u64 = 131_072; - let mut chunks = vec![]; + let mut chunk_ends = vec![]; let mut last = None; for i in 0..MAX { @@ -18,30 +18,32 @@ fn can_iterate_over_allocated_things() { let this = this as *const _ as usize; if match last { - Some(last) if last + mem::size_of::() == this => false, + Some(last) if last - mem::size_of::() == this => false, _ => true, } { - println!("new chunk @ 0x{:x}", this); + let chunk_end = this + mem::size_of::(); + println!("new chunk ending @ 0x{:x}", chunk_end); assert!( - !chunks.contains(&this), + !chunk_ends.contains(&chunk_end), "should not have already allocated this chunk" ); - chunks.push(this); + chunk_ends.push(chunk_end); } last = Some(this); } let mut seen = vec![false; MAX as usize]; - chunks.reverse(); + chunk_ends.reverse(); // Safe because we always allocated objects of the same type in this arena, // and their size >= their align. for ch in bump.iter_allocated_chunks() { - println!("iter chunk @ {:p}", ch); + let chunk_end = ch.as_ptr() as usize + ch.len(); + println!("iter chunk ending @ {:#x}", chunk_end); assert_eq!( - chunks.pop().unwrap(), - ch.as_ptr() as usize, + chunk_ends.pop().unwrap(), + chunk_end, "should iterate over each chunk once, in order they were allocated in" ); @@ -144,7 +146,7 @@ where let (before, mid, after) = unsafe { c.align_to::() }; assert!(before.is_empty()); assert!(after.is_empty()); - mid.iter().copied() + mid.iter().rev().copied() }); assert!(pushed_values.eq(iter.clone())); } @@ -169,8 +171,11 @@ fn test_reset() { assert!(b.iter_allocated_chunks().count() > 1); - let ptr = b.iter_allocated_chunks().last().unwrap().as_ptr(); + let last_chunk = b.iter_allocated_chunks().last().unwrap(); + let start = last_chunk.as_ptr() as usize; + let end = start + last_chunk.len(); + dbg!((start, end)); b.reset(); - assert_eq!(ptr as usize, b.alloc(0u64) as *const u64 as usize); + assert_eq!(end - mem::size_of::(), b.alloc(0u64) as *const u64 as usize); assert_eq!(b.iter_allocated_chunks().count(), 1); } diff --git a/tests/vec.rs b/tests/vec.rs old mode 100644 new mode 100755 index d33399c..7ccfda0 --- a/tests/vec.rs +++ b/tests/vec.rs @@ -1,7 +1,6 @@ #![cfg(feature = "collections")] use bumpalo::{collections::Vec, Bump}; use std::cell::Cell; -use std::mem; #[test] fn push_a_bunch_of_items() { @@ -12,97 +11,6 @@ fn push_a_bunch_of_items() { } } -#[test] -#[allow(clippy::cognitive_complexity)] -fn test_realloc() { - let b = Bump::with_capacity(1000); - let v1_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let v2_data = [41, 42, 43, 44, 45, 46, 47, 48, 49, 50]; - let mut v1 = bumpalo::vec![in &b; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - let v1_ptr = v1.as_ptr(); - assert!(10 <= v1.capacity() && v1.capacity() < 20); - - // Shift the size up and down a few times and see that it stays in place - v1.reserve(100); - assert!(v1.capacity() >= 100); - assert_eq!(v1.as_ptr(), v1_ptr); - assert_eq!(v1, v1_data); - - v1.shrink_to_fit(); - assert!(10 <= v1.capacity() && v1.capacity() < 20); - assert_eq!(v1.as_ptr(), v1_ptr); - assert_eq!(v1, v1_data); - - v1.reserve(100); - assert!(v1.capacity() >= 100); - assert_eq!(v1.as_ptr(), v1_ptr); - assert_eq!(v1, v1_data); - - v1.shrink_to_fit(); - assert!(10 <= v1.capacity() && v1.capacity() < 20); - assert_eq!(v1.as_ptr(), v1_ptr); - assert_eq!(v1, v1_data); - - // Allocate just after our buffer, to see that it blocks in-place expansion - let mut v2 = bumpalo::vec![in &b; 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]; - let v2_ptr = v2.as_ptr(); - assert!(10 <= v2.capacity() && v2.capacity() < 20); - assert_eq!(unsafe { v1_ptr.add(v1.capacity()) }, v2_ptr); - - v1.reserve(100); - assert!(v1.capacity() >= 100); - assert_ne!(v1.as_ptr(), v1_ptr); - assert_eq!(v1, v1_data); - - // Our chunk is now [old, dead v1] [current v2] [current v1] - let v1_ptr = v1.as_ptr(); - assert_eq!(unsafe { v2_ptr.add(v2.capacity()) }, v1_ptr); - - // See that we can still shrink at the new location as well - v1.shrink_to_fit(); - assert!(10 <= v1.capacity() && v1.capacity() < 20); - assert_eq!(v1.as_ptr(), v1_ptr); - assert_eq!(v1, v1_data); - - // And see that we get a new chunk if we expand too much - v1.reserve(10_000); - assert!(v1.capacity() >= 10_000); - assert_ne!(v1.as_ptr(), v1_ptr); - assert_eq!(v1, v1_data); - - // See that we can deallocate and re-use the existing memory - let v1_ptr = v1.as_ptr(); - mem::drop(v1); - - let mut v1 = bumpalo::vec![in &b; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert!(10 <= v1.capacity() && v1.capacity() < 20); - assert_eq!(v1.as_ptr(), v1_ptr); - - // At this point, the old chunk is [old, dead v1] [current v2] [old, dead v1] - // See that we can still shrink buffers that are not at the end without moving them - v2.truncate(5); - v2.shrink_to_fit(); - assert!(v2.capacity() < 10); - assert_eq!(v2.as_ptr(), v2_ptr); - assert_eq!(v2, &v2_data[..5]); - - // However we cannot increase their size back up again without moving - v2.extend_from_slice(&[46, 47, 48, 49, 50]); - assert!(10 <= v2.capacity() && v2.capacity() < 20); - assert_ne!(v2.as_ptr(), v2_ptr); - assert_eq!(v2, v2_data); - let v2_ptr = v2.as_ptr(); - - // At this point, our new chunk should be [current v1][current v2] - assert_eq!(unsafe { v1_ptr.add(v1.capacity()) }, v2_ptr); - - // If we free v2, we should be able to extend v1 inplace - mem::drop(v2); - v1.reserve(100); - assert!(v1.capacity() >= 100); - assert_eq!(v1.as_ptr(), v1_ptr); -} - #[test] fn recursive_vecs() { // The purpose of this test is to see if the data structures with