binary trees
This commit is contained in:
parent
1c9d620627
commit
d84b1968d5
16 changed files with 521 additions and 139 deletions
285
Cargo.lock
generated
285
Cargo.lock
generated
|
@ -11,6 +11,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anes"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.6.18"
|
version = "0.6.18"
|
||||||
|
@ -107,6 +113,12 @@ dependencies = [
|
||||||
"git2",
|
"git2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.21.0"
|
version = "1.21.0"
|
||||||
|
@ -133,6 +145,12 @@ version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cast"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.12"
|
version = "1.2.12"
|
||||||
|
@ -150,6 +168,33 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ciborium"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
|
||||||
|
dependencies = [
|
||||||
|
"ciborium-io",
|
||||||
|
"ciborium-ll",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ciborium-io"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ciborium-ll"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
|
||||||
|
dependencies = [
|
||||||
|
"ciborium-io",
|
||||||
|
"half",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.28"
|
version = "4.5.28"
|
||||||
|
@ -202,6 +247,42 @@ version = "0.8.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "criterion"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
|
||||||
|
dependencies = [
|
||||||
|
"anes",
|
||||||
|
"cast",
|
||||||
|
"ciborium",
|
||||||
|
"clap",
|
||||||
|
"criterion-plot",
|
||||||
|
"is-terminal",
|
||||||
|
"itertools 0.10.5",
|
||||||
|
"num-traits",
|
||||||
|
"once_cell",
|
||||||
|
"oorandom",
|
||||||
|
"plotters",
|
||||||
|
"rayon",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"tinytemplate",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "criterion-plot"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
|
||||||
|
dependencies = [
|
||||||
|
"cast",
|
||||||
|
"itertools 0.10.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam"
|
name = "crossbeam"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
|
@ -258,6 +339,12 @@ version = "0.8.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crunchy"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "delegate"
|
name = "delegate"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
|
@ -390,6 +477,16 @@ dependencies = [
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "half"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crunchy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -570,6 +667,15 @@ version = "1.70.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
@ -579,6 +685,12 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jobserver"
|
name = "jobserver"
|
||||||
version = "0.1.32"
|
version = "0.1.32"
|
||||||
|
@ -588,6 +700,16 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
@ -678,7 +800,7 @@ dependencies = [
|
||||||
"enum-map",
|
"enum-map",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"is-terminal",
|
"is-terminal",
|
||||||
"itertools",
|
"itertools 0.12.1",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
@ -806,6 +928,12 @@ version = "1.20.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oorandom"
|
||||||
|
version = "11.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
|
@ -841,6 +969,34 @@ version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plotters"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
"plotters-backend",
|
||||||
|
"plotters-svg",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plotters-backend"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plotters-svg"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670"
|
||||||
|
dependencies = [
|
||||||
|
"plotters-backend",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portable-atomic"
|
name = "portable-atomic"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
|
@ -1008,6 +1164,21 @@ version = "1.0.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "same-file"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -1040,6 +1211,18 @@ dependencies = [
|
||||||
"syn 2.0.98",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.138"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -1155,6 +1338,16 @@ dependencies = [
|
||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinytemplate"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.16"
|
version = "1.0.16"
|
||||||
|
@ -1210,9 +1403,12 @@ dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"clap",
|
"clap",
|
||||||
|
"criterion",
|
||||||
"easy-bitfield",
|
"easy-bitfield",
|
||||||
|
"env_logger",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
|
"log",
|
||||||
"mmtk",
|
"mmtk",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"rand",
|
"rand",
|
||||||
|
@ -1228,6 +1424,16 @@ dependencies = [
|
||||||
"syn 2.0.98",
|
"syn 2.0.98",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "walkdir"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||||
|
dependencies = [
|
||||||
|
"same-file",
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.13.3+wasi-0.2.2"
|
version = "0.13.3+wasi-0.2.2"
|
||||||
|
@ -1237,6 +1443,74 @@ dependencies = [
|
||||||
"wit-bindgen-rt",
|
"wit-bindgen-rt",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.98",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.98",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-sys"
|
||||||
|
version = "0.3.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
@ -1253,6 +1527,15 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
|
@ -2,3 +2,6 @@
|
||||||
members = ["vmkit", "vmkit-proc"]
|
members = ["vmkit", "vmkit-proc"]
|
||||||
default-members = ["vmkit"]
|
default-members = ["vmkit"]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
[workspace.example]
|
||||||
|
members = ["examples/*"]
|
|
@ -9,8 +9,10 @@ bytemuck = "1.21.0"
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
clap = { version = "4.5.28", features = ["derive"] }
|
clap = { version = "4.5.28", features = ["derive"] }
|
||||||
easy-bitfield = "0.1.0"
|
easy-bitfield = "0.1.0"
|
||||||
|
env_logger = "0.11.6"
|
||||||
errno = "0.3.10"
|
errno = "0.3.10"
|
||||||
libc = "0.2.169"
|
libc = "0.2.169"
|
||||||
|
log = "0.4.25"
|
||||||
mmtk = { git = "https://github.com/mmtk/mmtk-core" }
|
mmtk = { git = "https://github.com/mmtk/mmtk-core" }
|
||||||
parking_lot = "0.12.3"
|
parking_lot = "0.12.3"
|
||||||
rand = "0.9.0"
|
rand = "0.9.0"
|
||||||
|
@ -31,3 +33,10 @@ full-precise = []
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3.9", features = ["everything"] }
|
winapi = { version = "0.3.9", features = ["everything"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
criterion = "0.5.1"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "binarytrees"
|
||||||
|
harness = false
|
||||||
|
|
0
vmkit/benches/binarytrees.rs
Normal file
0
vmkit/benches/binarytrees.rs
Normal file
|
@ -17,7 +17,7 @@ pub trait VirtualMachine: Sized + 'static + Send + Sync {
|
||||||
type Slot: SlotExtra;
|
type Slot: SlotExtra;
|
||||||
|
|
||||||
const MAX_ALIGNMENT: usize = 16;
|
const MAX_ALIGNMENT: usize = 16;
|
||||||
const MIN_ALIGNMENT: usize = 16;
|
const MIN_ALIGNMENT: usize = 8;
|
||||||
|
|
||||||
/// Does this VM use conservative tracing? If `true` then VM can
|
/// Does this VM use conservative tracing? If `true` then VM can
|
||||||
/// query VO-bit (valid-object bit) to check if an object is live
|
/// query VO-bit (valid-object bit) to check if an object is live
|
||||||
|
|
|
@ -1,42 +1,72 @@
|
||||||
use easy_bitfield::{FromBitfield, ToBitfield};
|
|
||||||
use mmtk::{util::options::PlanSelector, vm::slot::SimpleSlot, AllocationSemantics, MMTKBuilder};
|
use mmtk::{util::options::PlanSelector, vm::slot::SimpleSlot, AllocationSemantics, MMTKBuilder};
|
||||||
|
use std::mem::offset_of;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
use vmkit::{
|
use vmkit::{
|
||||||
mm::{traits::ToSlot, MemoryManager},
|
mm::{traits::Trace, MemoryManager},
|
||||||
object_model::metadata::{GCMetadata, Metadata, Trace},
|
object_model::{
|
||||||
|
metadata::{GCMetadata, TraceCallback},
|
||||||
|
object::VMKitObject,
|
||||||
|
},
|
||||||
threading::{GCBlockAdapter, Thread, ThreadContext},
|
threading::{GCBlockAdapter, Thread, ThreadContext},
|
||||||
VMKit, VirtualMachine,
|
VMKit, VirtualMachine,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TestContext;
|
const CONSERVATIVE_TRACE_NODE: bool = false;
|
||||||
|
|
||||||
impl ThreadContext<VM> for TestContext {
|
#[repr(C)]
|
||||||
|
struct Node {
|
||||||
|
left: VMKitObject,
|
||||||
|
right: VMKitObject,
|
||||||
|
i: usize,
|
||||||
|
j: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
static METADATA: GCMetadata<BenchVM> = GCMetadata {
|
||||||
|
trace: TraceCallback::TraceObject(|object, tracer| unsafe {
|
||||||
|
let node = object.as_address().as_mut_ref::<Node>();
|
||||||
|
node.left.trace_object(tracer);
|
||||||
|
node.right.trace_object(tracer);
|
||||||
|
}),
|
||||||
|
instance_size: size_of::<Node>(),
|
||||||
|
compute_size: None,
|
||||||
|
alignment: 16,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BenchVM {
|
||||||
|
vmkit: VMKit<Self>,
|
||||||
|
}
|
||||||
|
|
||||||
|
static VM: OnceLock<BenchVM> = OnceLock::new();
|
||||||
|
|
||||||
|
struct ThreadBenchContext;
|
||||||
|
|
||||||
|
impl ThreadContext<BenchVM> for ThreadBenchContext {
|
||||||
|
fn new(_: bool) -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
fn save_thread_state(&self) {}
|
fn save_thread_state(&self) {}
|
||||||
|
|
||||||
fn scan_roots(&self, _factory: impl mmtk::vm::RootsWorkFactory<<VM as VirtualMachine>::Slot>) {}
|
fn scan_roots(
|
||||||
|
&self,
|
||||||
|
_factory: impl mmtk::vm::RootsWorkFactory<<BenchVM as VirtualMachine>::Slot>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
fn scan_conservative_roots(
|
fn scan_conservative_roots(
|
||||||
&self,
|
&self,
|
||||||
croots: &mut vmkit::mm::conservative_roots::ConservativeRoots,
|
_croots: &mut vmkit::mm::conservative_roots::ConservativeRoots,
|
||||||
) {
|
) {
|
||||||
let _ = croots;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new(_collector_context: bool) -> Self {
|
|
||||||
Self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static VM_STORAGE: OnceLock<VM> = OnceLock::new();
|
|
||||||
impl VirtualMachine for VM {
|
|
||||||
const MAX_ALIGNMENT: usize = 16;
|
|
||||||
const MIN_ALIGNMENT: usize = 16;
|
|
||||||
type ThreadContext = TestContext;
|
|
||||||
type BlockAdapterList = (GCBlockAdapter, ());
|
|
||||||
type Metadata = &'static GCMetadata<VM>;
|
|
||||||
type Slot = SimpleSlot;
|
|
||||||
|
|
||||||
|
impl VirtualMachine for BenchVM {
|
||||||
|
type BlockAdapterList = (GCBlockAdapter, ());
|
||||||
|
type Metadata = &'static GCMetadata<Self>;
|
||||||
|
type Slot = SimpleSlot;
|
||||||
|
type ThreadContext = ThreadBenchContext;
|
||||||
fn get() -> &'static Self {
|
fn get() -> &'static Self {
|
||||||
VM_STORAGE.get().unwrap()
|
VM.get().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vmkit(&self) -> &VMKit<Self> {
|
fn vmkit(&self) -> &VMKit<Self> {
|
||||||
|
@ -45,7 +75,16 @@ impl VirtualMachine for VM {
|
||||||
|
|
||||||
fn prepare_for_roots_re_scanning() {}
|
fn prepare_for_roots_re_scanning() {}
|
||||||
|
|
||||||
fn notify_initial_thread_scan_complete(_partial_scan: bool, _tls: mmtk::util::VMWorkerThread) {}
|
fn notify_initial_thread_scan_complete(partial_scan: bool, tls: mmtk::util::VMWorkerThread) {
|
||||||
|
let _ = partial_scan;
|
||||||
|
let _ = tls;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn forward_weak_refs(
|
||||||
|
_worker: &mut mmtk::scheduler::GCWorker<vmkit::mm::MemoryManager<Self>>,
|
||||||
|
_tracer_context: impl mmtk::vm::ObjectTracerContext<vmkit::mm::MemoryManager<Self>>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
fn scan_roots_in_mutator_thread(
|
fn scan_roots_in_mutator_thread(
|
||||||
_tls: mmtk::util::VMWorkerThread,
|
_tls: mmtk::util::VMWorkerThread,
|
||||||
|
@ -63,105 +102,138 @@ impl VirtualMachine for VM {
|
||||||
>,
|
>,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn forward_weak_refs(
|
|
||||||
_worker: &mut mmtk::scheduler::GCWorker<vmkit::mm::MemoryManager<Self>>,
|
|
||||||
_tracer_context: impl mmtk::vm::ObjectTracerContext<vmkit::mm::MemoryManager<Self>>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VM {
|
fn make_node(
|
||||||
vmkit: VMKit<Self>,
|
thread: &Thread<BenchVM>,
|
||||||
|
left: VMKitObject,
|
||||||
|
right: VMKitObject,
|
||||||
|
i: usize,
|
||||||
|
j: usize,
|
||||||
|
) -> VMKitObject {
|
||||||
|
let node = MemoryManager::allocate(
|
||||||
|
thread,
|
||||||
|
size_of::<Node>(),
|
||||||
|
16,
|
||||||
|
&METADATA,
|
||||||
|
AllocationSemantics::Default,
|
||||||
|
);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
node.set_field_object_no_write_barrier::<BenchVM, false>(offset_of!(Node, left), left);
|
||||||
|
node.set_field_object_no_write_barrier::<BenchVM, false>(offset_of!(Node, right), right);
|
||||||
|
node.set_field_usize::<BenchVM>(offset_of!(Node, i), i);
|
||||||
|
node.set_field_usize::<BenchVM>(offset_of!(Node, j), j);
|
||||||
|
}
|
||||||
|
node
|
||||||
}
|
}
|
||||||
|
|
||||||
static METADATA: GCMetadata<VM> = GCMetadata {
|
fn tree_size(i: usize) -> usize {
|
||||||
instance_size: 48,
|
(1 << (i + 1)) - 1
|
||||||
compute_size: None,
|
|
||||||
trace: Trace::TraceObject(|object, _tracer| {
|
|
||||||
println!("tracing {}", object.as_address());
|
|
||||||
}),
|
|
||||||
alignment: 16,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FooMeta;
|
|
||||||
|
|
||||||
impl Metadata<VM> for FooMeta {
|
|
||||||
const METADATA_BIT_SIZE: usize = 56;
|
|
||||||
fn gc_metadata(&self) -> &'static GCMetadata<VM> {
|
|
||||||
&METADATA
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_object(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_object_reference(_reference: mmtk::util::ObjectReference) -> Self {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_object_reference(&self) -> Option<mmtk::util::ObjectReference> {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToSlot<SimpleSlot> for FooMeta {
|
fn num_iters(stretch_tree_depth: usize, i: usize) -> usize {
|
||||||
fn to_slot(&self) -> Option<SimpleSlot> {
|
4 + tree_size(stretch_tree_depth) / tree_size(i)
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromBitfield<u64> for FooMeta {
|
fn populate(thread: &Thread<BenchVM>, depth: usize, this_node: VMKitObject) {
|
||||||
fn from_bitfield(_bitfield: u64) -> Self {
|
let mut depth = depth;
|
||||||
FooMeta
|
if depth <= 0 {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_i64(_value: i64) -> Self {
|
depth -= 1;
|
||||||
FooMeta
|
this_node.set_field_object::<BenchVM, false>(
|
||||||
}
|
offset_of!(Node, left),
|
||||||
|
make_node(thread, VMKitObject::NULL, VMKitObject::NULL, 0, 0),
|
||||||
|
);
|
||||||
|
let left = this_node.get_field_object::<BenchVM, false>(offset_of!(Node, left));
|
||||||
|
this_node.set_field_object::<BenchVM, false>(
|
||||||
|
offset_of!(Node, right),
|
||||||
|
make_node(thread, VMKitObject::NULL, VMKitObject::NULL, 0, 0),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
populate(
|
||||||
|
thread,
|
||||||
|
depth,
|
||||||
|
this_node.get_field_object::<BenchVM, false>(offset_of!(Node, left)),
|
||||||
|
);
|
||||||
|
populate(
|
||||||
|
thread,
|
||||||
|
depth,
|
||||||
|
this_node.get_field_object::<BenchVM, false>(offset_of!(Node, right)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToBitfield<u64> for FooMeta {
|
fn make_tree(thread: &Thread<BenchVM>, depth: usize) -> VMKitObject {
|
||||||
fn to_bitfield(self) -> u64 {
|
if depth <= 0 {
|
||||||
0
|
return make_node(thread, VMKitObject::NULL, VMKitObject::NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn one() -> Self {
|
let left = make_tree(thread, depth - 1);
|
||||||
FooMeta
|
let right = make_tree(thread, depth - 1);
|
||||||
}
|
make_node(thread, left, right, 0, 0)
|
||||||
|
|
||||||
fn zero() -> Self {
|
|
||||||
FooMeta
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C-unwind" fn handler(signum: libc::c_int) {
|
fn time_construction(thread: &Thread<BenchVM>, stretch_tree_depth: usize, depth: usize) {
|
||||||
println!("signal {signum}");
|
let i_num_iters = num_iters(stretch_tree_depth, depth);
|
||||||
println!("backtrace:\n{}", std::backtrace::Backtrace::force_capture());
|
println!("creating {} trees of depth {}", i_num_iters, depth);
|
||||||
std::process::exit(1);
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
while i < i_num_iters {
|
||||||
|
let temp_tree = make_node(thread, VMKitObject::NULL, VMKitObject::NULL, 0, 0);
|
||||||
|
populate(thread, depth, temp_tree);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let finish = std::time::Instant::now();
|
||||||
|
println!("\tTop down construction took: {:04}ms", finish.duration_since(start).as_micros() as f64 / 1000.0);
|
||||||
|
|
||||||
|
|
||||||
|
let duration = start.elapsed();
|
||||||
|
println!("time_construction: {:?}", duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
env_logger::init();
|
||||||
libc::signal(libc::SIGSEGV, handler as usize);
|
let mut options = MMTKBuilder::new();
|
||||||
|
options.options.plan.set(PlanSelector::StickyImmix);
|
||||||
|
options.options.gc_trigger.set(mmtk::util::options::GCTriggerSelector::DynamicHeapSize(64*1024*1024, 8*1024*1024*1024));
|
||||||
|
let vm = BenchVM {
|
||||||
|
vmkit: VMKit::new(options)
|
||||||
|
};
|
||||||
|
|
||||||
|
VM.set(vm).unwrap_or_else(|_| panic!("Failed to set VM"));
|
||||||
|
|
||||||
|
Thread::<BenchVM>::main(ThreadBenchContext, || {
|
||||||
|
let tls= Thread::<BenchVM>::current();
|
||||||
|
|
||||||
|
let depth = std::env::var("DEPTH").unwrap_or("18".to_string()).parse::<usize>().unwrap();
|
||||||
|
let long_lived_tree_depth = depth;
|
||||||
|
|
||||||
|
let stretch_tree_depth = depth + 1;
|
||||||
|
|
||||||
|
println!("stretching memory with tree of depth: {}", stretch_tree_depth);
|
||||||
|
let start = std::time::Instant::now();
|
||||||
|
make_tree(tls, stretch_tree_depth as _);
|
||||||
|
|
||||||
|
println!("creating long-lived tree of depth: {}", long_lived_tree_depth);
|
||||||
|
let long_lived_tree = make_node(tls, VMKitObject::NULL, VMKitObject::NULL, 0, 0);
|
||||||
|
populate(tls, long_lived_tree_depth as _, long_lived_tree);
|
||||||
|
|
||||||
|
|
||||||
|
let mut d = 4;
|
||||||
|
|
||||||
|
while d <= depth {
|
||||||
|
time_construction(tls, stretch_tree_depth, d);
|
||||||
|
d += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut mmtk = MMTKBuilder::new();
|
let finish = std::time::Instant::now();
|
||||||
mmtk.options.plan.set(PlanSelector::Immix);
|
println!("total execution time: {:04}ms", finish.duration_since(start).as_micros() as f64 / 1000.0);
|
||||||
mmtk.options.threads.set(1);
|
|
||||||
VM_STORAGE.get_or_init(|| VM {
|
|
||||||
vmkit: VMKit::new(mmtk),
|
|
||||||
});
|
|
||||||
|
|
||||||
Thread::<VM>::main(TestContext, || {
|
|
||||||
let tls = Thread::<VM>::current();
|
|
||||||
let my_obj = MemoryManager::allocate(tls, 48, 16, &METADATA, AllocationSemantics::Default);
|
|
||||||
|
|
||||||
println!("Allocated object at {}", my_obj.as_address());
|
|
||||||
|
|
||||||
MemoryManager::<VM>::request_gc();
|
|
||||||
|
|
||||||
println!("object {} at {:p}", my_obj.as_address(), &my_obj);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -73,11 +73,12 @@ impl<VM: VirtualMachine> MemoryManager<VM> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C-unwind" fn allocate(
|
pub extern "C-unwind" fn allocate(
|
||||||
thread: &Thread<VM>,
|
thread: &Thread<VM>,
|
||||||
size: usize,
|
mut size: usize,
|
||||||
alignment: usize,
|
alignment: usize,
|
||||||
metadata: VM::Metadata,
|
metadata: VM::Metadata,
|
||||||
mut semantics: AllocationSemantics,
|
mut semantics: AllocationSemantics,
|
||||||
) -> VMKitObject {
|
) -> VMKitObject {
|
||||||
|
size += size_of::<HeapObjectHeader<VM>>();
|
||||||
if semantics == AllocationSemantics::Default
|
if semantics == AllocationSemantics::Default
|
||||||
&& size >= thread.max_non_los_default_alloc_bytes()
|
&& size >= thread.max_non_los_default_alloc_bytes()
|
||||||
{
|
{
|
||||||
|
@ -103,7 +104,6 @@ impl<VM: VirtualMachine> MemoryManager<VM> {
|
||||||
});
|
});
|
||||||
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
||||||
Self::set_vo_bit(object);
|
Self::set_vo_bit(object);
|
||||||
Self::refill_tlab(thread);
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ pub struct VMKitActivePlan<VM: VirtualMachine>(PhantomData<VM>);
|
||||||
impl<VM: VirtualMachine> ActivePlan<MemoryManager<VM>> for VMKitActivePlan<VM> {
|
impl<VM: VirtualMachine> ActivePlan<MemoryManager<VM>> for VMKitActivePlan<VM> {
|
||||||
|
|
||||||
fn is_mutator(tls: mmtk::util::VMThread) -> bool {
|
fn is_mutator(tls: mmtk::util::VMThread) -> bool {
|
||||||
|
let x = Thread::<VM>::from_vm_thread(tls);
|
||||||
Thread::<VM>::from_vm_thread(tls).active_mutator_context()
|
Thread::<VM>::from_vm_thread(tls).active_mutator_context()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ fn is_address_maybe_unmapped(addr: Address, size: usize) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aslr_vm_layout(mmtk_options: &mut Options) -> VMLayout {
|
pub fn aslr_vm_layout(mmtk_options: &mut Options) -> VMLayout {
|
||||||
let mut vm_layout = VMLayout::default();
|
/*let mut vm_layout = VMLayout::default();
|
||||||
let options = &*OPTIONS;
|
let options = &*OPTIONS;
|
||||||
|
|
||||||
if options.compressed_pointers {
|
if options.compressed_pointers {
|
||||||
|
@ -89,7 +89,9 @@ pub fn aslr_vm_layout(mmtk_options: &mut Options) -> VMLayout {
|
||||||
options.max_heap_size,
|
options.max_heap_size,
|
||||||
));
|
));
|
||||||
|
|
||||||
vm_layout
|
vm_layout*/
|
||||||
|
|
||||||
|
VMLayout::default()
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::marker::PhantomData;
|
||||||
use crate::{
|
use crate::{
|
||||||
mm::MemoryManager,
|
mm::MemoryManager,
|
||||||
object_model::{
|
object_model::{
|
||||||
metadata::{Metadata, Trace},
|
metadata::{Metadata, TraceCallback},
|
||||||
object::VMKitObject,
|
object::VMKitObject,
|
||||||
},
|
},
|
||||||
options::OPTIONS,
|
options::OPTIONS,
|
||||||
|
@ -57,11 +57,11 @@ impl<VM: VirtualMachine> Scanning<MemoryManager<VM>> for VMKitScanning<VM> {
|
||||||
let gc_metadata = metadata.gc_metadata();
|
let gc_metadata = metadata.gc_metadata();
|
||||||
let trace = &gc_metadata.trace;
|
let trace = &gc_metadata.trace;
|
||||||
match trace {
|
match trace {
|
||||||
Trace::ScanSlots(fun) => {
|
TraceCallback::ScanSlots(fun) => {
|
||||||
fun(object, slot_visitor);
|
fun(object, slot_visitor);
|
||||||
}
|
}
|
||||||
Trace::None => (),
|
TraceCallback::None => (),
|
||||||
Trace::TraceObject(_) => {
|
TraceCallback::TraceObject(_) => {
|
||||||
unreachable!("TraceObject is not supported for scanning");
|
unreachable!("TraceObject is not supported for scanning");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ impl<VM: VirtualMachine> Scanning<MemoryManager<VM>> for VMKitScanning<VM> {
|
||||||
let gc_metadata = metadata.gc_metadata();
|
let gc_metadata = metadata.gc_metadata();
|
||||||
let trace = &gc_metadata.trace;
|
let trace = &gc_metadata.trace;
|
||||||
match trace {
|
match trace {
|
||||||
Trace::ScanSlots(fun) => {
|
TraceCallback::ScanSlots(fun) => {
|
||||||
// wrap object tracer in a trait that implements SlotVisitor
|
// wrap object tracer in a trait that implements SlotVisitor
|
||||||
// but actually traces the object directly.
|
// but actually traces the object directly.
|
||||||
let mut visitor = TraceSlotVisitor::<VM, OT> {
|
let mut visitor = TraceSlotVisitor::<VM, OT> {
|
||||||
|
@ -86,8 +86,8 @@ impl<VM: VirtualMachine> Scanning<MemoryManager<VM>> for VMKitScanning<VM> {
|
||||||
};
|
};
|
||||||
fun(object, &mut visitor);
|
fun(object, &mut visitor);
|
||||||
}
|
}
|
||||||
Trace::None => (),
|
TraceCallback::None => (),
|
||||||
Trace::TraceObject(fun) => {
|
TraceCallback::TraceObject(fun) => {
|
||||||
fun(object, object_tracer);
|
fun(object, object_tracer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ impl<VM: VirtualMachine> Scanning<MemoryManager<VM>> for VMKitScanning<VM> {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let object = VMKitObject::from(object);
|
let object = VMKitObject::from(object);
|
||||||
let metadata = object.header::<VM>().metadata();
|
let metadata = object.header::<VM>().metadata();
|
||||||
matches!(metadata.gc_metadata().trace, Trace::ScanSlots(_))
|
matches!(metadata.gc_metadata().trace, TraceCallback::ScanSlots(_))
|
||||||
&& (!metadata.is_object() || metadata.to_slot().is_some())
|
&& (!metadata.is_object() || metadata.to_slot().is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,9 @@ impl TLAB {
|
||||||
let aligned_size = raw_align_up(size, alignment);
|
let aligned_size = raw_align_up(size, alignment);
|
||||||
let result = self.cursor.align_up(alignment);
|
let result = self.cursor.align_up(alignment);
|
||||||
if result + aligned_size > self.limit {
|
if result + aligned_size > self.limit {
|
||||||
|
|
||||||
return Address::ZERO;
|
return Address::ZERO;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
self.cursor = result.add(aligned_size);
|
self.cursor = result.add(aligned_size);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,15 +24,15 @@ pub trait ToSlot<SL: Slot> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Trace {
|
pub trait Trace {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer);
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Scan<SL: Slot> {
|
pub trait Scan<SL: Slot> {
|
||||||
fn scan_object(&self, visitor: &mut impl SlotVisitor<SL>);
|
fn scan_object(&self, visitor: &mut dyn SlotVisitor<SL>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Trace for VMKitObject {
|
impl Trace for VMKitObject {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer) {
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) {
|
||||||
if self.is_null() {
|
if self.is_null() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ impl Trace for VMKitObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Trace, VM: VirtualMachine> Trace for InternalPointer<T, VM> {
|
impl<T: Trace, VM: VirtualMachine> Trace for InternalPointer<T, VM> {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer) {
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) {
|
||||||
#[cfg(feature = "cooperative")]
|
#[cfg(feature = "cooperative")]
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -72,7 +72,7 @@ impl<T: Trace, VM: VirtualMachine> Trace for InternalPointer<T, VM> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SL: Slot + SlotExtra> Scan<SL> for VMKitObject {
|
impl<SL: Slot + SlotExtra> Scan<SL> for VMKitObject {
|
||||||
fn scan_object(&self, visitor: &mut impl SlotVisitor<SL>) {
|
fn scan_object(&self, visitor: &mut dyn SlotVisitor<SL>) {
|
||||||
if let Some(slot) = self.to_slot() {
|
if let Some(slot) = self.to_slot() {
|
||||||
visitor.visit_slot(slot);
|
visitor.visit_slot(slot);
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ macro_rules! impl_prim {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SL: Slot> Scan<SL> for $t {
|
impl<SL: Slot> Scan<SL> for $t {
|
||||||
fn scan_object(&self, visitor: &mut impl SlotVisitor<SL>) {
|
fn scan_object(&self, visitor: &mut dyn SlotVisitor<SL>) {
|
||||||
let _ = visitor;
|
let _ = visitor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ macro_rules! impl_prim {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Trace for $t {
|
impl Trace for $t {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer) {
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) {
|
||||||
let _ = tracer;
|
let _ = tracer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ impl<T: SupportsEnqueuing, U: SupportsEnqueuing> SupportsEnqueuing for Result<T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Trace> Trace for Option<T> {
|
impl<T: Trace> Trace for Option<T> {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer) {
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) {
|
||||||
if let Some(value) = self {
|
if let Some(value) = self {
|
||||||
value.trace_object(tracer);
|
value.trace_object(tracer);
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ impl<T: Trace> Trace for Option<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Trace> Trace for Vec<T> {
|
impl<T: Trace> Trace for Vec<T> {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer) {
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) {
|
||||||
for value in self {
|
for value in self {
|
||||||
value.trace_object(tracer);
|
value.trace_object(tracer);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ impl<T: Trace> Trace for Vec<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Trace, const N: usize> Trace for [T; N] {
|
impl<T: Trace, const N: usize> Trace for [T; N] {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer) {
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) {
|
||||||
for value in self {
|
for value in self {
|
||||||
value.trace_object(tracer);
|
value.trace_object(tracer);
|
||||||
}
|
}
|
||||||
|
@ -234,13 +234,13 @@ impl<T: Trace, const N: usize> Trace for [T; N] {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Trace> Trace for Box<T> {
|
impl<T: Trace> Trace for Box<T> {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer) {
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) {
|
||||||
(**self).trace_object(tracer);
|
(**self).trace_object(tracer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SL: Slot, T: Scan<SL>> Scan<SL> for Vec<T> {
|
impl<SL: Slot, T: Scan<SL>> Scan<SL> for Vec<T> {
|
||||||
fn scan_object(&self, visitor: &mut impl SlotVisitor<SL>) {
|
fn scan_object(&self, visitor: &mut dyn SlotVisitor<SL>) {
|
||||||
for value in self {
|
for value in self {
|
||||||
value.scan_object(visitor);
|
value.scan_object(visitor);
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ impl<SL: Slot, T: Scan<SL>> Scan<SL> for Vec<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SL: Slot, T: Scan<SL>, const N: usize> Scan<SL> for [T; N] {
|
impl<SL: Slot, T: Scan<SL>, const N: usize> Scan<SL> for [T; N] {
|
||||||
fn scan_object(&self, visitor: &mut impl SlotVisitor<SL>) {
|
fn scan_object(&self, visitor: &mut dyn SlotVisitor<SL>) {
|
||||||
for value in self {
|
for value in self {
|
||||||
value.scan_object(visitor);
|
value.scan_object(visitor);
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ impl<T, VM: VirtualMachine> SupportsEnqueuing for FatInternalPointer<T, VM> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, VM: VirtualMachine, SL: Slot + SlotExtra> Scan<SL> for FatInternalPointer<T, VM> {
|
impl<T, VM: VirtualMachine, SL: Slot + SlotExtra> Scan<SL> for FatInternalPointer<T, VM> {
|
||||||
fn scan_object(&self, visitor: &mut impl SlotVisitor<SL>) {
|
fn scan_object(&self, visitor: &mut dyn SlotVisitor<SL>) {
|
||||||
visitor.visit_slot(self.object().to_slot().expect("never fails"));
|
visitor.visit_slot(self.object().to_slot().expect("never fails"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,14 +272,14 @@ impl<T, VM: VirtualMachine, SL: Slot + SlotExtra> ToSlot<SL> for FatInternalPoin
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, VM: VirtualMachine> Trace for FatInternalPointer<T, VM> {
|
impl<T, VM: VirtualMachine> Trace for FatInternalPointer<T, VM> {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer) {
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) {
|
||||||
self.object().trace_object(tracer);
|
self.object().trace_object(tracer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Trace for VMKitNarrow {
|
impl Trace for VMKitNarrow {
|
||||||
fn trace_object(&mut self, tracer: &mut impl ObjectTracer) {
|
fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) {
|
||||||
let mut object = self.to_object();
|
let mut object = self.to_object();
|
||||||
object.trace_object(tracer);
|
object.trace_object(tracer);
|
||||||
*self = VMKitNarrow::encode(object);
|
*self = VMKitNarrow::encode(object);
|
||||||
|
@ -287,7 +287,7 @@ impl Trace for VMKitNarrow {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SL: SlotExtra> Scan<SL> for VMKitNarrow {
|
impl<SL: SlotExtra> Scan<SL> for VMKitNarrow {
|
||||||
fn scan_object(&self, visitor: &mut impl SlotVisitor<SL>) {
|
fn scan_object(&self, visitor: &mut dyn SlotVisitor<SL>) {
|
||||||
let slot = SL::from_narrow(self);
|
let slot = SL::from_narrow(self);
|
||||||
visitor.visit_slot(slot);
|
visitor.visit_slot(slot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,7 @@ impl<VM: VirtualMachine> ObjectModel<MemoryManager<VM>> for VMKitObjectModel<VM>
|
||||||
}
|
}
|
||||||
impl<VM: VirtualMachine> VMKitObjectModel<VM> {
|
impl<VM: VirtualMachine> VMKitObjectModel<VM> {
|
||||||
fn move_object(from_obj: VMKitObject, mut to: MoveTarget, num_bytes: usize) -> VMKitObject {
|
fn move_object(from_obj: VMKitObject, mut to: MoveTarget, num_bytes: usize) -> VMKitObject {
|
||||||
|
log::trace!("move_object: from_obj: {}, to: {}", from_obj.as_address(), to);
|
||||||
let mut copy_bytes = num_bytes;
|
let mut copy_bytes = num_bytes;
|
||||||
let mut obj_ref_offset = OBJECT_REF_OFFSET;
|
let mut obj_ref_offset = OBJECT_REF_OFFSET;
|
||||||
let hash_state = from_obj.header::<VM>().hash_state();
|
let hash_state = from_obj.header::<VM>().hash_state();
|
||||||
|
|
|
@ -10,14 +10,14 @@ use super::object::VMKitObject;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct GCMetadata<VM: VirtualMachine> {
|
pub struct GCMetadata<VM: VirtualMachine> {
|
||||||
pub trace: Trace<VM>,
|
pub trace: TraceCallback<VM>,
|
||||||
pub instance_size: usize,
|
pub instance_size: usize,
|
||||||
pub compute_size: Option<fn(VMKitObject) -> usize>,
|
pub compute_size: Option<fn(VMKitObject) -> usize>,
|
||||||
pub alignment: usize,
|
pub alignment: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Trace<VM: VirtualMachine> {
|
pub enum TraceCallback<VM: VirtualMachine> {
|
||||||
ScanSlots(fn(VMKitObject, &mut dyn SlotVisitor<VM::Slot>)),
|
ScanSlots(fn(VMKitObject, &mut dyn SlotVisitor<VM::Slot>)),
|
||||||
TraceObject(fn(VMKitObject, &mut dyn ObjectTracer)),
|
TraceObject(fn(VMKitObject, &mut dyn ObjectTracer)),
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use crate::mm::traits::SlotExtra;
|
use crate::mm::traits::SlotExtra;
|
||||||
use crate::threading::Thread;
|
use crate::threading::Thread;
|
||||||
use crate::{mm::MemoryManager, VirtualMachine};
|
use crate::{mm::MemoryManager, VirtualMachine};
|
||||||
|
@ -514,6 +516,15 @@ pub enum MoveTarget {
|
||||||
ToObject(VMKitObject),
|
ToObject(VMKitObject),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for MoveTarget {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
MoveTarget::ToAddress(addr) => write!(f, "ToAddress({})", addr),
|
||||||
|
MoveTarget::ToObject(obj) => write!(f, "ToObject({})", obj.as_address()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Narrow pointer to an object. This is used when pointer compression
|
/// Narrow pointer to an object. This is used when pointer compression
|
||||||
/// is enabled.
|
/// is enabled.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct Options {
|
||||||
#[clap(long, default_value_t = 1024)]
|
#[clap(long, default_value_t = 1024)]
|
||||||
pub interior_pointer_max_bytes: usize,
|
pub interior_pointer_max_bytes: usize,
|
||||||
|
|
||||||
#[clap(long, default_value_t = true)]
|
#[clap(long, default_value_t = false)]
|
||||||
pub aslr: bool,
|
pub aslr: bool,
|
||||||
|
|
||||||
#[clap(long, default_value_t = true)]
|
#[clap(long, default_value_t = true)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue