├── .gitattributes ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── ci ├── build.sh ├── build_and_package.sh ├── check_if_nightly.sh ├── docker │ ├── Dockerfile.hybrid │ ├── run-interactive.sh │ ├── run.sh │ └── static │ │ ├── cargo.config │ │ ├── run-if-enabled │ │ └── runner ├── package.sh ├── run_cross_tests.sh └── run_tests.sh ├── cli-core ├── Cargo.toml └── src │ ├── cmd_analyze_size.rs │ ├── cmd_extract.rs │ ├── cmd_gather.rs │ ├── data.rs │ ├── exporter_flamegraph.rs │ ├── exporter_flamegraph_pl.rs │ ├── exporter_heaptrack.rs │ ├── exporter_replay.rs │ ├── filter.rs │ ├── frame.rs │ ├── io_adapter.rs │ ├── lib.rs │ ├── loader.rs │ ├── postprocessor.rs │ ├── reader.rs │ ├── repack.rs │ ├── script.rs │ ├── script_virtual.rs │ ├── squeeze.rs │ ├── threaded_lz4_stream.rs │ ├── timeline.rs │ ├── tree.rs │ ├── tree_printer.rs │ ├── util.rs │ └── vecvec.rs ├── cli ├── Cargo.toml └── src │ └── main.rs ├── common ├── Cargo.toml └── src │ ├── event.rs │ ├── lib.rs │ ├── lz4_stream.rs │ ├── os_util.rs │ ├── request.rs │ └── timestamp.rs ├── docs ├── .gitignore ├── book.toml ├── build-for-deploy.sh ├── custom.css ├── plugins │ └── run-inline-snippets.rb └── src │ ├── SUMMARY.md │ ├── api_reference.md │ ├── api_reference │ ├── Allocation.md │ ├── Allocation │ │ ├── allocated_at.md │ │ ├── backtrace.md │ │ └── deallocated_at.md │ ├── AllocationGroupList.md │ ├── AllocationGroupList │ │ ├── len.md │ │ ├── only_all_leaked.md │ │ ├── only_count_at_least.md │ │ ├── op_iterator.md │ │ ├── op_square_brackets.md │ │ ├── sort_by_count.md │ │ ├── sort_by_count_ascending.md │ │ ├── sort_by_count_descending.md │ │ ├── sort_by_size.md │ │ ├── sort_by_size_ascending.md │ │ ├── sort_by_size_descending.md │ │ ├── take.md │ │ └── ungroup.md │ ├── AllocationList.md │ ├── AllocationList │ │ ├── group_by_backtrace.md │ │ ├── len.md │ │ ├── only_address_at_least.md │ │ ├── only_address_at_most.md │ │ ├── only_alive_at.md │ │ ├── only_alive_for_at_least.md │ │ ├── only_alive_for_at_most.md │ │ ├── only_allocated_after_at_least.md │ │ ├── only_allocated_until_at_most.md │ │ ├── only_backtrace_length_at_least.md │ │ ├── only_backtrace_length_at_most.md │ │ ├── only_chain_alive_for_at_least.md │ │ ├── only_chain_alive_for_at_most.md │ │ ├── only_chain_leaked.md │ │ ├── only_chain_length_at_least.md │ │ ├── only_chain_length_at_most.md │ │ ├── only_deallocated_after_at_least.md │ │ ├── only_deallocated_until_at_most.md │ │ ├── only_first_size_larger.md │ │ ├── only_first_size_larger_or_equal.md │ │ ├── only_first_size_smaller.md │ │ ├── only_first_size_smaller_or_equal.md │ │ ├── only_from_maps.md │ │ ├── only_group_allocations_at_least.md │ │ ├── only_group_allocations_at_most.md │ │ ├── only_group_interval_at_least.md │ │ ├── only_group_interval_at_most.md │ │ ├── only_group_leaked_allocations_at_least.md │ │ ├── only_group_leaked_allocations_at_most.md │ │ ├── only_group_max_total_usage_first_seen_at_least.md │ │ ├── only_group_max_total_usage_first_seen_at_most.md │ │ ├── only_jemalloc.md │ │ ├── only_larger.md │ │ ├── only_larger_or_equal.md │ │ ├── only_last_size_larger.md │ │ ├── only_last_size_larger_or_equal.md │ │ ├── only_last_size_smaller.md │ │ ├── only_last_size_smaller_or_equal.md │ │ ├── only_leaked.md │ │ ├── only_leaked_or_deallocated_after.md │ │ ├── only_matching_backtraces.md │ │ ├── only_matching_deallocation_backtraces.md │ │ ├── only_not_jemalloc.md │ │ ├── only_not_matching_backtraces.md │ │ ├── only_not_matching_deallocation_backtraces.md │ │ ├── only_not_passing_through_function.md │ │ ├── only_not_passing_through_source.md │ │ ├── only_passing_through_function.md │ │ ├── only_passing_through_source.md │ │ ├── only_position_in_chain_at_least.md │ │ ├── only_position_in_chain_at_most.md │ │ ├── only_ptmalloc_from_main_arena.md │ │ ├── only_ptmalloc_mmaped.md │ │ ├── only_ptmalloc_not_from_main_arena.md │ │ ├── only_ptmalloc_not_mmaped.md │ │ ├── only_smaller.md │ │ ├── only_smaller_or_equal.md │ │ ├── only_temporary.md │ │ ├── op_and.md │ │ ├── op_minus.md │ │ ├── op_plus.md │ │ ├── op_square_brackets.md │ │ ├── save_as_flamegraph.md │ │ └── save_as_graph.md │ ├── Backtrace.md │ ├── Backtrace │ │ └── strip.md │ ├── Data.md │ ├── Data │ │ ├── allocations.md │ │ └── runtime.md │ ├── Duration.md │ ├── Duration │ │ ├── op_minus.md │ │ ├── op_multiply.md │ │ └── op_plus.md │ ├── Graph.md │ ├── Graph │ │ ├── add.md │ │ ├── end_at.md │ │ ├── only_non_empty_series.md │ │ ├── save.md │ │ ├── save_each_series_as_flamegraph.md │ │ ├── save_each_series_as_graph.md │ │ ├── show_address_space.md │ │ ├── show_deallocations.md │ │ ├── show_live_allocations.md │ │ ├── show_memory_usage.md │ │ ├── show_new_allocations.md │ │ ├── show_rss.md │ │ ├── start_at.md │ │ ├── trim.md │ │ ├── trim_left.md │ │ ├── trim_right.md │ │ ├── with_gradient_color_scheme.md │ │ ├── without_axes.md │ │ ├── without_grid.md │ │ └── without_legend.md │ ├── Map.md │ ├── Map │ │ ├── allocated_at.md │ │ ├── backtrace.md │ │ └── deallocated_at.md │ ├── MapList.md │ ├── MapList │ │ ├── len.md │ │ ├── only_address_at_least.md │ │ ├── only_address_at_most.md │ │ ├── only_alive_at.md │ │ ├── only_alive_for_at_least.md │ │ ├── only_alive_for_at_most.md │ │ ├── only_allocated_after_at_least.md │ │ ├── only_allocated_until_at_most.md │ │ ├── only_backtrace_length_at_least.md │ │ ├── only_backtrace_length_at_most.md │ │ ├── only_bytehound.md │ │ ├── only_deallocated_after_at_least.md │ │ ├── only_deallocated_until_at_most.md │ │ ├── only_executable.md │ │ ├── only_jemalloc.md │ │ ├── only_larger.md │ │ ├── only_larger_or_equal.md │ │ ├── only_leaked.md │ │ ├── only_leaked_or_deallocated_after.md │ │ ├── only_matching_backtraces.md │ │ ├── only_matching_deallocation_backtraces.md │ │ ├── only_not_bytehound.md │ │ ├── only_not_executable.md │ │ ├── only_not_jemalloc.md │ │ ├── only_not_matching_backtraces.md │ │ ├── only_not_matching_deallocation_backtraces.md │ │ ├── only_not_passing_through_function.md │ │ ├── only_not_passing_through_source.md │ │ ├── only_not_readable.md │ │ ├── only_not_writable.md │ │ ├── only_passing_through_function.md │ │ ├── only_passing_through_source.md │ │ ├── only_peak_rss_at_least.md │ │ ├── only_peak_rss_at_most.md │ │ ├── only_readable.md │ │ ├── only_smaller.md │ │ ├── only_smaller_or_equal.md │ │ ├── only_temporary.md │ │ ├── only_writable.md │ │ ├── op_and.md │ │ ├── op_minus.md │ │ ├── op_plus.md │ │ └── op_square_brackets.md │ ├── globals.md │ └── globals │ │ ├── allocations.md │ │ ├── argv.md │ │ ├── chdir.md │ │ ├── data.md │ │ ├── dirname.md │ │ ├── exit.md │ │ ├── gb.md │ │ ├── graph.md │ │ ├── h.md │ │ ├── info.md │ │ ├── kb.md │ │ ├── load.md │ │ ├── m.md │ │ ├── maps.md │ │ ├── mb.md │ │ ├── mkdir_p.md │ │ ├── ms.md │ │ ├── println.md │ │ ├── s.md │ │ └── us.md │ ├── common_issues.md │ ├── configuration.md │ ├── getting_started.md │ ├── introduction.md │ └── memory_leak_analysis.md ├── fast_range_map ├── Cargo.toml ├── benches │ └── rangemaps.rs ├── fuzz │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── fuzz_targets │ │ ├── fuzz_insert.rs │ │ └── fuzz_remove.rs └── src │ └── lib.rs ├── gather ├── Cargo.toml └── src │ └── main.rs ├── integration-tests ├── Cargo.toml ├── build.rs ├── src │ ├── lib.rs │ ├── tests.rs │ └── utils.rs └── test-programs │ ├── alloc-in-tls.cpp │ ├── backtrace.c │ ├── basic.c │ ├── cross-thread-alloc.c │ ├── cull.c │ ├── dlopen.c │ ├── dlopen_so.c │ ├── exit_1.c │ ├── exit_2.c │ ├── exit_3.c │ ├── fork.c │ ├── gather.c │ ├── jemalloc │ ├── Cargo.toml │ ├── jemalloc-common │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── jemalloc-v03 │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── jemalloc-v05-unprefixed │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ └── jemalloc-v05 │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs │ ├── longjmp.c │ ├── mmap.c │ ├── return-f64.rs │ ├── return-opt-u128.rs │ ├── spawn-child.c │ ├── start-stop.c │ ├── throw.cpp │ └── wasmtime │ ├── Cargo.lock │ ├── Cargo.toml │ ├── interrupt │ ├── Cargo.toml │ └── src │ │ ├── interrupt.wat │ │ └── main.rs │ └── linking │ ├── Cargo.toml │ └── src │ ├── linking1.wat │ ├── linking2.wat │ └── main.rs ├── jemallocator ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── benches │ └── roundtrip.rs ├── ci │ ├── dox.sh │ └── run.sh ├── jemalloc-ctl │ ├── Cargo.toml │ ├── LICENSE-APACHE │ ├── LICENSE-MIT │ ├── README.md │ ├── rustfmt.toml │ └── src │ │ ├── arenas.rs │ │ ├── config.rs │ │ ├── error.rs │ │ ├── keys.rs │ │ ├── lib.rs │ │ ├── macros.rs │ │ ├── opt.rs │ │ ├── raw.rs │ │ ├── stats.rs │ │ ├── stats_print.rs │ │ └── thread.rs ├── jemalloc-sys │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── configure │ │ ├── VERSION │ │ └── configure │ ├── jemalloc │ │ ├── .appveyor.yml │ │ ├── .autom4te.cfg │ │ ├── .cirrus.yml │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── COPYING │ │ ├── ChangeLog │ │ ├── INSTALL.md │ │ ├── Makefile.in │ │ ├── README │ │ ├── TUNING.md │ │ ├── autogen.sh │ │ ├── bin │ │ │ ├── jemalloc-config.in │ │ │ ├── jemalloc.sh.in │ │ │ └── jeprof.in │ │ ├── build-aux │ │ │ ├── config.guess │ │ │ ├── config.sub │ │ │ └── install-sh │ │ ├── config.stamp.in │ │ ├── configure.ac │ │ ├── doc │ │ │ ├── html.xsl.in │ │ │ ├── jemalloc.xml.in │ │ │ ├── manpages.xsl.in │ │ │ └── stylesheet.xsl │ │ ├── include │ │ │ ├── jemalloc │ │ │ │ ├── internal │ │ │ │ │ ├── arena_externs.h │ │ │ │ │ ├── arena_inlines_a.h │ │ │ │ │ ├── arena_inlines_b.h │ │ │ │ │ ├── arena_stats.h │ │ │ │ │ ├── arena_structs_a.h │ │ │ │ │ ├── arena_structs_b.h │ │ │ │ │ ├── arena_types.h │ │ │ │ │ ├── assert.h │ │ │ │ │ ├── atomic.h │ │ │ │ │ ├── atomic_c11.h │ │ │ │ │ ├── atomic_gcc_atomic.h │ │ │ │ │ ├── atomic_gcc_sync.h │ │ │ │ │ ├── atomic_msvc.h │ │ │ │ │ ├── background_thread_externs.h │ │ │ │ │ ├── background_thread_inlines.h │ │ │ │ │ ├── background_thread_structs.h │ │ │ │ │ ├── base_externs.h │ │ │ │ │ ├── base_inlines.h │ │ │ │ │ ├── base_structs.h │ │ │ │ │ ├── base_types.h │ │ │ │ │ ├── bin.h │ │ │ │ │ ├── bin_stats.h │ │ │ │ │ ├── bin_types.h │ │ │ │ │ ├── bit_util.h │ │ │ │ │ ├── bitmap.h │ │ │ │ │ ├── cache_bin.h │ │ │ │ │ ├── ckh.h │ │ │ │ │ ├── ctl.h │ │ │ │ │ ├── div.h │ │ │ │ │ ├── emitter.h │ │ │ │ │ ├── extent_dss.h │ │ │ │ │ ├── extent_externs.h │ │ │ │ │ ├── extent_inlines.h │ │ │ │ │ ├── extent_mmap.h │ │ │ │ │ ├── extent_structs.h │ │ │ │ │ ├── extent_types.h │ │ │ │ │ ├── hash.h │ │ │ │ │ ├── hook.h │ │ │ │ │ ├── jemalloc_internal_decls.h │ │ │ │ │ ├── jemalloc_internal_defs.h.in │ │ │ │ │ ├── jemalloc_internal_externs.h │ │ │ │ │ ├── jemalloc_internal_includes.h │ │ │ │ │ ├── jemalloc_internal_inlines_a.h │ │ │ │ │ ├── jemalloc_internal_inlines_b.h │ │ │ │ │ ├── jemalloc_internal_inlines_c.h │ │ │ │ │ ├── jemalloc_internal_macros.h │ │ │ │ │ ├── jemalloc_internal_types.h │ │ │ │ │ ├── jemalloc_preamble.h.in │ │ │ │ │ ├── large_externs.h │ │ │ │ │ ├── log.h │ │ │ │ │ ├── malloc_io.h │ │ │ │ │ ├── mutex.h │ │ │ │ │ ├── mutex_pool.h │ │ │ │ │ ├── mutex_prof.h │ │ │ │ │ ├── nstime.h │ │ │ │ │ ├── pages.h │ │ │ │ │ ├── ph.h │ │ │ │ │ ├── private_namespace.sh │ │ │ │ │ ├── private_symbols.sh │ │ │ │ │ ├── prng.h │ │ │ │ │ ├── prof_externs.h │ │ │ │ │ ├── prof_inlines_a.h │ │ │ │ │ ├── prof_inlines_b.h │ │ │ │ │ ├── prof_structs.h │ │ │ │ │ ├── prof_types.h │ │ │ │ │ ├── public_namespace.sh │ │ │ │ │ ├── public_unnamespace.sh │ │ │ │ │ ├── ql.h │ │ │ │ │ ├── qr.h │ │ │ │ │ ├── quantum.h │ │ │ │ │ ├── rb.h │ │ │ │ │ ├── rtree.h │ │ │ │ │ ├── rtree_tsd.h │ │ │ │ │ ├── safety_check.h │ │ │ │ │ ├── sc.h │ │ │ │ │ ├── seq.h │ │ │ │ │ ├── smoothstep.h │ │ │ │ │ ├── smoothstep.sh │ │ │ │ │ ├── spin.h │ │ │ │ │ ├── stats.h │ │ │ │ │ ├── sz.h │ │ │ │ │ ├── tcache_externs.h │ │ │ │ │ ├── tcache_inlines.h │ │ │ │ │ ├── tcache_structs.h │ │ │ │ │ ├── tcache_types.h │ │ │ │ │ ├── test_hooks.h │ │ │ │ │ ├── ticker.h │ │ │ │ │ ├── tsd.h │ │ │ │ │ ├── tsd_generic.h │ │ │ │ │ ├── tsd_malloc_thread_cleanup.h │ │ │ │ │ ├── tsd_tls.h │ │ │ │ │ ├── tsd_types.h │ │ │ │ │ ├── tsd_win.h │ │ │ │ │ ├── util.h │ │ │ │ │ └── witness.h │ │ │ │ ├── jemalloc.sh │ │ │ │ ├── jemalloc_defs.h.in │ │ │ │ ├── jemalloc_macros.h.in │ │ │ │ ├── jemalloc_mangle.sh │ │ │ │ ├── jemalloc_protos.h.in │ │ │ │ ├── jemalloc_rename.sh │ │ │ │ └── jemalloc_typedefs.h.in │ │ │ └── msvc_compat │ │ │ │ ├── C99 │ │ │ │ ├── stdbool.h │ │ │ │ └── stdint.h │ │ │ │ ├── strings.h │ │ │ │ └── windows_extra.h │ │ ├── jemalloc.pc.in │ │ ├── m4 │ │ │ └── ax_cxx_compile_stdcxx.m4 │ │ ├── msvc │ │ │ ├── ReadMe.txt │ │ │ ├── jemalloc_vc2015.sln │ │ │ ├── jemalloc_vc2017.sln │ │ │ ├── projects │ │ │ │ ├── vc2015 │ │ │ │ │ ├── jemalloc │ │ │ │ │ │ ├── jemalloc.vcxproj │ │ │ │ │ │ └── jemalloc.vcxproj.filters │ │ │ │ │ └── test_threads │ │ │ │ │ │ ├── test_threads.vcxproj │ │ │ │ │ │ └── test_threads.vcxproj.filters │ │ │ │ └── vc2017 │ │ │ │ │ ├── jemalloc │ │ │ │ │ ├── jemalloc.vcxproj │ │ │ │ │ └── jemalloc.vcxproj.filters │ │ │ │ │ └── test_threads │ │ │ │ │ ├── test_threads.vcxproj │ │ │ │ │ └── test_threads.vcxproj.filters │ │ │ └── test_threads │ │ │ │ ├── test_threads.cpp │ │ │ │ ├── test_threads.h │ │ │ │ └── test_threads_main.cpp │ │ ├── run_tests.sh │ │ ├── scripts │ │ │ ├── gen_run_tests.py │ │ │ └── gen_travis.py │ │ ├── src │ │ │ ├── arena.c │ │ │ ├── background_thread.c │ │ │ ├── base.c │ │ │ ├── bin.c │ │ │ ├── bitmap.c │ │ │ ├── ckh.c │ │ │ ├── ctl.c │ │ │ ├── div.c │ │ │ ├── extent.c │ │ │ ├── extent_dss.c │ │ │ ├── extent_mmap.c │ │ │ ├── hash.c │ │ │ ├── hook.c │ │ │ ├── jemalloc.c │ │ │ ├── jemalloc_cpp.cpp │ │ │ ├── large.c │ │ │ ├── log.c │ │ │ ├── malloc_io.c │ │ │ ├── mutex.c │ │ │ ├── mutex_pool.c │ │ │ ├── nstime.c │ │ │ ├── pages.c │ │ │ ├── prng.c │ │ │ ├── prof.c │ │ │ ├── rtree.c │ │ │ ├── safety_check.c │ │ │ ├── sc.c │ │ │ ├── stats.c │ │ │ ├── sz.c │ │ │ ├── tcache.c │ │ │ ├── test_hooks.c │ │ │ ├── ticker.c │ │ │ ├── tsd.c │ │ │ ├── witness.c │ │ │ └── zone.c │ │ └── test │ │ │ ├── include │ │ │ └── test │ │ │ │ ├── SFMT-alti.h │ │ │ │ ├── SFMT-params.h │ │ │ │ ├── SFMT-params11213.h │ │ │ │ ├── SFMT-params1279.h │ │ │ │ ├── SFMT-params132049.h │ │ │ │ ├── SFMT-params19937.h │ │ │ │ ├── SFMT-params216091.h │ │ │ │ ├── SFMT-params2281.h │ │ │ │ ├── SFMT-params4253.h │ │ │ │ ├── SFMT-params44497.h │ │ │ │ ├── SFMT-params607.h │ │ │ │ ├── SFMT-params86243.h │ │ │ │ ├── SFMT-sse2.h │ │ │ │ ├── SFMT.h │ │ │ │ ├── btalloc.h │ │ │ │ ├── extent_hooks.h │ │ │ │ ├── jemalloc_test.h.in │ │ │ │ ├── jemalloc_test_defs.h.in │ │ │ │ ├── math.h │ │ │ │ ├── mq.h │ │ │ │ ├── mtx.h │ │ │ │ ├── test.h │ │ │ │ ├── thd.h │ │ │ │ └── timer.h │ │ │ ├── integration │ │ │ ├── MALLOCX_ARENA.c │ │ │ ├── aligned_alloc.c │ │ │ ├── allocated.c │ │ │ ├── extent.c │ │ │ ├── extent.sh │ │ │ ├── malloc.c │ │ │ ├── mallocx.c │ │ │ ├── mallocx.sh │ │ │ ├── overflow.c │ │ │ ├── posix_memalign.c │ │ │ ├── rallocx.c │ │ │ ├── sdallocx.c │ │ │ ├── slab_sizes.c │ │ │ ├── slab_sizes.sh │ │ │ ├── smallocx.c │ │ │ ├── smallocx.sh │ │ │ ├── thread_arena.c │ │ │ ├── thread_tcache_enabled.c │ │ │ ├── xallocx.c │ │ │ └── xallocx.sh │ │ │ ├── src │ │ │ ├── SFMT.c │ │ │ ├── btalloc.c │ │ │ ├── btalloc_0.c │ │ │ ├── btalloc_1.c │ │ │ ├── math.c │ │ │ ├── mq.c │ │ │ ├── mtx.c │ │ │ ├── test.c │ │ │ ├── thd.c │ │ │ └── timer.c │ │ │ ├── stress │ │ │ ├── hookbench.c │ │ │ └── microbench.c │ │ │ ├── test.sh.in │ │ │ └── unit │ │ │ ├── SFMT.c │ │ │ ├── a0.c │ │ │ ├── arena_reset.c │ │ │ ├── arena_reset_prof.c │ │ │ ├── arena_reset_prof.sh │ │ │ ├── atomic.c │ │ │ ├── background_thread.c │ │ │ ├── background_thread_enable.c │ │ │ ├── base.c │ │ │ ├── binshard.c │ │ │ ├── binshard.sh │ │ │ ├── bit_util.c │ │ │ ├── bitmap.c │ │ │ ├── ckh.c │ │ │ ├── decay.c │ │ │ ├── decay.sh │ │ │ ├── div.c │ │ │ ├── emitter.c │ │ │ ├── extent_quantize.c │ │ │ ├── extent_util.c │ │ │ ├── fork.c │ │ │ ├── hash.c │ │ │ ├── hook.c │ │ │ ├── huge.c │ │ │ ├── junk.c │ │ │ ├── junk.sh │ │ │ ├── junk_alloc.c │ │ │ ├── junk_alloc.sh │ │ │ ├── junk_free.c │ │ │ ├── junk_free.sh │ │ │ ├── log.c │ │ │ ├── mallctl.c │ │ │ ├── malloc_io.c │ │ │ ├── math.c │ │ │ ├── mq.c │ │ │ ├── mtx.c │ │ │ ├── nstime.c │ │ │ ├── pack.c │ │ │ ├── pack.sh │ │ │ ├── pages.c │ │ │ ├── ph.c │ │ │ ├── prng.c │ │ │ ├── prof_accum.c │ │ │ ├── prof_accum.sh │ │ │ ├── prof_active.c │ │ │ ├── prof_active.sh │ │ │ ├── prof_gdump.c │ │ │ ├── prof_gdump.sh │ │ │ ├── prof_idump.c │ │ │ ├── prof_idump.sh │ │ │ ├── prof_log.c │ │ │ ├── prof_log.sh │ │ │ ├── prof_reset.c │ │ │ ├── prof_reset.sh │ │ │ ├── prof_tctx.c │ │ │ ├── prof_tctx.sh │ │ │ ├── prof_thread_name.c │ │ │ ├── prof_thread_name.sh │ │ │ ├── ql.c │ │ │ ├── qr.c │ │ │ ├── rb.c │ │ │ ├── retained.c │ │ │ ├── rtree.c │ │ │ ├── safety_check.c │ │ │ ├── safety_check.sh │ │ │ ├── sc.c │ │ │ ├── seq.c │ │ │ ├── size_classes.c │ │ │ ├── slab.c │ │ │ ├── smoothstep.c │ │ │ ├── spin.c │ │ │ ├── stats.c │ │ │ ├── stats_print.c │ │ │ ├── test_hooks.c │ │ │ ├── ticker.c │ │ │ ├── tsd.c │ │ │ ├── witness.c │ │ │ ├── zero.c │ │ │ └── zero.sh │ ├── src │ │ └── lib.rs │ ├── tests │ │ ├── malloc_conf_empty.rs │ │ ├── malloc_conf_set.rs │ │ └── unprefixed_malloc.rs │ └── update_jemalloc.md ├── jemallocator-global │ ├── Cargo.toml │ ├── LICENSE-APACHE │ ├── LICENSE-MIT │ ├── README.md │ └── src │ │ └── lib.rs ├── src │ └── lib.rs ├── systest │ ├── Cargo.toml │ ├── build.rs │ └── src │ │ └── main.rs └── tests │ ├── background_thread_defaults.rs │ ├── background_thread_enabled.rs │ ├── ffi.rs │ ├── grow_in_place.rs │ ├── malloctl.rs │ ├── shrink_in_place.rs │ ├── smoke.rs │ ├── smoke_ffi.rs │ └── usable_size.rs ├── lz4-compress ├── Cargo.toml ├── LICENSE ├── README.md └── src │ ├── compress.rs │ ├── decompress.rs │ ├── lib.rs │ ├── main.rs │ └── tests.rs ├── mimalloc_rust ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE.txt ├── README.md ├── libmimalloc-sys │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── c_src │ │ └── mimalloc │ │ │ ├── .gitattributes │ │ │ ├── .gitignore │ │ │ ├── CMakeLists.txt │ │ │ ├── LICENSE │ │ │ ├── azure-pipelines.yml │ │ │ ├── bin │ │ │ ├── mimalloc-redirect.dll │ │ │ ├── mimalloc-redirect.lib │ │ │ ├── mimalloc-redirect32.dll │ │ │ ├── mimalloc-redirect32.lib │ │ │ ├── minject.exe │ │ │ └── minject32.exe │ │ │ ├── cmake │ │ │ ├── mimalloc-config-version.cmake │ │ │ └── mimalloc-config.cmake │ │ │ ├── doc │ │ │ ├── bench-2020 │ │ │ │ ├── bench-c5-18xlarge-2020-01-20-a.svg │ │ │ │ ├── bench-c5-18xlarge-2020-01-20-b.svg │ │ │ │ ├── bench-c5-18xlarge-2020-01-20-rss-a.svg │ │ │ │ ├── bench-c5-18xlarge-2020-01-20-rss-b.svg │ │ │ │ ├── bench-r5a-1.svg │ │ │ │ ├── bench-r5a-12xlarge-2020-01-16-a.svg │ │ │ │ ├── bench-r5a-12xlarge-2020-01-16-b.svg │ │ │ │ ├── bench-r5a-2.svg │ │ │ │ ├── bench-r5a-rss-1.svg │ │ │ │ ├── bench-r5a-rss-2.svg │ │ │ │ ├── bench-spec-rss.svg │ │ │ │ ├── bench-spec.svg │ │ │ │ ├── bench-z4-1.svg │ │ │ │ ├── bench-z4-2.svg │ │ │ │ ├── bench-z4-rss-1.svg │ │ │ │ └── bench-z4-rss-2.svg │ │ │ ├── bench-2021 │ │ │ │ ├── bench-amd5950x-2021-01-30-a.svg │ │ │ │ ├── bench-amd5950x-2021-01-30-b.svg │ │ │ │ ├── bench-c5-18xlarge-2021-01-30-a.svg │ │ │ │ ├── bench-c5-18xlarge-2021-01-30-b.svg │ │ │ │ ├── bench-c5-18xlarge-2021-01-30-rss-a.svg │ │ │ │ ├── bench-c5-18xlarge-2021-01-30-rss-b.svg │ │ │ │ └── bench-macmini-2021-01-30.svg │ │ │ ├── doxyfile │ │ │ ├── ds-logo.jpg │ │ │ ├── ds-logo.png │ │ │ ├── mimalloc-doc.h │ │ │ ├── mimalloc-doxygen.css │ │ │ ├── mimalloc-logo-100.png │ │ │ ├── mimalloc-logo.png │ │ │ ├── mimalloc-logo.svg │ │ │ ├── spades-logo.png │ │ │ └── unreal-logo.svg │ │ │ ├── ide │ │ │ ├── vs2017 │ │ │ │ ├── mimalloc-override-test.vcxproj │ │ │ │ ├── mimalloc-override.vcxproj │ │ │ │ ├── mimalloc-test-stress.vcxproj │ │ │ │ ├── mimalloc-test.vcxproj │ │ │ │ ├── mimalloc.sln │ │ │ │ └── mimalloc.vcxproj │ │ │ └── vs2019 │ │ │ │ ├── mimalloc-override-test.vcxproj │ │ │ │ ├── mimalloc-override.vcxproj │ │ │ │ ├── mimalloc-test-api.vcxproj │ │ │ │ ├── mimalloc-test-stress.vcxproj │ │ │ │ ├── mimalloc-test.vcxproj │ │ │ │ ├── mimalloc.sln │ │ │ │ └── mimalloc.vcxproj │ │ │ ├── include │ │ │ ├── mimalloc-atomic.h │ │ │ ├── mimalloc-internal.h │ │ │ ├── mimalloc-new-delete.h │ │ │ ├── mimalloc-override.h │ │ │ ├── mimalloc-types.h │ │ │ └── mimalloc.h │ │ │ ├── readme.md │ │ │ ├── src │ │ │ ├── alloc-aligned.c │ │ │ ├── alloc-override-osx.c │ │ │ ├── alloc-override.c │ │ │ ├── alloc-posix.c │ │ │ ├── alloc.c │ │ │ ├── arena.c │ │ │ ├── bitmap.c │ │ │ ├── bitmap.h │ │ │ ├── heap.c │ │ │ ├── init.c │ │ │ ├── options.c │ │ │ ├── os.c │ │ │ ├── page-queue.c │ │ │ ├── page.c │ │ │ ├── random.c │ │ │ ├── region.c │ │ │ ├── segment-cache.c │ │ │ ├── segment.c │ │ │ ├── static.c │ │ │ └── stats.c │ │ │ └── test │ │ │ ├── CMakeLists.txt │ │ │ ├── main-override-static.c │ │ │ ├── main-override.c │ │ │ ├── main-override.cpp │ │ │ ├── main.c │ │ │ ├── readme.md │ │ │ ├── test-api-fill.c │ │ │ ├── test-api.c │ │ │ ├── test-stress.c │ │ │ └── testhelper.h │ ├── src │ │ ├── extended.rs │ │ └── lib.rs │ └── sys-test │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ └── main.rs └── src │ └── lib.rs ├── preload ├── Cargo.toml └── src │ ├── allocation_tracker.rs │ ├── api.rs │ ├── arc_lite.rs │ ├── arch.rs │ ├── channel.rs │ ├── elf.rs │ ├── event.rs │ ├── global.rs │ ├── init.rs │ ├── lib.rs │ ├── logger.rs │ ├── macros.rs │ ├── nohash.rs │ ├── opt.rs │ ├── ordered_map.rs │ ├── processing_thread.rs │ ├── raw_file.rs │ ├── smaps.rs │ ├── spin_lock.rs │ ├── syscall.rs │ ├── timestamp.rs │ ├── unwind.rs │ ├── utils.rs │ ├── writer_memory.rs │ └── writers.rs ├── replay ├── Makefile ├── generate.sh └── replay.cpp ├── rust-toolchain ├── screenshot_graph.png ├── screenshot_gui_group_by_backtrace.png ├── screenshot_gui_memory_usage_graph.png ├── screenshot_gui_scripting_console.png ├── server-core ├── Cargo.toml ├── build.rs └── src │ ├── byte_channel.rs │ ├── filter.rs │ ├── itertools.rs │ ├── lib.rs │ ├── protocol.rs │ ├── streaming_channel.rs │ └── streaming_serializer.rs ├── simulation ├── .gitignore ├── Cargo.toml ├── generate-simulation-data.sh ├── memory-profiling-simulation.dat └── src │ └── main.rs └── webui ├── .babelrc ├── README.md ├── package.json ├── src ├── App.js ├── Feather.js ├── Graph.js ├── PageDataAddressSpace.js ├── PageDataAllocations.js ├── PageDataConsole.js ├── PageDataList.js ├── PageDataMapDetails.js ├── PageDataMaps.js ├── PageDataOverview.js ├── Tabbed.js ├── import-bootstrap.js ├── import-jquery.js ├── import-popper.js ├── index.css ├── index.html ├── index.js ├── list-common.js └── utils.js └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | jemallocator/* linguist-vendored 2 | lz4-compress/* linguist-vendored 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | target-docker 3 | **/*.rs.bk 4 | webui/.cache 5 | webui/.parcel-cache 6 | webui/dist 7 | webui/node_modules 8 | replay/replay 9 | replay/generated.inc 10 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["common", "lz4-compress", "jemallocator/jemalloc-sys", "preload", "cli-core", "cli", "server-core", "gather", "integration-tests", "mimalloc_rust", "fast_range_map"] 3 | resolver = "2" 4 | 5 | [profile.dev] 6 | opt-level = 2 7 | incremental = true 8 | 9 | [profile.release] 10 | opt-level = 3 11 | lto = true 12 | panic = "abort" 13 | debug = true 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Short version for non-lawyers: 2 | 3 | SPDX-License-Identifier: MIT OR Apache-2.0 4 | 5 | memory-profiler is dual-licensed under Apache 2.0 and MIT 6 | terms. 7 | 8 | Longer version: 9 | 10 | Except as otherwise noted (below and/or in individual files), memory-profiler is 11 | licensed under the Apache License, Version 2.0 or 12 | or the MIT license 13 | or , at your option. -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /ci/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | cd "$(dirname $(readlink -f "$0"))/.." 5 | 6 | source ./ci/check_if_nightly.sh 7 | 8 | cd preload 9 | cargo build --release --target=x86_64-unknown-linux-gnu $FEATURES_NIGHTLY 10 | cd .. 11 | 12 | cd cli 13 | cargo build --release --target=x86_64-unknown-linux-gnu 14 | cd .. 15 | 16 | cd gather 17 | cargo build --release --target=x86_64-unknown-linux-gnu 18 | cd .. 19 | -------------------------------------------------------------------------------- /ci/build_and_package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | cd "$(dirname $(readlink -f "$0"))/.." 5 | 6 | ./ci/build.sh 7 | ./ci/package.sh 8 | -------------------------------------------------------------------------------- /ci/check_if_nightly.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set +e 4 | echo "$(rustc --version)" | grep -q "nightly" 5 | if [ "$?" = "0" ]; then 6 | FEATURES_NIGHTLY="--features nightly" 7 | else 8 | FEATURES_NIGHTLY="" 9 | fi 10 | set -e 11 | -------------------------------------------------------------------------------- /ci/docker/run-interactive.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -euo pipefail 4 | exec "$(dirname $(readlink -f "$0"))/run.sh" --interactive "$@" 5 | -------------------------------------------------------------------------------- /ci/docker/static/cargo.config: -------------------------------------------------------------------------------- 1 | [target.aarch64-unknown-linux-gnu] 2 | linker = "/usr/bin/aarch64-linux-gnu-gcc" 3 | runner = "/usr/local/bin/runner" 4 | 5 | [target.armv7-unknown-linux-gnueabihf] 6 | linker = "/usr/bin/arm-linux-gnueabihf-gcc" 7 | runner = "/usr/local/bin/runner" 8 | 9 | [target.mips64-unknown-linux-gnuabi64] 10 | linker = "/usr/bin/mips64-linux-gnuabi64-gcc" 11 | runner = "/usr/local/bin/runner" 12 | -------------------------------------------------------------------------------- /ci/docker/static/run-if-enabled: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | set +e 6 | echo "$TARGET_LIST" | grep -q "$1" 7 | R=$? 8 | shift 9 | set -e 10 | 11 | if [[ "$R" == "0" ]]; then 12 | /bin/bash -c "set -euo pipefail ; $@" 13 | exit $? 14 | fi 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /ci/docker/static/runner: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export QEMU_SET_ENV=LD_PRELOAD=$TARGET_LD_PRELOAD 4 | 5 | INFO=$(file $1) 6 | 7 | echo "$INFO" | grep -q "ARM aarch64" 8 | if [[ "$?" -eq "0" ]]; then 9 | export QEMU_LD_PREFIX=/usr/aarch64-linux-gnu 10 | exec qemu-aarch64 "$@" 11 | fi 12 | 13 | echo "$INFO" | grep -q "ARM, EABI" 14 | if [[ "$?" -eq "0" ]]; then 15 | export QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf 16 | exec qemu-arm "$@" 17 | fi 18 | 19 | echo "$INFO" | grep -q "MIPS64" 20 | if [[ "$?" -eq "0" ]]; then 21 | export QEMU_LD_PREFIX=/usr/mips64-linux-gnuabi64 22 | exec qemu-mips64 "$@" 23 | fi 24 | 25 | echo "$INFO" | grep -q "x86-64" 26 | if [[ "$?" -eq "0" ]]; then 27 | export QEMU_LD_PREFIX=/ 28 | exec qemu-x86_64 "$@" 29 | fi 30 | 31 | echo "ERROR: Unknown architecture!" 32 | exit 1 33 | -------------------------------------------------------------------------------- /ci/package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | cd "$(dirname $(readlink -f "$0"))/.." 5 | 6 | CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-$(dirname $(readlink -f "$0"))/../target} 7 | 8 | echo "Packaging for deployment..." 9 | 10 | rm -Rf $CARGO_TARGET_DIR/travis-deployment $CARGO_TARGET_DIR/travis-deployment-tmp 11 | mkdir -p $CARGO_TARGET_DIR/travis-deployment $CARGO_TARGET_DIR/travis-deployment-tmp 12 | 13 | cp $CARGO_TARGET_DIR/x86_64-unknown-linux-gnu/release/libbytehound.so $CARGO_TARGET_DIR/travis-deployment-tmp/ 14 | cp $CARGO_TARGET_DIR/x86_64-unknown-linux-gnu/release/bytehound $CARGO_TARGET_DIR/travis-deployment-tmp/ 15 | cp $CARGO_TARGET_DIR/x86_64-unknown-linux-gnu/release/bytehound-gather $CARGO_TARGET_DIR/travis-deployment-tmp/ 16 | 17 | cd $CARGO_TARGET_DIR/travis-deployment-tmp 18 | tar -zcf ../travis-deployment/bytehound-x86_64-unknown-linux-gnu.tgz \ 19 | libbytehound.so \ 20 | bytehound \ 21 | bytehound-gather 22 | 23 | echo "Deployment package built!" 24 | -------------------------------------------------------------------------------- /ci/run_cross_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | cd "$(dirname $(readlink -f "$0"))/.." 5 | 6 | source ./ci/check_if_nightly.sh 7 | 8 | export MEMORY_PROFILER_TEST_TARGET=$1 9 | export MEMORY_PROFILER_TEST_RUNNER=/usr/local/bin/runner 10 | 11 | cd preload 12 | cargo build --target=$MEMORY_PROFILER_TEST_TARGET $FEATURES_NIGHTLY 13 | cd .. 14 | 15 | cd integration-tests 16 | MEMORY_PROFILER_TEST_PRELOAD_PATH=$MEMORY_PROFILER_TEST_TARGET/debug cargo test --no-default-features 17 | cd .. 18 | 19 | cd preload 20 | cargo build --target=$MEMORY_PROFILER_TEST_TARGET $FEATURES_NIGHTLY --release 21 | cd .. 22 | 23 | cd integration-tests 24 | MEMORY_PROFILER_TEST_PRELOAD_PATH=$MEMORY_PROFILER_TEST_TARGET/release cargo test --no-default-features 25 | cd .. 26 | -------------------------------------------------------------------------------- /ci/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | cd "$(dirname $(readlink -f "$0"))/.." 5 | 6 | source ./ci/check_if_nightly.sh 7 | 8 | export RUST_BACKTRACE=1 9 | 10 | cd common 11 | cargo test --target=x86_64-unknown-linux-gnu 12 | cd .. 13 | 14 | cd preload 15 | cargo test --target=x86_64-unknown-linux-gnu $FEATURES_NIGHTLY 16 | cd .. 17 | 18 | cd cli-core 19 | cargo test --target=x86_64-unknown-linux-gnu 20 | cd .. 21 | 22 | cd server-core 23 | cargo test --target=x86_64-unknown-linux-gnu 24 | cd .. 25 | 26 | ./ci/build.sh 27 | 28 | ci/run_cross_tests.sh x86_64-unknown-linux-gnu 29 | ci/run_cross_tests.sh aarch64-unknown-linux-gnu 30 | ci/run_cross_tests.sh armv7-unknown-linux-gnueabihf 31 | ci/run_cross_tests.sh mips64-unknown-linux-gnuabi64 32 | -------------------------------------------------------------------------------- /cli-core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cli-core" 3 | version = "0.11.0" 4 | authors = ["Jan Bujak "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | smallvec = "1" 9 | byteorder = "1" 10 | ctrlc = "3" 11 | goblin = "0.0.24" 12 | string-interner = { version = "0.7", default-features = false } 13 | cpp_demangle = "0.2" 14 | chrono = "0.4" 15 | libc = "0.2" 16 | log = "0.4" 17 | lru = "0.6" 18 | bitflags = "1" 19 | inferno = { version = "0.9", default-features = false } 20 | lazy_static = "1" 21 | ahash = "0.7" 22 | parking_lot = "0.12" 23 | crossbeam-channel = "0.5" 24 | rayon = "1" 25 | regex = "1" 26 | rhai = { version = "1", features = ["unchecked"] } 27 | plotters = { version = "0.3", default-features = false, features = ["svg_backend", "all_series"] } 28 | colorgrad = "0.4" 29 | serde_json = "1" 30 | derive_more = "0.99" 31 | 32 | common = { path = "../common" } 33 | lz4-compress = { path = "../lz4-compress" } 34 | fast_range_map = { path = "../fast_range_map" } 35 | 36 | [dependencies.nwind] 37 | git = "https://github.com/koute/not-perf.git" 38 | rev = "911723c" 39 | 40 | [dev-dependencies] 41 | quickcheck = "0.9" 42 | -------------------------------------------------------------------------------- /cli-core/src/repack.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, Read, Write}; 2 | 3 | use common::speedy::{ 4 | Writable 5 | }; 6 | 7 | use common::event::Event; 8 | use common::lz4_stream::Lz4Writer; 9 | 10 | use crate::reader::parse_events; 11 | 12 | pub fn repack< F, G >( disable_compression: bool, input_fp: F, output_fp: G ) -> Result< (), io::Error > 13 | where F: Read + Send + 'static, 14 | G: Write + Send + 'static 15 | { 16 | let (header, event_stream) = parse_events( input_fp )?; 17 | let mut output_fp = Lz4Writer::new( output_fp ); 18 | if disable_compression { 19 | output_fp.disable_compression()?; 20 | } 21 | 22 | Event::Header( header ).write_to_stream( &mut output_fp )?; 23 | for event in event_stream { 24 | let event = event?; 25 | event.write_to_stream( &mut output_fp )?; 26 | } 27 | 28 | output_fp.flush()?; 29 | 30 | Ok(()) 31 | } -------------------------------------------------------------------------------- /cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bytehound-cli" 3 | version = "0.11.0" 4 | authors = ["Jan Bujak "] 5 | edition = "2018" 6 | 7 | [[bin]] 8 | name = "bytehound" 9 | path = "src/main.rs" 10 | 11 | [dependencies] 12 | log = "0.4" 13 | env_logger = "0.6" 14 | structopt = "0.2" 15 | cli-core = { path = "../cli-core" } 16 | server-core = { path = "../server-core", optional = true } 17 | tikv-jemallocator = "0.4" 18 | 19 | [features] 20 | default = ["subcommand-server"] 21 | subcommand-server = ["server-core"] 22 | -------------------------------------------------------------------------------- /common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common" 3 | version = "0.11.0" 4 | authors = ["Jan Bujak "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | lz4-compress = { path = "../lz4-compress" } 9 | speedy = "0.8" 10 | byteorder = "1" 11 | libc = "0.2" 12 | bitflags = "1" 13 | -------------------------------------------------------------------------------- /common/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub extern crate speedy; 2 | 3 | mod os_util; 4 | mod timestamp; 5 | 6 | pub mod event; 7 | pub mod lz4_stream; 8 | pub mod request; 9 | 10 | pub use crate::os_util::get_local_ips; 11 | pub use crate::timestamp::Timestamp; 12 | -------------------------------------------------------------------------------- /common/src/request.rs: -------------------------------------------------------------------------------- 1 | use std::borrow::Cow; 2 | use speedy::{Readable, Writable}; 3 | use crate::timestamp::Timestamp; 4 | use crate::event::DataId; 5 | 6 | pub const PROTOCOL_VERSION: u32 = 2; 7 | 8 | #[derive(PartialEq, Debug, Readable, Writable)] 9 | pub enum Request { 10 | StartStreaming, 11 | TriggerMemoryDump, 12 | Ping 13 | } 14 | 15 | #[derive(PartialEq, Debug, Readable, Writable)] 16 | pub enum Response< 'a > { 17 | Start( BroadcastHeader ), 18 | Data( Cow< 'a, [u8] > ), 19 | FinishedInitialStreaming, 20 | Pong, 21 | Finished 22 | } 23 | 24 | #[derive(PartialEq, Debug, Readable, Writable)] 25 | pub struct BroadcastHeader { 26 | pub id: DataId, 27 | pub initial_timestamp: Timestamp, 28 | pub timestamp: Timestamp, 29 | pub wall_clock_secs: u64, 30 | pub wall_clock_nsecs: u64, 31 | pub pid: u32, 32 | pub cmdline: Vec< u8 >, 33 | pub executable: Vec< u8 >, 34 | pub arch: String, 35 | pub listener_port: u16, 36 | pub protocol_version: u32 37 | } 38 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | .cache 2 | book 3 | src/generated 4 | -------------------------------------------------------------------------------- /docs/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Jan Bujak"] 3 | language = "en" 4 | multilingual = false 5 | src = "src" 6 | title = "Memory profiling for fun and profit" 7 | 8 | [output.html] 9 | additional-css = ["custom.css"] 10 | site-url = "/bytehound/" 11 | 12 | [preprocessor.run-inline-snippets] 13 | command = "ruby plugins/run-inline-snippets.rb" 14 | -------------------------------------------------------------------------------- /docs/build-for-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -Rf .cache 4 | rm -Rf src/generated 5 | mdbook clean 6 | mdbook build 7 | -------------------------------------------------------------------------------- /docs/custom.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --sidebar-width: 400px; 3 | } 4 | 5 | p img { 6 | border: 1px solid #aaa; 7 | border-radius: 4px; 8 | opacity: 0.8; 9 | padding: 1rem; 10 | } -------------------------------------------------------------------------------- /docs/src/api_reference.md: -------------------------------------------------------------------------------- 1 | # API reference 2 | 3 | The profiler supports an embedded domain specific language based on [Rhai](https://rhai.rs) 4 | for easy data analysis. Here's an API reference of everything the DSL exposes. -------------------------------------------------------------------------------- /docs/src/api_reference/Allocation.md: -------------------------------------------------------------------------------- 1 | # Allocation 2 | 3 | `Allocation` is an object representing a single allocation. 4 | -------------------------------------------------------------------------------- /docs/src/api_reference/Allocation/allocated_at.md: -------------------------------------------------------------------------------- 1 | ## Allocation::allocated_at 2 | 3 | ```rhai 4 | fn allocated_at( 5 | self: Allocation 6 | ) -> Duration 7 | ``` 8 | 9 | Returns when this allocation was made, as a time offset from the start of the profiling. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println(allocations()[0].allocated_at()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/Allocation/backtrace.md: -------------------------------------------------------------------------------- 1 | ## Allocation::backtrace 2 | 3 | ```rhai 4 | fn backtrace( 5 | self: Allocation 6 | ) -> Backtrace 7 | ``` 8 | 9 | Returns the backtrace of this allocation. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println(allocations()[0].backtrace()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/Allocation/deallocated_at.md: -------------------------------------------------------------------------------- 1 | ## Allocation::deallocated_at 2 | 3 | ```rhai 4 | fn deallocated_at( 5 | self: Allocation 6 | ) -> Option 7 | ``` 8 | 9 | Returns when this allocation was freed, as a time offset from the start of the profiling. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println((allocations().only_leaked())[0].deallocated_at()); 15 | println((allocations().only_temporary())[0].deallocated_at()); 16 | ``` 17 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList.md: -------------------------------------------------------------------------------- 1 | # AllocationGroupList 2 | 3 | `AllocationGroupList` is an object which holds multiple [`AllocationList`s](AllocationList.md) 4 | grouped according to a specified criteria. 5 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/len.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::len 2 | 3 | ```rhai 4 | fn len( 5 | self: AllocationGroupList 6 | ) -> Integer 7 | ``` 8 | 9 | Returns the number of allocation groups within the list. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println(allocations().group_by_backtrace().len()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/only_all_leaked.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::only_all_leaked 2 | 3 | ```rhai 4 | fn only_all_leaked( 5 | self: AllocationGroupList 6 | ) -> AllocationGroupList 7 | ``` 8 | 9 | Returns a new `AllocationGroupList` with only those groups where all of the allocations where leaked. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/only_count_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::only_count_at_least 2 | 3 | ```rhai 4 | fn only_count_at_least( 5 | self: AllocationGroupList, 6 | threshold: Integer 7 | ) -> AllocationGroupList 8 | ``` 9 | 10 | Returns a new `AllocationGroupList` with only those groups where the number of allocations is 11 | at least `threshold` allocations or more. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/op_iterator.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::(iterator) 2 | 3 | `AllocationGroupList` can be iterated with a `for`. 4 | 5 | ### Examples 6 | 7 | ```rhai,%run 8 | for group in allocations().group_by_backtrace().take(2) { 9 | println("Allocations in group: {}", group.len()); 10 | } 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/op_square_brackets.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::[] 2 | 3 | ```rhai 4 | fn []( 5 | index: Integer 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a given [`AllocationList`](../AllocationList.md) from the list. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | let groups = allocations().group_by_backtrace().sort_by_count(); 15 | println(groups[0].len()); 16 | println(groups[1].len()); 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/sort_by_count.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::sort_by_count 2 | 3 | Alias for [sort_by_count_descending](sort_by_count_descending.md). 4 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/sort_by_count_ascending.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::sort_by_count_ascending 2 | 3 | ```rhai 4 | fn sort_by_count_ascending( 5 | self: AllocationGroupList 6 | ) -> AllocationGroupList 7 | ``` 8 | 9 | Sorts the groups by allocation count in an ascending order. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | let groups = allocations().group_by_backtrace().sort_by_count_ascending(); 15 | println(groups[0].len()); 16 | println(groups[1].len()); 17 | println(groups[groups.len() - 1].len()); 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/sort_by_count_descending.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::sort_by_count_descending 2 | 3 | ```rhai 4 | fn sort_by_count_descending( 5 | self: AllocationGroupList 6 | ) -> AllocationGroupList 7 | ``` 8 | 9 | Sorts the groups by allocation count in a descending order. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | let groups = allocations().group_by_backtrace().sort_by_count_descending(); 15 | println(groups[0].len()); 16 | println(groups[1].len()); 17 | println(groups[groups.len() - 1].len()); 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/sort_by_size.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::sort_by_size 2 | 3 | Alias for [sort_by_size_descending](sort_by_size_descending.md). 4 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/sort_by_size_ascending.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::sort_by_size_ascending 2 | 3 | ```rhai 4 | fn sort_by_size_ascending( 5 | self: AllocationGroupList 6 | ) -> AllocationGroupList 7 | ``` 8 | 9 | Sorts the groups by their memory usage in an ascending order. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/sort_by_size_descending.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::sort_by_size_descending 2 | 3 | ```rhai 4 | fn sort_by_size_descending( 5 | self: AllocationGroupList 6 | ) -> AllocationGroupList 7 | ``` 8 | 9 | Sorts the groups by their memory usage in a descending order. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/take.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::take 2 | 3 | ```rhai 4 | fn take( 5 | self: AllocationGroupList, 6 | count: AllocationGroupList 7 | ) -> AllocanioGroupList 8 | ``` 9 | 10 | Returns a new list with at most `count` items. 11 | 12 | ### Examples 13 | 14 | ```rhai,%run 15 | let groups = allocations().group_by_backtrace(); 16 | println(groups.len()); 17 | println(groups.take(3).len()); 18 | println(groups.take(100).len()); 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationGroupList/ungroup.md: -------------------------------------------------------------------------------- 1 | ## AllocationGroupList::ungroup 2 | 3 | ```rhai 4 | fn ungroup( 5 | self: AllocationGroupList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Ungroups all of the allocations back into a flat list. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList.md: -------------------------------------------------------------------------------- 1 | # AllocationList 2 | 3 | `AllocationList` is an object which holds a list of allocations. 4 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/group_by_backtrace.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::group_by_backtrace 2 | 3 | ```rhai 4 | fn group_by_backtrace( 5 | self: AllocationList 6 | ) -> AllocationGroupList 7 | ``` 8 | 9 | Groups all of the allocations according to their backtrace. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/len.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::len 2 | 3 | ```rhai 4 | fn len( 5 | self: AllocationList 6 | ) -> Integer 7 | ``` 8 | 9 | Returns the number of allocations within the list. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println(allocations().len()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_address_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_address_at_least 2 | 3 | ```rhai 4 | fn only_address_at_least( 5 | self: AllocationList, 6 | address: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose address is equal or higher than the one specified. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_address_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_address_at_most 2 | 3 | ```rhai 4 | fn only_address_at_most( 5 | self: AllocationList, 6 | address: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose address is equal or lower than the one specified. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_alive_at.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_alive_at 2 | 3 | ```rhai 4 | fn only_alive_at( 5 | self: AllocationList, 6 | durations: [Duration] 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that were alive at all 11 | of the times specified by `durations` as measured from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_allocated_after_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_allocated_after_at_least 2 | 3 | ```rhai 4 | fn only_allocated_after_at_least( 5 | self: AllocationList, 6 | duration: Duration 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that were allocated after at least `duration` 11 | from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_allocated_until_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_allocated_until_at_most 2 | 3 | ```rhai 4 | fn only_allocated_until_at_most( 5 | self: AllocationList, 6 | duration: Duration 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that were allocated until at most `duration` 11 | from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_backtrace_length_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_backtrace_length_at_least 2 | 3 | ```rhai 4 | fn only_backtrace_length_at_least( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that have a backtrace which has at least `threshold` many frames. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_backtrace_length_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_backtrace_length_at_most 2 | 3 | ```rhai 4 | fn only_backtrace_length_at_most( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that have a backtrace which has at most `threshold` many frames. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_chain_leaked.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_chain_leaked 2 | 3 | ```rhai 4 | fn only_chain_leaked( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a new `AllocationList` with only those allocations where 10 | their last allocation in their realloc chain was leaked. 11 | 12 | A leaked allocation is an allocation which was never deallocated. 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_chain_length_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_chain_length_at_least 2 | 3 | ```rhai 4 | fn only_chain_length_at_least( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose whole allocation chain was at least `threshold` allocations long. 11 | 12 | For example, for the following allocation pattern: 13 | 14 | ```c 15 | void * a0 = malloc(size); 16 | 17 | void * b0 = malloc(size); 18 | void * b1 = realloc(b0, size + 1); 19 | ``` 20 | 21 | this code: 22 | 23 | ```rhai 24 | allocations().only_chain_length_at_least(2) 25 | ``` 26 | 27 | will only match `b0` and `b1`, since their whole allocation chain has at least two allocations. 28 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_chain_length_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_chain_length_at_most 2 | 3 | ```rhai 4 | fn only_chain_length_at_most( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose whole allocation chain was at most `threshold` allocations long. 11 | 12 | For example, for the following allocation pattern: 13 | 14 | ```c 15 | void * a0 = malloc(size); 16 | void * a1 = realloc(a0, size + 1); 17 | 18 | void * b0 = malloc(size); 19 | void * b1 = realloc(b0, size + 1); 20 | void * b2 = realloc(b1, size + 2); 21 | ``` 22 | 23 | this code: 24 | 25 | ```rhai 26 | allocations().only_chain_length_at_most(2) 27 | ``` 28 | 29 | will only match `a0` and `a1`, since their whole allocation chain has at most two allocations. 30 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_deallocated_after_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_deallocated_after_at_least 2 | 3 | ```rhai 4 | fn only_deallocated_after_at_least( 5 | self: AllocationList, 6 | duration: Duration 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that were deallocated after at least `duration` 11 | from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_deallocated_until_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_deallocated_until_at_most 2 | 3 | ```rhai 4 | fn only_deallocated_until_at_most( 5 | self: AllocationList, 6 | duration: Duration 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that were deallocated until at most `duration` 11 | from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_first_size_larger.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_first_size_larger 2 | 3 | ```rhai 4 | fn only_first_size_larger( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that are part of an allocation chain where the first allocation's size is larger than the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_first_size_larger_or_equal.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_first_size_larger_or_equal 2 | 3 | ```rhai 4 | fn only_first_size_larger_or_equal( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that are part of an allocation chain where the first allocation's size is larger or equal to the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_first_size_smaller.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_first_size_smaller 2 | 3 | ```rhai 4 | fn only_first_size_smaller( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that are part of an allocation chain where the first allocation's size is smaller than the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_first_size_smaller_or_equal.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_first_size_smaller_or_equal 2 | 3 | ```rhai 4 | fn only_first_size_smaller_or_equal( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that are part of an allocation chain where the first allocation's size is smaller or equal to the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_from_maps.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_from_maps 2 | 3 | ```rhai 4 | fn only_from_maps( 5 | self: MapList, 6 | map_ids: Map|MapList|Integer 7 | ) -> MapList 8 | ``` 9 | 10 | ```rhai 11 | fn only_from_maps( 12 | self: MapList, 13 | map_ids: [Map|MapList|Integer] 14 | ) -> MapList 15 | ``` 16 | 17 | Returns a new `AllocationList` with only the allocations that come from within given `map_ids`. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_group_allocations_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_group_allocations_at_least 2 | 3 | ```rhai 4 | fn only_group_allocations_at_least( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that come from a stack trace which produced at least `threshold` allocations. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_group_allocations_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_group_allocations_at_most 2 | 3 | ```rhai 4 | fn only_group_allocations_at_most( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that come from a stack trace which produced at most `threshold` allocations. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_group_interval_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_group_interval_at_least 2 | 3 | ```rhai 4 | fn only_group_interval_at_least( 5 | self: AllocationList, 6 | duration: Duration 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that come from a stack trace which produced allocations spanning at least `duration`, 11 | as measured from the very first allocation, to the very last allocation from the same location. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_group_interval_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_group_interval_at_most 2 | 3 | ```rhai 4 | fn only_group_interval_at_most( 5 | self: AllocationList, 6 | duration: Duration 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that come from a stack trace which produced allocations spanning at most `duration`, 11 | as measured from the very first allocation, to the very last allocation from the same location. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_group_leaked_allocations_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_group_leaked_allocations_at_least 2 | 3 | ```rhai 4 | fn only_group_leaked_allocations_at_least( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that come from a stack trace which produced at least `threshold` leaked allocations. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_group_leaked_allocations_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_group_leaked_allocations_at_most 2 | 3 | ```rhai 4 | fn only_group_leaked_allocations_at_most( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that come from a stack trace which produced at most `threshold` leaked allocations. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_group_max_total_usage_first_seen_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_group_max_total_usage_first_seen_at_least 2 | 3 | ```rhai 4 | fn only_group_max_total_usage_first_seen_at_least( 5 | self: AllocationList, 6 | duration: Duration 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that come from 11 | a stack trace whose total maximum memory usage first peaked after at least 12 | `duration` from the start of profiling. 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_group_max_total_usage_first_seen_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_group_max_total_usage_first_seen_at_most 2 | 3 | ```rhai 4 | fn only_group_max_total_usage_first_seen_at_most( 5 | self: AllocationList, 6 | duration: Duration 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that come from 11 | a stack trace whose total maximum memory usage first peaked before at most 12 | `duration` from the start of profiling. 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_jemalloc.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_jemalloc 2 | 3 | ```rhai 4 | fn only_jemalloc( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a new `AllocationList` with only allocations which were allocated through 10 | one of the jemalloc interfaces. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_larger.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_larger 2 | 3 | ```rhai 4 | fn only_larger( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose size is larger than the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_larger_or_equal.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_larger_or_equal 2 | 3 | ```rhai 4 | fn only_larger_or_equal( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose size is larger or equal to the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_last_size_larger.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_last_size_larger 2 | 3 | ```rhai 4 | fn only_last_size_larger( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that are part of an allocation chain where the last allocation's size is larger than the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_last_size_larger_or_equal.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_last_size_larger_or_equal 2 | 3 | ```rhai 4 | fn only_last_size_larger_or_equal( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that are part of an allocation chain where the last allocation's size is larger or equal to the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_last_size_smaller.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_last_size_smaller 2 | 3 | ```rhai 4 | fn only_last_size_smaller( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that are part of an allocation chain where the last allocation's size is smaller than the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_last_size_smaller_or_equal.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_last_size_smaller_or_equal 2 | 3 | ```rhai 4 | fn only_last_size_smaller_or_equal( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that are part of an allocation chain where the last allocation's size is smaller or equal to the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_leaked.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_leaked 2 | 3 | ```rhai 4 | fn only_leaked( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a new `AllocationList` with only leaked allocations. 10 | 11 | A leaked allocation is an allocation which was never deallocated. 12 | 13 | Opposite of [`only_temporary`](./only_temporary.md). 14 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_leaked_or_deallocated_after.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_leaked_or_deallocated_after 2 | 3 | ```rhai 4 | fn only_leaked_or_deallocated_after( 5 | self: AllocationList, 6 | duration: Duration 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations that were either leaked or deallocated 11 | after `duration` from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_matching_backtraces.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_matching_backtraces 2 | 3 | ```rhai 4 | fn only_matching_backtraces( 5 | self: AllocationList, 6 | backtrace_ids: [Backtrace|AllocationList|MapList|AllocationGroupList|Integer] 7 | ) -> AllocationList 8 | ``` 9 | 10 | ```rhai 11 | fn only_matching_backtraces( 12 | self: AllocationList, 13 | backtrace_ids: Backtrace|AllocationList|MapList|AllocationGroupList|Integer 14 | ) -> AllocationList 15 | ``` 16 | 17 | Returns a new `AllocationList` with only the allocations that come from one of the given `backtrace_ids`. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_matching_deallocation_backtraces.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_matching_deallocation_backtraces 2 | 3 | ```rhai 4 | fn only_matching_deallocation_backtraces( 5 | self: AllocationList, 6 | backtrace_ids: [Backtrace|AllocationList|MapList|AllocationGroupList|Integer] 7 | ) -> AllocationList 8 | ``` 9 | 10 | ```rhai 11 | fn only_matching_deallocation_backtraces( 12 | self: AllocationList, 13 | backtrace_ids: Backtrace|AllocationList|MapList|AllocationGroupList|Integer 14 | ) -> AllocationList 15 | ``` 16 | 17 | Returns a new `AllocationList` with only the allocations that were deallocated at one of the given `backtrace_ids`. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_not_jemalloc.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_not_jemalloc 2 | 3 | ```rhai 4 | fn only_not_jemalloc( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a new `AllocationList` with only allocations which were *not* allocated through 10 | one of the jemalloc interfaces. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_not_matching_backtraces.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_not_matching_backtraces 2 | 3 | ```rhai 4 | fn only_not_matching_backtraces( 5 | self: AllocationList, 6 | backtrace_ids: [Backtrace|AllocationList|MapList|AllocationGroupList|Integer] 7 | ) -> AllocationList 8 | ``` 9 | 10 | ```rhai 11 | fn only_not_matching_backtraces( 12 | self: AllocationList, 13 | backtrace_ids: Backtrace|AllocationList|MapList|AllocationGroupList|Integer 14 | ) -> AllocationList 15 | ``` 16 | 17 | Returns a new `AllocationList` with only the allocations that do not come from one of the given `backtrace_ids`. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_not_matching_deallocation_backtraces.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_not_matching_deallocation_backtraces 2 | 3 | ```rhai 4 | fn only_not_matching_deallocation_backtraces( 5 | self: AllocationList, 6 | backtrace_ids: [Backtrace|AllocationList|MapList|AllocationGroupList|Integer] 7 | ) -> AllocationList 8 | ``` 9 | 10 | ```rhai 11 | fn only_not_matching_deallocation_backtraces( 12 | self: AllocationList, 13 | backtrace_ids: Backtrace|AllocationList|MapList|AllocationGroupList|Integer 14 | ) -> AllocationList 15 | ``` 16 | 17 | Returns a new `AllocationList` with only the allocations that were not deallocated at one of the given `backtrace_ids`. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_not_passing_through_function.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_not_passing_through_function 2 | 3 | ```rhai 4 | fn only_not_passing_through_function( 5 | self: AllocationList, 6 | regex: String 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose backtrace does **not** contain a function which matches a given regex. 11 | 12 | The flavor of regexps used here is the same as Rust's [`regex` crate](https://docs.rs/regex). -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_not_passing_through_source.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_not_passing_through_source 2 | 3 | ```rhai 4 | fn only_not_passing_through_source( 5 | self: AllocationList, 6 | regex: String 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose backtrace does **not** contain a frame which passes through a source file which matches a given regex. 11 | 12 | The flavor of regexps used here is the same as Rust's [`regex` crate](https://docs.rs/regex). 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_passing_through_function.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_passing_through_function 2 | 3 | ```rhai 4 | fn only_passing_through_function( 5 | self: AllocationList, 6 | regex: String 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose backtrace contains a function which matches a given regex. 11 | 12 | The flavor of regexps used here is the same as Rust's [`regex` crate](https://docs.rs/regex). 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_passing_through_source.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_passing_through_source 2 | 3 | ```rhai 4 | fn only_passing_through_source( 5 | self: AllocationList, 6 | regex: String 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose backtrace contains a frame which passes through a source file which matches a given regex. 11 | 12 | The flavor of regexps used here is the same as Rust's [`regex` crate](https://docs.rs/regex). 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_position_in_chain_at_least.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_position_in_chain_at_least 2 | 3 | ```rhai 4 | fn only_position_in_chain_at_least( 5 | self: AllocationList, 6 | position: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose position in their allocation chain is at least equal to `position`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_position_in_chain_at_most.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_position_in_chain_at_most 2 | 3 | ```rhai 4 | fn only_position_in_chain_at_most( 5 | self: AllocationList, 6 | position: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose position in their allocation chain is at most equal to `position`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_ptmalloc_from_main_arena.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_ptmalloc_from_main_arena 2 | 3 | ```rhai 4 | fn only_ptmalloc_from_main_arena( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a new `AllocationList` with only ptmalloc allocations which were internally allocated on the main arena. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_ptmalloc_mmaped.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_ptmalloc_mmaped 2 | 3 | ```rhai 4 | fn only_ptmalloc_mmaped( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a new `AllocationList` with only ptmalloc allocations which were internally allocated through `mmap`. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_ptmalloc_not_from_main_arena.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_ptmalloc_not_from_main_arena 2 | 3 | ```rhai 4 | fn only_ptmalloc_not_from_main_arena( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a new `AllocationList` with only ptmalloc allocations which were internally not allocated on the main arena. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_ptmalloc_not_mmaped.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_ptmalloc_not_mmaped 2 | 3 | ```rhai 4 | fn only_ptmalloc_not_mmaped( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a new `AllocationList` with only ptmalloc allocations which were internally not allocated through `mmap`. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_smaller.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_smaller 2 | 3 | ```rhai 4 | fn only_smaller( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose size is smaller than the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_smaller_or_equal.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_smaller_or_equal 2 | 3 | ```rhai 4 | fn only_smaller_or_equal( 5 | self: AllocationList, 6 | threshold: Integer 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new `AllocationList` with only the allocations whose size is smaller or equal to the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/only_temporary.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::only_temporary 2 | 3 | ```rhai 4 | fn only_temporary( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a new `AllocationList` with only temporary allocations. 10 | 11 | A temporary allocation is an allocation which was eventually deallocated. 12 | 13 | Opposite of [`only_leaked`](./only_leaked.md). 14 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/op_and.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::& 2 | 3 | ```rhai 4 | fn &( 5 | lhs: AllocationList, 6 | rhs: AllocationList 7 | ) -> AllocationList 8 | ``` 9 | 10 | Returns a new allocation list with all of the allocations that are both in `lhs` and `rhs`. 11 | 12 | ### Examples 13 | 14 | Here are graphs of two distinct allocation lists: 15 | 16 | ```rhai,%run,%hide-code 17 | graph() 18 | // %hide_next_line 19 | .trim_left() 20 | .add(allocations().only_temporary().only_deallocated_until_at_most(data().runtime() * 0.6)) 21 | .save(); 22 | ``` 23 | 24 | ```rhai,%run,%hide-code 25 | graph() 26 | .add(allocations().only_temporary().only_allocated_after_at_least(data().runtime() * 0.4)) 27 | .save(); 28 | ``` 29 | 30 | And here's how they look when merged through the `&` operator: 31 | 32 | ```rhai,%run 33 | let lhs = allocations() 34 | .only_temporary() 35 | .only_deallocated_until_at_most(data().runtime() * 0.6); 36 | 37 | let rhs = allocations() 38 | .only_temporary() 39 | .only_allocated_after_at_least(data().runtime() * 0.4); 40 | 41 | graph() 42 | .add(lhs & rhs) 43 | .save(); 44 | ``` 45 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/op_square_brackets.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::[] 2 | 3 | ```rhai 4 | fn []( 5 | index: Integer 6 | ) -> Allocation 7 | ``` 8 | 9 | Returns a given [`Allocation`](../Allocation.md) from the list. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println(allocations()[0].backtrace()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/save_as_flamegraph.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::save_as_flamegraph 2 | 3 | ```rhai 4 | fn save_as_flamegraph( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | ```rhai 10 | fn save_as_flamegraph( 11 | self: AllocationList, 12 | path: String 13 | ) -> AllocationList 14 | ``` 15 | 16 | Saves the allocation list as a flamegraph. The `path` argument is optional; if missing the filename will be automatically generated. 17 | 18 | ### Examples 19 | 20 | ```rhai,%run 21 | allocations() 22 | .only_temporary() 23 | .save_as_flamegraph("allocations.svg"); 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/src/api_reference/AllocationList/save_as_graph.md: -------------------------------------------------------------------------------- 1 | ## AllocationList::save_as_graph 2 | 3 | ```rhai 4 | fn save_as_graph( 5 | self: AllocationList 6 | ) -> AllocationList 7 | ``` 8 | 9 | ```rhai 10 | fn save_as_graph( 11 | self: AllocationList, 12 | path: String 13 | ) -> AllocationList 14 | ``` 15 | 16 | Saves the allocation list as a graph. The `path` argument is optional; if missing the filename will be automatically generated. 17 | 18 | ### Examples 19 | 20 | ```rhai,%run 21 | allocations() 22 | .only_temporary() 23 | .save_as_graph("allocations.svg"); 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/src/api_reference/Backtrace.md: -------------------------------------------------------------------------------- 1 | # Backtrace 2 | 3 | `Backtrace` is an object representing a single backtrace. 4 | -------------------------------------------------------------------------------- /docs/src/api_reference/Backtrace/strip.md: -------------------------------------------------------------------------------- 1 | ## Backtrace::strip 2 | 3 | ```rhai 4 | fn strip( 5 | self: Backtrace 6 | ) -> Backtrace 7 | ``` 8 | 9 | Strips out useless junk from the backtrace. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | let groups = allocations().group_by_backtrace().sort_by_size(); 15 | let backtrace = groups[0][0].backtrace(); 16 | 17 | println("Before:"); 18 | println(backtrace); 19 | 20 | println(); 21 | println("After:"); 22 | println(backtrace.strip()); 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/src/api_reference/Data.md: -------------------------------------------------------------------------------- 1 | # Data 2 | 3 | `Data` is an object which holds a loaded data file. 4 | 5 | You can either use [`data`](./globals/data.md) to access the currently loaded data file, 6 | or you can use [`load`](./globals/load.md) to load one. 7 | -------------------------------------------------------------------------------- /docs/src/api_reference/Data/allocations.md: -------------------------------------------------------------------------------- 1 | ## Data::allocations 2 | 3 | ```rhai 4 | fn allocation( 5 | self: Data 6 | ) -> AllocationList 7 | ``` 8 | 9 | Returns a list of all of the allocations for this data file. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/Data/runtime.md: -------------------------------------------------------------------------------- 1 | ## Data::runtime 2 | 3 | ```rhai 4 | fn runtime( 5 | self: Data 6 | ) -> Duration 7 | ``` 8 | 9 | Returns the whole duration of the runtime as measured from the start of profiling. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/Duration.md: -------------------------------------------------------------------------------- 1 | # Duration 2 | 3 | `Duration` is an object which represents a span of time. 4 | 5 | Usually you'd use one of these functions to create one: 6 | 7 | - [h](./globals/h.md) 8 | - [m](./globals/m.md) 9 | - [s](./globals/s.md) 10 | - [ms](./globals/ms.md) 11 | - [us](./globals/us.md) 12 | - [Data::runtime](./Data/runtime.md) 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/Duration/op_minus.md: -------------------------------------------------------------------------------- 1 | ## Duration::- 2 | 3 | ```rhai 4 | fn -( 5 | lhs: Duration, 6 | rhs: Duration 7 | ) -> Duration 8 | ``` 9 | 10 | Subtracts two durations together. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/Duration/op_multiply.md: -------------------------------------------------------------------------------- 1 | ## Duration::* 2 | 3 | ```rhai 4 | fn *( 5 | lhs: Integer|Float, 6 | rhs: Duration 7 | ) -> Duration 8 | ``` 9 | 10 | ```rhai 11 | fn *( 12 | lhs: Duration, 13 | rhs: Integer|Float 14 | ) -> Duration 15 | ``` 16 | 17 | Multiplies a given duration by a number. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/Duration/op_plus.md: -------------------------------------------------------------------------------- 1 | ## Duration::+ 2 | 3 | ```rhai 4 | fn +( 5 | lhs: Duration, 6 | rhs: Duration 7 | ) -> Duration 8 | ``` 9 | 10 | Adds two durations together. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph.md: -------------------------------------------------------------------------------- 1 | # Graph 2 | 3 | `Graph` is a builder object used to render an allocation graph. 4 | 5 | Use [`graph`](./globals/graph.md) to construct a new instance. 6 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/add.md: -------------------------------------------------------------------------------- 1 | ## Graph::add 2 | 3 | ```rhai 4 | fn add( 5 | self: Graph, 6 | list: AllocationList|AllocationGroupList|MapList 7 | ) -> Graph 8 | ``` 9 | 10 | ```rhai 11 | fn add( 12 | self: Graph, 13 | series_name: String, 14 | list: AllocationList|MapList 15 | ) -> Graph 16 | ``` 17 | 18 | Adds a new series to the graph with the given `list`. 19 | 20 | If you add multiple allocation lists the graph will become an area graph, where every extra `add` will 21 | only add new allocations to the graph which were not present in any of the previously added lists. 22 | 23 | A single graph can either show allocations, or maps. Mixing both in a single graph is not supported. 24 | 25 | ### Examples 26 | 27 | ```rhai,%run 28 | graph() 29 | // %hide_next_line 30 | .trim() 31 | .add("Only leaked", allocations().only_leaked()) 32 | .add("Remaining", allocations()) 33 | .save(); 34 | ``` 35 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/end_at.md: -------------------------------------------------------------------------------- 1 | ## Graph::end_at 2 | 3 | ```rhai 4 | fn end_at( 5 | self: Graph, 6 | duration: Duration 7 | ) -> Graph 8 | ``` 9 | 10 | Truncate or extend the graph until given `duration` as measured from the start of the profiling. 11 | 12 | ### Examples 13 | 14 | Assuming we have the following graph: 15 | 16 | ```rhai,%run 17 | graph() 18 | // %hide_next_line 19 | .trim_left() 20 | .add(allocations()) 21 | .save(); 22 | ``` 23 | 24 | We can truncate it like this: 25 | 26 | ```rhai,%run 27 | graph() 28 | // %hide_next_line 29 | .trim_left() 30 | .add(allocations()) 31 | .end_at(data().runtime() - s(2)) 32 | .save(); 33 | ``` 34 | 35 | It can also be used to extend the graph: 36 | 37 | ```rhai,%run 38 | graph() 39 | // %hide_next_line 40 | .trim_left() 41 | .add(allocations()) 42 | .end_at(data().runtime() + s(5)) 43 | .save(); 44 | ``` 45 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/only_non_empty_series.md: -------------------------------------------------------------------------------- 1 | ## Graph::only_non_empty_series 2 | 3 | ```rhai 4 | fn only_non_empty_series( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Hides legend entries for any series which are empty. 10 | 11 | ### Examples 12 | 13 | Let's say we have the following code: 14 | 15 | ```rhai,%run 16 | graph() 17 | // %hide_next_line 18 | .trim() 19 | .add("Leaked", allocations().only_leaked()) 20 | .add("Temporary", allocations().only_temporary()) 21 | .add("Remaining", allocations()) 22 | .save(); 23 | ``` 24 | 25 | As we can see we have an extra "Remaining" series which is empty; we can automatically hide it using `only_non_empty_series`: 26 | 27 | ```rhai,%run 28 | graph() 29 | // %hide_next_line 30 | .trim() 31 | .add("Leaked", allocations().only_leaked()) 32 | .add("Temporary", allocations().only_temporary()) 33 | .add("Remaining", allocations()) 34 | .only_non_empty_series() 35 | .save(); 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/save.md: -------------------------------------------------------------------------------- 1 | ## Graph::save 2 | 3 | ```rhai 4 | fn save( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | ```rhai 10 | fn save( 11 | self: Graph, 12 | path: String 13 | ) -> Graph 14 | ``` 15 | 16 | Saves the graph to a file. The `path` argument is optional; if missing the filename will be automatically generated. 17 | 18 | ### Examples 19 | 20 | ```rhai,%run 21 | graph() 22 | .add(allocations()) 23 | .save("allocations.svg"); 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/save_each_series_as_flamegraph.md: -------------------------------------------------------------------------------- 1 | ## Graph::save_each_series_as_flamegraph 2 | 3 | ```rhai 4 | fn save_each_series_as_flamegraph( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | ```rhai 10 | fn save_each_series_as_flamegraph( 11 | self: Graph, 12 | output_directory: String 13 | ) -> Graph 14 | ``` 15 | 16 | Saves each series of the graph into a separate file as a flamegraph. The `output_directory` argument is optional; 17 | if missing the files will be generated in the current directory. 18 | 19 | ### Examples 20 | 21 | ```rhai,%run 22 | graph() 23 | .add("Temporary", allocations().only_temporary()) 24 | .add("Leaked", allocations().only_leaked()) 25 | .save_each_series_as_flamegraph(); 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/save_each_series_as_graph.md: -------------------------------------------------------------------------------- 1 | ## Graph::save_each_series_as_graph 2 | 3 | ```rhai 4 | fn save_each_series_as_graph( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | ```rhai 10 | fn save_each_series_as_graph( 11 | self: Graph, 12 | output_directory: String 13 | ) -> Graph 14 | ``` 15 | 16 | Saves each series of the graph into a separate file. The `output_directory` argument is optional; 17 | if missing the files will be generated in the current directory. 18 | 19 | ### Examples 20 | 21 | ```rhai,%run 22 | graph() 23 | // %hide_next_line 24 | .trim_left() 25 | .add("Temporary", allocations().only_temporary()) 26 | .add("Leaked", allocations().only_leaked()) 27 | .save_each_series_as_graph(); 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/show_address_space.md: -------------------------------------------------------------------------------- 1 | ## Graph::show_address_space 2 | 3 | ```rhai 4 | fn show_address_space( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Configures the graph to show maps' used address space. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | graph() 15 | // %hide_next_line 16 | .trim() 17 | .add(maps()) 18 | .show_address_space() 19 | .save(); 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/show_deallocations.md: -------------------------------------------------------------------------------- 1 | ## Graph::show_deallocations 2 | 3 | ```rhai 4 | fn show_deallocations( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Configures the graph to show deallocations. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | graph() 15 | // %hide_next_line 16 | .trim() 17 | .add(allocations()) 18 | .show_deallocations() 19 | .save(); 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/show_live_allocations.md: -------------------------------------------------------------------------------- 1 | ## Graph::show_live_allocations 2 | 3 | ```rhai 4 | fn show_live_allocations( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Configures the graph to show the number of allocations which are alive. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | graph() 15 | // %hide_next_line 16 | .trim() 17 | .add(allocations()) 18 | .show_live_allocations() 19 | .save(); 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/show_memory_usage.md: -------------------------------------------------------------------------------- 1 | ## Graph::show_memory_usage 2 | 3 | ```rhai 4 | fn show_memory_usage( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Configures the graph to show memory usage. 10 | 11 | This is the default. 12 | 13 | ### Examples 14 | 15 | ```rhai,%run 16 | graph() 17 | // %hide_next_line 18 | .trim() 19 | .add(allocations()) 20 | .show_memory_usage() 21 | .save(); 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/show_new_allocations.md: -------------------------------------------------------------------------------- 1 | ## Graph::show_new_allocations 2 | 3 | ```rhai 4 | fn show_new_allocations( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Configures the graph to show new allocations. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | graph() 15 | // %hide_next_line 16 | .trim() 17 | .add(allocations()) 18 | .show_new_allocations() 19 | .save(); 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/show_rss.md: -------------------------------------------------------------------------------- 1 | ## Graph::show_rss 2 | 3 | ```rhai 4 | fn show_rss( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Configures the graph to show maps' RSS. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | graph() 15 | // %hide_next_line 16 | .trim() 17 | .add(maps()) 18 | .show_rss() 19 | .save(); 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/start_at.md: -------------------------------------------------------------------------------- 1 | ## Graph::start_at 2 | 3 | ```rhai 4 | fn start_at( 5 | self: Graph, 6 | duration: Duration 7 | ) -> Graph 8 | ``` 9 | 10 | Make the graph start after the given `duration` as measured from the start of the profiling. 11 | 12 | ### Examples 13 | 14 | Assuming we have the following graph: 15 | 16 | ```rhai,%run 17 | graph() 18 | // %hide_next_line 19 | .trim_left() 20 | .add(allocations()) 21 | .save(); 22 | ``` 23 | 24 | We can make it start later like this: 25 | 26 | ```rhai,%run 27 | graph() 28 | // %hide_next_line 29 | .trim_left() 30 | .add(allocations()) 31 | .start_at(s(2)) 32 | .save(); 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/trim.md: -------------------------------------------------------------------------------- 1 | ## Graph::trim 2 | 3 | ```rhai 4 | fn trim_right( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Trims any empty space on both sides of the graph. 10 | 11 | ### Examples 12 | 13 | Here's a graph which has a significant amount of empty on both sides: 14 | 15 | ```rhai,%run,%hide-code 16 | let xs = allocations() 17 | .only_allocated_after_at_least(data().runtime() * 0.25) 18 | .only_deallocated_until_at_most(data().runtime() * 0.75); 19 | 20 | graph() 21 | .add(xs) 22 | .save(); 23 | ``` 24 | 25 | By applying `trim` to it here's how it'll look like: 26 | 27 | ```rhai,%run,%hide-code 28 | let xs = allocations() 29 | .only_allocated_after_at_least(data().runtime() * 0.25) 30 | .only_deallocated_until_at_most(data().runtime() * 0.75); 31 | 32 | graph() 33 | .trim() 34 | .add(xs) 35 | .save(); 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/trim_left.md: -------------------------------------------------------------------------------- 1 | ## Graph::trim_left 2 | 3 | ```rhai 4 | fn trim_left( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Trims any empty space in the left portion of the graph. 10 | 11 | ### Examples 12 | 13 | Here's a graph which has a significant amount of empty space at the start with no allocations: 14 | 15 | ```rhai,%run,%hide-code 16 | graph() 17 | .trim_right() 18 | .add(allocations().only_allocated_after_at_least(data().runtime() * 0.25)) 19 | .save(); 20 | ``` 21 | 22 | By applying `trim_left` to it here's how it'll look like: 23 | 24 | ```rhai,%run,%hide-code 25 | graph() 26 | .trim_right() 27 | .trim_left() 28 | .add(allocations().only_allocated_after_at_least(data().runtime() * 0.25)) 29 | .save(); 30 | ``` 31 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/trim_right.md: -------------------------------------------------------------------------------- 1 | ## Graph::trim_right 2 | 3 | ```rhai 4 | fn trim_right( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Trims any empty space in the right portion of the graph. 10 | 11 | ### Examples 12 | 13 | Here's a graph which has a significant amount of empty space at the end: 14 | 15 | ```rhai,%run,%hide-code 16 | graph() 17 | .trim_left() 18 | .add(allocations().only_deallocated_until_at_most(data().runtime() * 0.75)) 19 | .save(); 20 | ``` 21 | 22 | By applying `trim_right` to it here's how it'll look like: 23 | 24 | ```rhai,%run,%hide-code 25 | graph() 26 | .trim_left() 27 | .trim_right() 28 | .add(allocations().only_deallocated_until_at_most(data().runtime() * 0.75)) 29 | .save(); 30 | ``` 31 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/with_gradient_color_scheme.md: -------------------------------------------------------------------------------- 1 | ## Graph::with_gradient_color_scheme 2 | 3 | ```rhai 4 | fn with_gradient_color_scheme( 5 | self: Graph, 6 | start: String, 7 | end: String 8 | ) -> Graph 9 | ``` 10 | 11 | Sets the graph color scheme so that the bottommost series is of the `start` color 12 | and the topmost series is of the `end` color. 13 | 14 | ### Examples 15 | 16 | ```rhai,%run 17 | let xs = allocations().only_temporary(); 18 | graph() 19 | // %hide_next_line 20 | .trim() 21 | .add(xs.only_alive_for_at_least(data().runtime() * 0.8)) 22 | .add(xs.only_alive_for_at_least(data().runtime() * 0.7)) 23 | .add(xs.only_alive_for_at_least(data().runtime() * 0.6)) 24 | .add(xs.only_alive_for_at_least(data().runtime() * 0.5)) 25 | .add(xs.only_alive_for_at_least(data().runtime() * 0.4)) 26 | .add(xs.only_alive_for_at_least(data().runtime() * 0.3)) 27 | .add(xs.only_alive_for_at_least(data().runtime() * 0.2)) 28 | .add(xs.only_alive_for_at_least(data().runtime() * 0.1)) 29 | .with_gradient_color_scheme("red", "blue") 30 | .save(); 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/without_axes.md: -------------------------------------------------------------------------------- 1 | ## Graph::without_axes 2 | 3 | ```rhai 4 | fn without_axes( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Removes the horizonal and vertical axis of the graph. 10 | 11 | ### Examples 12 | 13 | Before: 14 | 15 | ```rhai,%run 16 | graph() 17 | // %hide_next_line 18 | .trim() 19 | .add(allocations()) 20 | .save(); 21 | ``` 22 | 23 | After: 24 | 25 | ```rhai,%run 26 | graph() 27 | // %hide_next_line 28 | .trim() 29 | .add(allocations()) 30 | .without_axes() 31 | .save(); 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/without_grid.md: -------------------------------------------------------------------------------- 1 | ## Graph::without_grid 2 | 3 | ```rhai 4 | fn without_grid( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Removes the grid from the graph. 10 | 11 | ### Examples 12 | 13 | Before: 14 | 15 | ```rhai,%run 16 | graph() 17 | // %hide_next_line 18 | .trim() 19 | .add(allocations()) 20 | .save(); 21 | ``` 22 | 23 | After: 24 | 25 | ```rhai,%run 26 | graph() 27 | // %hide_next_line 28 | .trim() 29 | .add(allocations()) 30 | .without_grid() 31 | .save(); 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/src/api_reference/Graph/without_legend.md: -------------------------------------------------------------------------------- 1 | ## Graph::without_legend 2 | 3 | ```rhai 4 | fn without_legend( 5 | self: Graph 6 | ) -> Graph 7 | ``` 8 | 9 | Removes the legend from the graph. 10 | 11 | ### Examples 12 | 13 | Before: 14 | 15 | ```rhai,%run 16 | graph() 17 | // %hide_next_line 18 | .trim() 19 | .add("Allocations", allocations()) 20 | .save(); 21 | ``` 22 | 23 | After: 24 | 25 | ```rhai,%run 26 | graph() 27 | // %hide_next_line 28 | .trim() 29 | .add("Allocations", allocations()) 30 | .without_legend() 31 | .save(); 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/src/api_reference/Map.md: -------------------------------------------------------------------------------- 1 | # Map 2 | 3 | `Map` is an object representing a single map. 4 | -------------------------------------------------------------------------------- /docs/src/api_reference/Map/allocated_at.md: -------------------------------------------------------------------------------- 1 | ## Map::allocated_at 2 | 3 | ```rhai 4 | fn allocated_at( 5 | self: Map 6 | ) -> Duration 7 | ``` 8 | 9 | Returns when this map was mapped, as a time offset from the start of the profiling. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println(maps()[0].allocated_at()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/Map/backtrace.md: -------------------------------------------------------------------------------- 1 | ## Map::backtrace 2 | 3 | ```rhai 4 | fn backtrace( 5 | self: Map 6 | ) -> Option 7 | ``` 8 | 9 | Returns the backtrace of this map. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println(maps()[0].backtrace()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/Map/deallocated_at.md: -------------------------------------------------------------------------------- 1 | ## Map::deallocated_at 2 | 3 | ```rhai 4 | fn deallocated_at( 5 | self: Map 6 | ) -> Option 7 | ``` 8 | 9 | Returns when this map was unmapped, as a time offset from the start of the profiling. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println((maps().only_leaked())[0].deallocated_at()); 15 | println((maps().only_temporary())[0].deallocated_at()); 16 | ``` 17 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList.md: -------------------------------------------------------------------------------- 1 | # MapList 2 | 3 | `MapList` is an object which holds a list of maps. 4 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/len.md: -------------------------------------------------------------------------------- 1 | ## MapList::len 2 | 3 | ```rhai 4 | fn len( 5 | self: MapList 6 | ) -> Integer 7 | ``` 8 | 9 | Returns the number of maps within the list. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println(maps().len()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_address_at_least.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_address_at_least 2 | 3 | ```rhai 4 | fn only_address_at_least( 5 | self: MapList, 6 | address: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose address is equal or higher than the one specified. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_address_at_most.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_address_at_most 2 | 3 | ```rhai 4 | fn only_address_at_most( 5 | self: MapList, 6 | address: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose address is equal or lower than the one specified. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_alive_at.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_alive_at 2 | 3 | ```rhai 4 | fn only_alive_at( 5 | self: MapList, 6 | durations: [Duration] 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that were alive at all 11 | of the times specified by `durations` as measured from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_alive_for_at_least.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_alive_for_at_least 2 | 3 | ```rhai 4 | fn only_alive_for_at_least( 5 | self: MapList, 6 | duration: Duration 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that were alive for at least the given `duration`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_alive_for_at_most.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_alive_for_at_most 2 | 3 | ```rhai 4 | fn only_alive_for_at_most( 5 | self: MapList, 6 | duration: Duration 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that were alive for at most the given `duration`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_allocated_after_at_least.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_allocated_after_at_least 2 | 3 | ```rhai 4 | fn only_allocated_after_at_least( 5 | self: MapList, 6 | duration: Duration 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that were mapped after at least `duration` 11 | from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_allocated_until_at_most.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_allocated_until_at_most 2 | 3 | ```rhai 4 | fn only_allocated_until_at_most( 5 | self: MapList, 6 | duration: Duration 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that were mapped until at most `duration` 11 | from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_backtrace_length_at_least.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_backtrace_length_at_least 2 | 3 | ```rhai 4 | fn only_backtrace_length_at_least( 5 | self: MapList, 6 | threshold: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that have a backtrace which has at least `threshold` many frames. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_backtrace_length_at_most.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_backtrace_length_at_most 2 | 3 | ```rhai 4 | fn only_backtrace_length_at_most( 5 | self: MapList, 6 | threshold: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that have a backtrace which has at most `threshold` many frames. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_bytehound.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_bytehound 2 | 3 | ```rhai 4 | fn only_bytehound( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were mapped by Bytehound itself. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_deallocated_after_at_least.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_deallocated_after_at_least 2 | 3 | ```rhai 4 | fn only_deallocated_after_at_least( 5 | self: MapList, 6 | duration: Duration 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that were unmapped after at least `duration` 11 | from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_deallocated_until_at_most.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_deallocated_until_at_most 2 | 3 | ```rhai 4 | fn only_deallocated_until_at_most( 5 | self: MapList, 6 | duration: Duration 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that were unmapped until at most `duration` 11 | from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_executable.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_executable 2 | 3 | ```rhai 4 | fn only_executable( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were mapped with the executable flag set. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_jemalloc.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_jemalloc 2 | 3 | ```rhai 4 | fn only_jemalloc( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were mapped by jemalloc. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_larger.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_larger 2 | 3 | ```rhai 4 | fn only_larger( 5 | self: MapList, 6 | threshold: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose size (address space) is larger than the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_larger_or_equal.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_larger_or_equal 2 | 3 | ```rhai 4 | fn only_larger_or_equal( 5 | self: MapList, 6 | threshold: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose size (address space) is larger or equal to the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_leaked.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_leaked 2 | 3 | ```rhai 4 | fn only_leaked( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only leaked maps. 10 | 11 | Opposite of [`only_temporary`](./only_temporary.md). 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_leaked_or_deallocated_after.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_leaked_or_deallocated_after 2 | 3 | ```rhai 4 | fn only_leaked_or_deallocated_after( 5 | self: MapList, 6 | duration: Duration 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps that were either leaked or unmapped 11 | after `duration` from the start of profiling. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_matching_backtraces.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_matching_backtraces 2 | 3 | ```rhai 4 | fn only_matching_backtraces( 5 | self: MapList, 6 | backtrace_ids: [Backtrace|AllocationList|MapList|AllocationGroupList|Integer] 7 | ) -> MapList 8 | ``` 9 | 10 | ```rhai 11 | fn only_matching_backtraces( 12 | self: MapList, 13 | backtrace_ids: Backtrace|AllocationList|MapList|AllocationGroupList|Integer 14 | ) -> MapList 15 | ``` 16 | 17 | Returns a new `MapList` with only the maps that come from one of the given `backtrace_ids`. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_matching_deallocation_backtraces.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_matching_deallocation_backtraces 2 | 3 | ```rhai 4 | fn only_matching_deallocation_backtraces( 5 | self: MapList, 6 | backtrace_ids: [Backtrace|AllocationList|MapList|AllocationGroupList|Integer] 7 | ) -> MapList 8 | ``` 9 | 10 | ```rhai 11 | fn only_matching_deallocation_backtraces( 12 | self: MapList, 13 | backtrace_ids: Backtrace|AllocationList|MapList|AllocationGroupList|Integer 14 | ) -> MapList 15 | ``` 16 | 17 | Returns a new `MapList` with only the maps that were unmapped at one of the given `backtrace_ids`. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_not_bytehound.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_not_bytehound 2 | 3 | ```rhai 4 | fn only_not_bytehound( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were not mapped by Bytehound itself. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_not_executable.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_not_executable 2 | 3 | ```rhai 4 | fn only_not_executable( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were mapped without the executable flag set. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_not_jemalloc.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_not_jemalloc 2 | 3 | ```rhai 4 | fn only_not_jemalloc( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were not mapped by jemalloc. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_not_matching_backtraces.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_not_matching_backtraces 2 | 3 | ```rhai 4 | fn only_not_matching_backtraces( 5 | self: MapList, 6 | backtrace_ids: [Backtrace|AllocationList|MapList|AllocationGroupList|Integer] 7 | ) -> MapList 8 | ``` 9 | 10 | ```rhai 11 | fn only_not_matching_backtraces( 12 | self: MapList, 13 | backtrace_ids: Backtrace|AllocationList|MapList|AllocationGroupList|Integer 14 | ) -> MapList 15 | ``` 16 | 17 | Returns a new `MapList` with only the maps that do not come from one of the given `backtrace_ids`. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_not_matching_deallocation_backtraces.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_not_matching_deallocation_backtraces 2 | 3 | ```rhai 4 | fn only_not_matching_deallocation_backtraces( 5 | self: MapList, 6 | backtrace_ids: [Backtrace|AllocationList|MapList|AllocationGroupList|Integer] 7 | ) -> MapList 8 | ``` 9 | 10 | ```rhai 11 | fn only_not_matching_deallocation_backtraces( 12 | self: MapList, 13 | backtrace_ids: Backtrace|AllocationList|MapList|AllocationGroupList|Integer 14 | ) -> MapList 15 | ``` 16 | 17 | Returns a new `MapList` with only the maps that were not unmapped at one of the given `backtrace_ids`. 18 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_not_passing_through_function.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_not_passing_through_function 2 | 3 | ```rhai 4 | fn only_not_passing_through_function( 5 | self: MapList, 6 | regex: String 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose backtrace does **not** contain a function which matches a given regex. 11 | 12 | The flavor of regexps used here is the same as Rust's [`regex` crate](https://docs.rs/regex). -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_not_passing_through_source.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_not_passing_through_source 2 | 3 | ```rhai 4 | fn only_not_passing_through_source( 5 | self: MapList, 6 | regex: String 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose backtrace does **not** contain a frame which passes through a source file which matches a given regex. 11 | 12 | The flavor of regexps used here is the same as Rust's [`regex` crate](https://docs.rs/regex). 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_not_readable.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_not_readable 2 | 3 | ```rhai 4 | fn only_not_readable( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were mapped without the readable flag set. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_not_writable.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_not_writable 2 | 3 | ```rhai 4 | fn only_not_writable( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were mapped without the writable flag set. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_passing_through_function.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_passing_through_function 2 | 3 | ```rhai 4 | fn only_passing_through_function( 5 | self: MapList, 6 | regex: String 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose backtrace contains a function which matches a given regex. 11 | 12 | The flavor of regexps used here is the same as Rust's [`regex` crate](https://docs.rs/regex). 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_passing_through_source.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_passing_through_source 2 | 3 | ```rhai 4 | fn only_passing_through_source( 5 | self: MapList, 6 | regex: String 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose backtrace contains a frame which passes through a source file which matches a given regex. 11 | 12 | The flavor of regexps used here is the same as Rust's [`regex` crate](https://docs.rs/regex). 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_peak_rss_at_least.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_peak_rss_at_least 2 | 3 | ```rhai 4 | fn only_peak_rss_at_least( 5 | self: MapList, 6 | threshold: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only those maps whose peak RSS is at least the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_peak_rss_at_most.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_peak_rss_at_most 2 | 3 | ```rhai 4 | fn only_peak_rss_at_most( 5 | self: MapList, 6 | threshold: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only those maps whose peak RSS is at most the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_readable.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_readable 2 | 3 | ```rhai 4 | fn only_readable( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were mapped with the readable flag set. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_smaller.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_smaller 2 | 3 | ```rhai 4 | fn only_smaller( 5 | self: MapList, 6 | threshold: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose size (address space) is smaller than the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_smaller_or_equal.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_smaller_or_equal 2 | 3 | ```rhai 4 | fn only_smaller_or_equal( 5 | self: MapList, 6 | threshold: Integer 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new `MapList` with only the maps whose size (address space) is smaller or equal to the given `threshold`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_temporary.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_temporary 2 | 3 | ```rhai 4 | fn only_temporary( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only temporary maps. 10 | 11 | Opposite of [`only_leaked`](./only_leaked.md). 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/only_writable.md: -------------------------------------------------------------------------------- 1 | ## MapList::only_writable 2 | 3 | ```rhai 4 | fn only_writable( 5 | self: MapList 6 | ) -> MapList 7 | ``` 8 | 9 | Returns a new `MapList` with only maps which were mapped with the writable flag set. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/op_and.md: -------------------------------------------------------------------------------- 1 | ## MapList::& 2 | 3 | ```rhai 4 | fn &( 5 | lhs: MapList, 6 | rhs: MapList 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new map list with all of the maps that are both in `lhs` and `rhs`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/op_minus.md: -------------------------------------------------------------------------------- 1 | ## MapList::- 2 | 3 | ```rhai 4 | fn -( 5 | lhs: MapList, 6 | rhs: MapList 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new map list with all of the maps from `lhs` which are not present in `rhs`. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/op_plus.md: -------------------------------------------------------------------------------- 1 | ## MapList::+ 2 | 3 | ```rhai 4 | fn +( 5 | lhs: MapList, 6 | rhs: MapList 7 | ) -> MapList 8 | ``` 9 | 10 | Returns a new map list with all of the maps from `lhs` and `rhs` combined. 11 | -------------------------------------------------------------------------------- /docs/src/api_reference/MapList/op_square_brackets.md: -------------------------------------------------------------------------------- 1 | ## MapList::[] 2 | 3 | ```rhai 4 | fn []( 5 | index: Integer 6 | ) -> Map 7 | ``` 8 | 9 | Returns a given [`Map`](../Map.md) from the list. 10 | 11 | ### Examples 12 | 13 | ```rhai,%run 14 | println(maps()[0].backtrace()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals.md: -------------------------------------------------------------------------------- 1 | # Globally available functions 2 | 3 | These are the functions that are globally defined and can be called anywhere. 4 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/allocations.md: -------------------------------------------------------------------------------- 1 | ## allocations 2 | 3 | ```rhai 4 | fn allocations() -> AllocationList 5 | ``` 6 | 7 | Returns an allocation list of the the currently globally loaded data file; equivalent to `data().allocations()`. 8 | 9 | If there is no globally loaded data file then it will throw an exception. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/argv.md: -------------------------------------------------------------------------------- 1 | ## argv 2 | 3 | ```rhai 4 | fn argv() -> [String] 5 | ``` 6 | 7 | Returns a list of arguments passed on the command-line. 8 | 9 | Makes sense only for scripts executed through the `script` subcommand. 10 | For scripts executed from the scripting console this will always return 11 | an empty array. 12 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/chdir.md: -------------------------------------------------------------------------------- 1 | ## chdir 2 | 3 | ```rhai 4 | fn chdir( 5 | path: String 6 | ) 7 | ``` 8 | 9 | Changes the current directory to the given `path`. 10 | 11 | Will physically change the current directory only for scripts executed through the `script` subcommand. 12 | For scripts executed from the scripting console no access to the local filesystem is provided, 13 | and a virtual filesystem will be simulated instead. 14 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/data.md: -------------------------------------------------------------------------------- 1 | ## data 2 | 3 | ```rhai 4 | fn data() -> Data 5 | ``` 6 | 7 | Return the currently globally loaded data file. 8 | 9 | When running the script through the scripting console this will return whatever data 10 | you currently have loaded. When running through the `script` subcommand it will return 11 | the data file specified with the `--data` parameter; if it wasn't specified then it 12 | will throw an exception. -------------------------------------------------------------------------------- /docs/src/api_reference/globals/dirname.md: -------------------------------------------------------------------------------- 1 | ## dirname 2 | 3 | ```rhai 4 | fn dirname( 5 | path: String 6 | ) -> String 7 | ``` 8 | 9 | Returns the given path without its final component. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/exit.md: -------------------------------------------------------------------------------- 1 | ## exit 2 | 3 | ```rhai 4 | fn exit() 5 | ``` 6 | 7 | ```rhai 8 | fn exit( 9 | status_code: Integer 10 | ) -> Duration 11 | ``` 12 | 13 | Immediately aborts execution with the given `status_code`. 14 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/gb.md: -------------------------------------------------------------------------------- 1 | ## gb 2 | 3 | ```rhai 4 | fn gb( 5 | value: Integer 6 | ) -> Integer 7 | ``` 8 | 9 | A convenience function equivalent to `value * 1000 * 1000 * 1000`. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/graph.md: -------------------------------------------------------------------------------- 1 | ## graph 2 | 3 | ```rhai 4 | fn graph() -> Graph 5 | ``` 6 | 7 | Constructs a new [`Graph`](../Graph.md) object. 8 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/h.md: -------------------------------------------------------------------------------- 1 | ## h 2 | 3 | ```rhai 4 | fn h( 5 | hours: Integer|Float 6 | ) -> Duration 7 | ``` 8 | 9 | Returns a new [`Duration`](../Duration.md) with the specified number of `hours`. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/info.md: -------------------------------------------------------------------------------- 1 | ## info 2 | 3 | ```rhai 4 | fn info( 5 | message: String 6 | ) 7 | ``` 8 | 9 | Generates an info print; only visible on the command-line. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/kb.md: -------------------------------------------------------------------------------- 1 | ## kb 2 | 3 | ```rhai 4 | fn kb( 5 | value: Integer 6 | ) -> Integer 7 | ``` 8 | 9 | A convenience function equivalent to `value * 1000`. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/load.md: -------------------------------------------------------------------------------- 1 | ## load 2 | 3 | ```rhai 4 | fn load( 5 | path: String 6 | ) -> Data 7 | ``` 8 | 9 | Loads a new data file from the given path. 10 | 11 | Makes sense only for scripts executed through the `script` subcommand. 12 | Will throw an exception when called from the scripting console. 13 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/m.md: -------------------------------------------------------------------------------- 1 | ## m 2 | 3 | ```rhai 4 | fn m( 5 | minutes: Integer|Float 6 | ) -> Duration 7 | ``` 8 | 9 | Returns a new [`Duration`](../Duration.md) with the specified number of `minutes`. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/maps.md: -------------------------------------------------------------------------------- 1 | ## allocations 2 | 3 | ```rhai 4 | fn maps() -> MapList 5 | ``` 6 | 7 | Returns a map list of the the currently globally loaded data file; equivalent to `data().maps()`. 8 | 9 | If there is no globally loaded data file then it will throw an exception. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/mb.md: -------------------------------------------------------------------------------- 1 | ## mb 2 | 3 | ```rhai 4 | fn mb( 5 | value: Integer 6 | ) -> Integer 7 | ``` 8 | 9 | A convenience function equivalent to `value * 1000 * 1000`. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/mkdir_p.md: -------------------------------------------------------------------------------- 1 | ## mkdir_p 2 | 3 | ```rhai 4 | fn mkdir_p( 5 | path: String 6 | ) 7 | ``` 8 | 9 | Creates a new directory and all of its parent components if they are missing. 10 | 11 | Equivalent to Rust's `std::fs::create_dir_all` or `mkdir -p`. 12 | 13 | Will physically create directories only for scripts executed through the `script` subcommand. 14 | For scripts executed from the scripting console no access to the local filesystem is provided, 15 | and a virtual filesystem will be simulated instead. 16 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/ms.md: -------------------------------------------------------------------------------- 1 | ## ms 2 | 3 | ```rhai 4 | fn ms( 5 | milliseconds: Integer|Float 6 | ) -> Duration 7 | ``` 8 | 9 | Returns a new [`Duration`](../Duration.md) with the specified number of `milliseconds`. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/println.md: -------------------------------------------------------------------------------- 1 | ## println 2 | 3 | ```rhai 4 | fn println() 5 | ``` 6 | 7 | ```rhai 8 | fn println( 9 | value: Any 10 | ) 11 | ``` 12 | 13 | ```rhai 14 | fn println( 15 | format: String, 16 | arg_1: Any 17 | ) 18 | ``` 19 | 20 | ```rhai 21 | fn println( 22 | format: String, 23 | arg_1: Any, 24 | arg_2: Any 25 | ) 26 | ``` 27 | 28 | ```rhai 29 | fn println( 30 | format: String, 31 | arg_1: Any, 32 | arg_2: Any, 33 | arg_3: Any 34 | ) 35 | ``` 36 | 37 | Prints out a given value or message, with optional Rust-like string interpolation. 38 | (At the moment only `{}` is supported in the format string.) 39 | 40 | For scripts executed through the scripting console it will print out the message 41 | directly on the web page; for scripts executed through the `script` subcommand 42 | it will print out the message on stdout. 43 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/s.md: -------------------------------------------------------------------------------- 1 | ## s 2 | 3 | ```rhai 4 | fn s( 5 | seconds: Integer|Float 6 | ) -> Duration 7 | ``` 8 | 9 | Returns a new [`Duration`](../Duration.md) with the specified number of `seconds`. 10 | -------------------------------------------------------------------------------- /docs/src/api_reference/globals/us.md: -------------------------------------------------------------------------------- 1 | ## us 2 | 3 | ```rhai 4 | fn us( 5 | microseconds: Integer|Float 6 | ) -> Duration 7 | ``` 8 | 9 | Returns a new [`Duration`](../Duration.md) with the specified number of `microseconds`. 10 | -------------------------------------------------------------------------------- /docs/src/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Is your application leaking memory? Using too much memory? Making too many allocations? 4 | Do you want to figure out why, and where exactly? 5 | 6 | If so you're in the right place! 7 | -------------------------------------------------------------------------------- /fast_range_map/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fast_range_map" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | hashbrown = { version = "0.13", features = ["raw"] } 10 | 11 | [dev-dependencies] 12 | criterion = "0.3" 13 | btree-range-map = "0.3.0" 14 | oorandom = "11.1.3" 15 | rangemap = "1.0.3" 16 | 17 | [[bench]] 18 | name = "rangemaps" 19 | harness = false 20 | -------------------------------------------------------------------------------- /fast_range_map/fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | corpus 3 | artifacts 4 | -------------------------------------------------------------------------------- /fast_range_map/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fast_range_map-fuzz" 3 | version = "0.0.0" 4 | authors = ["Automatically generated"] 5 | publish = false 6 | edition = "2018" 7 | 8 | [package.metadata] 9 | cargo-fuzz = true 10 | 11 | [dependencies] 12 | libfuzzer-sys = "0.4" 13 | rangemap = "1.0.3" 14 | 15 | [dependencies.fast_range_map] 16 | path = ".." 17 | 18 | # Prevent this from interfering with workspaces 19 | [workspace] 20 | members = ["."] 21 | 22 | [[bin]] 23 | name = "fuzz_insert" 24 | path = "fuzz_targets/fuzz_insert.rs" 25 | test = false 26 | doc = false 27 | 28 | [[bin]] 29 | name = "fuzz_remove" 30 | path = "fuzz_targets/fuzz_remove.rs" 31 | test = false 32 | doc = false 33 | -------------------------------------------------------------------------------- /fast_range_map/fuzz/fuzz_targets/fuzz_insert.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | use libfuzzer_sys::fuzz_target; 3 | 4 | extern crate fast_range_map; 5 | 6 | fuzz_target!( |data: &[u8]| { 7 | let mut map = fast_range_map::RangeMap::new(); 8 | let mut map_sanity = rangemap::RangeMap::new(); 9 | 10 | for (nth, chunk) in data.chunks_exact( 2 ).enumerate() { 11 | let start = chunk[0] as u64; 12 | let length = std::cmp::max( 1, chunk[1] as u64 ); 13 | let end = start + length; 14 | let range = start..end; 15 | map.insert( range.clone(), nth ); 16 | map_sanity.insert( range.clone(), nth ); 17 | } 18 | 19 | let map: Vec< _ > = map.into_vec(); 20 | let map_sanity: Vec< _ > = map_sanity.into_iter().collect(); 21 | assert_eq!( map, map_sanity ); 22 | }); 23 | -------------------------------------------------------------------------------- /fast_range_map/fuzz/fuzz_targets/fuzz_remove.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | use libfuzzer_sys::fuzz_target; 3 | 4 | extern crate fast_range_map; 5 | 6 | fuzz_target!( |data: &[u8]| { 7 | let mut map = fast_range_map::RangeMap::new(); 8 | let mut map_sanity = rangemap::RangeMap::new(); 9 | 10 | map.insert( 0..255, 1 ); 11 | map_sanity.insert( 0..255, 1 ); 12 | 13 | let mut sum = 0; 14 | for chunk in data.chunks_exact( 2 ) { 15 | let start = chunk[0] as u64; 16 | let length = std::cmp::max( 1, chunk[1] as u64 ); 17 | let end = start + length; 18 | let range = start..end; 19 | for (range, _) in map.remove( range.clone() ) { 20 | sum += range.end - range.start; 21 | } 22 | map_sanity.remove( range.clone() ); 23 | } 24 | 25 | let map: Vec< _ > = map.into_vec(); 26 | let map_sanity: Vec< _ > = map_sanity.into_iter().collect(); 27 | assert_eq!( map, map_sanity ); 28 | assert_eq!( sum, 255 - map.iter().map( |(key, _)| key.end - key.start ).sum::< u64 >() ); 29 | }); 30 | -------------------------------------------------------------------------------- /gather/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bytehound-gather" 3 | version = "0.11.0" 4 | authors = ["Jan Bujak "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | clap = { version = "2", default-features = false } 9 | log = "0.4" 10 | chrono = "0.4" 11 | cli-core = { path = "../cli-core" } 12 | -------------------------------------------------------------------------------- /integration-tests/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "integration-tests" 3 | version = "0.1.0" 4 | authors = ["Jan Bujak "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | libc = "0.2" 9 | attohttpc = { version = "0.4", default-features = false } 10 | serde = "1" 11 | serde_json = "1" 12 | serde_derive = "1" 13 | 14 | [features] 15 | default = ["test-wasmtime"] 16 | test-wasmtime = [] 17 | -------------------------------------------------------------------------------- /integration-tests/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!( 3 | "cargo:rustc-env=TARGET={}", 4 | std::env::var( "TARGET" ).unwrap() 5 | ); 6 | } 7 | -------------------------------------------------------------------------------- /integration-tests/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod utils; 3 | 4 | #[cfg(test)] 5 | mod tests; 6 | -------------------------------------------------------------------------------- /integration-tests/test-programs/alloc-in-tls.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Dummy { 6 | Dummy() { 7 | pointer = malloc( 123 ); 8 | } 9 | 10 | ~Dummy() { 11 | free( pointer ); 12 | free( malloc( 333 ) ); 13 | } 14 | 15 | void * pointer = nullptr; 16 | }; 17 | 18 | thread_local Dummy dummy; 19 | 20 | void * thread_main( void * ) { 21 | printf( "%p\n", dummy.pointer ); 22 | return nullptr; 23 | } 24 | 25 | int main() { 26 | printf( "%p\n", dummy.pointer ); 27 | 28 | pthread_t thread; 29 | pthread_create( &thread, nullptr, thread_main, nullptr ); 30 | pthread_join( thread, nullptr ); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /integration-tests/test-programs/backtrace.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void __attribute__ ((noinline)) foo() { 5 | malloc( 123456 ); 6 | 7 | void * buffer[ 32 ]; 8 | const int count = backtrace( buffer, 32 ); 9 | if( count == 0 ) { 10 | exit( 1 ); 11 | } 12 | char ** symbols = backtrace_symbols( buffer, count ); 13 | free( symbols ); 14 | } 15 | 16 | void __attribute__ ((noinline)) bar() { 17 | foo(); 18 | 19 | void * buffer[ 32 ]; 20 | const int count = backtrace( buffer, 32 ); 21 | if( count == 0 ) { 22 | exit( 1 ); 23 | } 24 | char ** symbols = backtrace_symbols( buffer, count ); 25 | free( symbols ); 26 | } 27 | 28 | int main() { 29 | bar(); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /integration-tests/test-programs/basic.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void __attribute__ ((noinline)) foobar() { 5 | void * a0 = malloc( 10 ); 6 | void * a1 = malloc( 100 ); 7 | void * a2 = malloc( 1000 ); 8 | void * a3 = realloc( a2, 10000 ); 9 | void * a4 = calloc( 100, 1000 ); 10 | void * a5 = NULL; 11 | posix_memalign( &a5, 65536, 1000000 ); 12 | void * a6 = mmap( NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ); 13 | 14 | free( a1 ); 15 | munmap( a6, 4096 ); 16 | } 17 | 18 | int main() { 19 | foobar(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /integration-tests/test-programs/cross-thread-alloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void * a0; 6 | void * a1; 7 | void * a2; 8 | 9 | void * thread_main_1( void * ) { 10 | usleep( 100 * 1000 ); 11 | free( a0 ); 12 | 13 | a1 = malloc( 1235 ); 14 | a2 = malloc( 1236 ); 15 | 16 | return NULL; 17 | } 18 | 19 | void * thread_main_2( void * ) { 20 | usleep( 100 * 1000 ); 21 | free( a1 ); 22 | 23 | return NULL; 24 | } 25 | 26 | int main() { 27 | a0 = malloc( 1234 ); 28 | 29 | pthread_t thread_1; 30 | pthread_create( &thread_1, NULL, thread_main_1, NULL ); 31 | pthread_join( thread_1, NULL ); 32 | 33 | pthread_t thread_2; 34 | pthread_create( &thread_2, NULL, thread_main_2, NULL ); 35 | pthread_join( thread_2, NULL ); 36 | 37 | usleep( 100 * 1000 ); 38 | free( a2 ); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /integration-tests/test-programs/cull.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static size_t counter = 1234; 5 | 6 | void __attribute__ ((noinline)) foobar( useconds_t sleep_for ) { 7 | void * a0 = malloc( counter ); 8 | counter += 1; 9 | 10 | if( sleep_for != 0 ) { 11 | usleep( sleep_for ); 12 | free( a0 ); 13 | } 14 | } 15 | 16 | const static useconds_t SLEEP_FOR[3] = { 1, 1000000, 0 }; 17 | 18 | int main() { 19 | for( int i = 0; i < 3; ++i ) { 20 | foobar( SLEEP_FOR[i] ); 21 | } 22 | 23 | void * a0 = malloc( 2000 ); 24 | realloc( a0, 3000 ); 25 | 26 | usleep( 500000 ); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /integration-tests/test-programs/dlopen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef void * (*Callback)(); 5 | 6 | int main() { 7 | usleep( 1000 * 1000 ); 8 | void * lib = dlopen( "./dlopen_so", RTLD_NOW ); 9 | Callback cb = (Callback)dlsym( lib, "function" ); 10 | cb(); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /integration-tests/test-programs/dlopen_so.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void * function() { 4 | return malloc( 123123 ); 5 | } 6 | -------------------------------------------------------------------------------- /integration-tests/test-programs/exit_1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | malloc( 11001 ); 5 | exit( 0 ); 6 | } 7 | -------------------------------------------------------------------------------- /integration-tests/test-programs/exit_2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | malloc( 12001 ); 6 | _exit( 0 ); 7 | } 8 | -------------------------------------------------------------------------------- /integration-tests/test-programs/exit_3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | malloc( 13001 ); 5 | _Exit( 0 ); 6 | } 7 | -------------------------------------------------------------------------------- /integration-tests/test-programs/gather.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | volatile int counter = 10001; 6 | volatile int running = 1; 7 | volatile int has_to_die = 0; 8 | 9 | static void signal_handler_sigusr1( int signal ) { 10 | counter++; 11 | } 12 | 13 | static void signal_handler_sigusr2( int signal ) { 14 | has_to_die = 1; 15 | } 16 | 17 | static void signal_handler_sigint( int signal ) { 18 | running = 0; 19 | } 20 | 21 | int main() { 22 | int last_counter = counter; 23 | malloc( last_counter ); 24 | 25 | signal( SIGUSR1, signal_handler_sigusr1 ); 26 | signal( SIGUSR2, signal_handler_sigusr2 ); 27 | signal( SIGINT, signal_handler_sigint ); 28 | 29 | for( ;; ) { 30 | usleep( 1000 ); 31 | if( counter != last_counter ) { 32 | last_counter = counter; 33 | malloc( last_counter ); 34 | } 35 | 36 | if( !running ) { 37 | return 0; 38 | } 39 | 40 | if( has_to_die ) { 41 | kill( getpid(), SIGKILL ); 42 | for( ;; ) { usleep( 1000 ); } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /integration-tests/test-programs/jemalloc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["jemalloc-common", "jemalloc-v05", "jemalloc-v05-unprefixed"] 3 | -------------------------------------------------------------------------------- /integration-tests/test-programs/jemalloc/jemalloc-common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "jemalloc-common" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | libc = "0.2" 10 | -------------------------------------------------------------------------------- /integration-tests/test-programs/jemalloc/jemalloc-v03/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "jemalloc-v03" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | jemallocator = "0.3.2" 10 | jemalloc-common = { path = "../jemalloc-common" } 11 | 12 | [workspace] 13 | -------------------------------------------------------------------------------- /integration-tests/test-programs/jemalloc/jemalloc-v03/src/main.rs: -------------------------------------------------------------------------------- 1 | #[global_allocator] 2 | static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc; 3 | 4 | fn main() { 5 | unsafe { 6 | jemalloc_common::run_test() 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /integration-tests/test-programs/jemalloc/jemalloc-v05-unprefixed/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "jemalloc-v05-unprefixed" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | jemallocator = { version = "0.5.0", features = ["unprefixed_malloc_on_supported_platforms"] } 10 | jemalloc-common = { path = "../jemalloc-common" } 11 | 12 | [workspace] 13 | -------------------------------------------------------------------------------- /integration-tests/test-programs/jemalloc/jemalloc-v05-unprefixed/src/main.rs: -------------------------------------------------------------------------------- 1 | #[global_allocator] 2 | static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc; 3 | 4 | fn main() { 5 | unsafe { 6 | jemalloc_common::run_test() 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /integration-tests/test-programs/jemalloc/jemalloc-v05/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "jemalloc-v05" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | jemallocator = "0.5.0" 10 | jemalloc-common = { path = "../jemalloc-common" } 11 | 12 | [workspace] 13 | -------------------------------------------------------------------------------- /integration-tests/test-programs/jemalloc/jemalloc-v05/src/main.rs: -------------------------------------------------------------------------------- 1 | #[global_allocator] 2 | static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc; 3 | 4 | fn main() { 5 | unsafe { 6 | jemalloc_common::run_test() 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /integration-tests/test-programs/return-f64.rs: -------------------------------------------------------------------------------- 1 | const CONSTANT: f64 = -3.7206620809969885e-103; 2 | 3 | extern { 4 | fn malloc( size: usize ) -> *const u8; 5 | fn abort() -> !; 6 | } 7 | 8 | #[inline(never)] 9 | #[no_mangle] 10 | fn func_1() -> f64 { 11 | unsafe { malloc( 123456 ); } 12 | CONSTANT 13 | } 14 | 15 | #[inline(never)] 16 | #[no_mangle] 17 | fn func_2() { 18 | if func_1() != CONSTANT { 19 | unsafe { abort(); } 20 | } 21 | } 22 | 23 | fn main() { 24 | func_2(); 25 | } -------------------------------------------------------------------------------- /integration-tests/test-programs/return-opt-u128.rs: -------------------------------------------------------------------------------- 1 | const CONSTANT: u128 = 0xaaaaaaaaaaaaaaaa5555555555555555; 2 | 3 | extern { 4 | fn malloc( size: usize ) -> *const u8; 5 | fn abort() -> !; 6 | } 7 | 8 | #[inline(never)] 9 | #[no_mangle] 10 | fn func_1() -> Option< u128 > { 11 | unsafe { malloc( 123456 ); } 12 | Some( CONSTANT ) 13 | } 14 | 15 | #[inline(never)] 16 | #[no_mangle] 17 | fn func_2() { 18 | if func_1() != Some( CONSTANT ) { 19 | unsafe { abort(); } 20 | } 21 | } 22 | 23 | fn main() { 24 | func_2(); 25 | } -------------------------------------------------------------------------------- /integration-tests/test-programs/spawn-child.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | usleep( 100000 ); 7 | malloc( 10001 ); 8 | 9 | pid_t pid = fork(); 10 | if( pid == 0 ) { 11 | // Child 12 | if (execl("./basic-from-spawn-child", "./basic-from-spawn-child", NULL) == -1) { 13 | return 1; 14 | } 15 | return 0; 16 | } 17 | 18 | waitpid(pid, NULL, 0); 19 | malloc( 10003 ); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /integration-tests/test-programs/wasmtime/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["linking", "interrupt"] 3 | -------------------------------------------------------------------------------- /integration-tests/test-programs/wasmtime/interrupt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "interrupt" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | wasmtime = "0.24" 10 | wasmtime-wasi = "0.24" 11 | wasi-cap-std-sync = "0.24" 12 | anyhow = "1" 13 | -------------------------------------------------------------------------------- /integration-tests/test-programs/wasmtime/interrupt/src/interrupt.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "run") 3 | (loop 4 | br 0) 5 | ) 6 | ) 7 | -------------------------------------------------------------------------------- /integration-tests/test-programs/wasmtime/linking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "linking" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | wasmtime = "0.24" 10 | wasmtime-wasi = "0.24" 11 | wasi-cap-std-sync = "0.24" 12 | anyhow = "1" 13 | -------------------------------------------------------------------------------- /integration-tests/test-programs/wasmtime/linking/src/linking1.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (import "linking2" "double" (func $double (param i32) (result i32))) 3 | (import "linking2" "log" (func $log (param i32 i32))) 4 | (import "linking2" "memory" (memory 1)) 5 | (import "linking2" "memory_offset" (global $offset i32)) 6 | 7 | (func (export "run") 8 | ;; Call into the other module to double our number, and we could print it 9 | ;; here but for now we just drop it 10 | i32.const 2 11 | call $double 12 | drop 13 | 14 | ;; Our `data` segment initialized our imported memory, so let's print the 15 | ;; string there now. 16 | global.get $offset 17 | i32.const 14 18 | call $log 19 | ) 20 | 21 | (data (global.get $offset) "Hello, world!\n") 22 | ) 23 | 24 | -------------------------------------------------------------------------------- /integration-tests/test-programs/wasmtime/linking/src/linking2.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (type $fd_write_ty (func (param i32 i32 i32 i32) (result i32))) 3 | (import "wasi_snapshot_preview1" "fd_write" (func $fd_write (type $fd_write_ty))) 4 | 5 | (func (export "double") (param i32) (result i32) 6 | local.get 0 7 | i32.const 2 8 | i32.mul 9 | ) 10 | 11 | (func (export "log") (param i32 i32) 12 | ;; store the pointer in the first iovec field 13 | i32.const 4 14 | local.get 0 15 | i32.store 16 | 17 | ;; store the length in the first iovec field 18 | i32.const 4 19 | local.get 1 20 | i32.store offset=4 21 | 22 | ;; call the `fd_write` import 23 | i32.const 1 ;; stdout fd 24 | i32.const 4 ;; iovs start 25 | i32.const 1 ;; number of iovs 26 | i32.const 0 ;; where to write nwritten bytes 27 | call $fd_write 28 | drop 29 | ) 30 | 31 | (memory (export "memory") 2) 32 | (global (export "memory_offset") i32 (i32.const 65536)) 33 | ) 34 | -------------------------------------------------------------------------------- /jemallocator/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /jemallocator/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "jemalloc-sys/jemalloc"] 2 | path = jemalloc-sys/jemalloc 3 | url = https://github.com/tikv/jemalloc 4 | branch = v5.2.x 5 | -------------------------------------------------------------------------------- /jemallocator/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.4.1 - 2020-11-16 2 | 3 | - Updated jemalloc to fix deadlock during initialization 4 | - Fixed failure of generating docs on release version 5 | 6 | # 0.4.0 - 2020-07-21 7 | 8 | - Forked from jemallocator master 9 | - Upgraded jemalloc to 5.2.1 (#1) 10 | - Fixed wrong version in generated C header (#1) 11 | - Upgraded project to 2018 edition (#2) 12 | -------------------------------------------------------------------------------- /jemallocator/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Alex Crichton 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /jemallocator/ci/dox.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -ex 4 | 5 | export RUSTDOCFLAGS="--cfg jemallocator_docs" 6 | cargo doc --features alloc_trait 7 | cargo doc -p tikv-jemalloc-sys 8 | cargo doc -p tikv-jemalloc-ctl 9 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-ctl/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Steven Fackler 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-ctl/rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 79 -------------------------------------------------------------------------------- /jemallocator/jemalloc-ctl/src/arenas.rs: -------------------------------------------------------------------------------- 1 | //! Arena operations. 2 | 3 | option! { 4 | narenas[ str: b"arenas.narenas\0", non_str: 2 ] => libc::c_uint | 5 | ops: r | 6 | docs: 7 | /// Current limit on the number of arenas. 8 | /// 9 | /// # Examples 10 | /// 11 | /// ``` 12 | /// # 13 | /// # #[global_allocator] 14 | /// # static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; 15 | /// # 16 | /// # fn main() { 17 | /// use tikv_jemalloc_ctl::arenas; 18 | /// println!("number of arenas: {}", arenas::narenas::read().unwrap()); 19 | /// 20 | /// let arenas_mib = arenas::narenas::mib().unwrap(); 21 | /// println!("number of arenas: {}", arenas_mib.read().unwrap()); 22 | /// # } 23 | /// ``` 24 | mib_docs: /// See [`narenas`]. 25 | } 26 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-ctl/src/config.rs: -------------------------------------------------------------------------------- 1 | //! `jemalloc`'s build-time configuration. 2 | 3 | option! { 4 | malloc_conf[ str: b"config.malloc_conf\0", str: 2 ] => &'static str | 5 | ops: r | 6 | docs: 7 | /// Default run-time options specified during `jemalloc`'s build configuration. 8 | /// 9 | /// The string will be empty unless `--with-malloc-conf` was specified 10 | /// during build configuration. 11 | /// 12 | /// # Examples 13 | /// 14 | /// ``` 15 | /// # #[global_allocator] 16 | /// # static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; 17 | /// # 18 | /// # fn main() { 19 | /// use tikv_jemalloc_ctl::config; 20 | /// let malloc_conf = config::malloc_conf::mib().unwrap(); 21 | /// println!("default malloc conf: {}", malloc_conf.read().unwrap()); 22 | /// # } 23 | /// ``` 24 | mib_docs: /// See [`malloc_conf`]. 25 | } 26 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/configure/VERSION: -------------------------------------------------------------------------------- 1 | 5.2.1-2-g172143a2979d9d948035423ce347e35cd1388fc3 2 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/.autom4te.cfg: -------------------------------------------------------------------------------- 1 | begin-language: "Autoconf-without-aclocal-m4" 2 | args: --no-cache 3 | end-language: "Autoconf-without-aclocal-m4" 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/.cirrus.yml: -------------------------------------------------------------------------------- 1 | env: 2 | CIRRUS_CLONE_DEPTH: 1 3 | ARCH: amd64 4 | 5 | task: 6 | freebsd_instance: 7 | matrix: 8 | image: freebsd-12-0-release-amd64 9 | image: freebsd-11-2-release-amd64 10 | install_script: 11 | - sed -i.bak -e 's,pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly,pkg+http://pkg.FreeBSD.org/\${ABI}/latest,' /etc/pkg/FreeBSD.conf 12 | - pkg upgrade -y 13 | - pkg install -y autoconf gmake 14 | script: 15 | - autoconf 16 | #- ./configure ${COMPILER_FLAGS:+ CC="$CC $COMPILER_FLAGS" CXX="$CXX $COMPILER_FLAGS" } $CONFIGURE_FLAGS 17 | - ./configure 18 | - export JFLAG=`sysctl -n kern.smp.cpus` 19 | - gmake -j${JFLAG} 20 | - gmake -j${JFLAG} tests 21 | - gmake check 22 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/README: -------------------------------------------------------------------------------- 1 | jemalloc is a general purpose malloc(3) implementation that emphasizes 2 | fragmentation avoidance and scalable concurrency support. jemalloc first came 3 | into use as the FreeBSD libc allocator in 2005, and since then it has found its 4 | way into numerous applications that rely on its predictable behavior. In 2010 5 | jemalloc development efforts broadened to include developer support features 6 | such as heap profiling and extensive monitoring/tuning hooks. Modern jemalloc 7 | releases continue to be integrated back into FreeBSD, and therefore versatility 8 | remains critical. Ongoing development efforts trend toward making jemalloc 9 | among the best allocators for a broad range of demanding applications, and 10 | eliminating/mitigating weaknesses that have practical repercussions for real 11 | world applications. 12 | 13 | The COPYING file contains copyright and licensing information. 14 | 15 | The INSTALL file contains information on how to configure, build, and install 16 | jemalloc. 17 | 18 | The ChangeLog file contains a brief summary of changes for each release. 19 | 20 | URL: http://jemalloc.net/ 21 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in autoconf; do 4 | echo "$i" 5 | $i 6 | if [ $? -ne 0 ]; then 7 | echo "Error $? in $i" 8 | exit 1 9 | fi 10 | done 11 | 12 | echo "./configure --enable-autogen $@" 13 | ./configure --enable-autogen $@ 14 | if [ $? -ne 0 ]; then 15 | echo "Error $? in ./configure" 16 | exit 1 17 | fi 18 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/bin/jemalloc.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | prefix=@prefix@ 4 | exec_prefix=@exec_prefix@ 5 | libdir=@libdir@ 6 | 7 | @LD_PRELOAD_VAR@=${libdir}/libjemalloc.@SOREV@ 8 | export @LD_PRELOAD_VAR@ 9 | exec "$@" 10 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/config.stamp.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/jemallocator/jemalloc-sys/jemalloc/config.stamp.in -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/doc/html.xsl.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/doc/manpages.xsl.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/doc/stylesheet.xsl: -------------------------------------------------------------------------------- 1 | 2 | ansi 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/arena_structs_a.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_ARENA_STRUCTS_A_H 2 | #define JEMALLOC_INTERNAL_ARENA_STRUCTS_A_H 3 | 4 | #include "jemalloc/internal/bitmap.h" 5 | 6 | struct arena_slab_data_s { 7 | /* Per region allocated/deallocated bitmap. */ 8 | bitmap_t bitmap[BITMAP_GROUPS_MAX]; 9 | }; 10 | 11 | #endif /* JEMALLOC_INTERNAL_ARENA_STRUCTS_A_H */ 12 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/base_externs.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BASE_EXTERNS_H 2 | #define JEMALLOC_INTERNAL_BASE_EXTERNS_H 3 | 4 | extern metadata_thp_mode_t opt_metadata_thp; 5 | extern const char *metadata_thp_mode_names[]; 6 | 7 | base_t *b0get(void); 8 | base_t *base_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks); 9 | void base_delete(tsdn_t *tsdn, base_t *base); 10 | extent_hooks_t *base_extent_hooks_get(base_t *base); 11 | extent_hooks_t *base_extent_hooks_set(base_t *base, 12 | extent_hooks_t *extent_hooks); 13 | void *base_alloc(tsdn_t *tsdn, base_t *base, size_t size, size_t alignment); 14 | extent_t *base_alloc_extent(tsdn_t *tsdn, base_t *base); 15 | void base_stats_get(tsdn_t *tsdn, base_t *base, size_t *allocated, 16 | size_t *resident, size_t *mapped, size_t *n_thp); 17 | void base_prefork(tsdn_t *tsdn, base_t *base); 18 | void base_postfork_parent(tsdn_t *tsdn, base_t *base); 19 | void base_postfork_child(tsdn_t *tsdn, base_t *base); 20 | bool base_boot(tsdn_t *tsdn); 21 | 22 | #endif /* JEMALLOC_INTERNAL_BASE_EXTERNS_H */ 23 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/base_inlines.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BASE_INLINES_H 2 | #define JEMALLOC_INTERNAL_BASE_INLINES_H 3 | 4 | static inline unsigned 5 | base_ind_get(const base_t *base) { 6 | return base->ind; 7 | } 8 | 9 | static inline bool 10 | metadata_thp_enabled(void) { 11 | return (opt_metadata_thp != metadata_thp_disabled); 12 | } 13 | #endif /* JEMALLOC_INTERNAL_BASE_INLINES_H */ 14 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/bin_types.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_BIN_TYPES_H 2 | #define JEMALLOC_INTERNAL_BIN_TYPES_H 3 | 4 | #include "jemalloc/internal/sc.h" 5 | 6 | #define BIN_SHARDS_MAX (1 << EXTENT_BITS_BINSHARD_WIDTH) 7 | #define N_BIN_SHARDS_DEFAULT 1 8 | 9 | /* Used in TSD static initializer only. Real init in arena_bind(). */ 10 | #define TSD_BINSHARDS_ZERO_INITIALIZER {{UINT8_MAX}} 11 | 12 | typedef struct tsd_binshards_s tsd_binshards_t; 13 | struct tsd_binshards_s { 14 | uint8_t binshard[SC_NBINS]; 15 | }; 16 | 17 | #endif /* JEMALLOC_INTERNAL_BIN_TYPES_H */ 18 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/extent_dss.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_EXTENT_DSS_H 2 | #define JEMALLOC_INTERNAL_EXTENT_DSS_H 3 | 4 | typedef enum { 5 | dss_prec_disabled = 0, 6 | dss_prec_primary = 1, 7 | dss_prec_secondary = 2, 8 | 9 | dss_prec_limit = 3 10 | } dss_prec_t; 11 | #define DSS_PREC_DEFAULT dss_prec_secondary 12 | #define DSS_DEFAULT "secondary" 13 | 14 | extern const char *dss_prec_names[]; 15 | 16 | extern const char *opt_dss; 17 | 18 | dss_prec_t extent_dss_prec_get(void); 19 | bool extent_dss_prec_set(dss_prec_t dss_prec); 20 | void *extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, 21 | size_t size, size_t alignment, bool *zero, bool *commit); 22 | bool extent_in_dss(void *addr); 23 | bool extent_dss_mergeable(void *addr_a, void *addr_b); 24 | void extent_dss_boot(void); 25 | 26 | #endif /* JEMALLOC_INTERNAL_EXTENT_DSS_H */ 27 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/extent_mmap.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_EXTENT_MMAP_EXTERNS_H 2 | #define JEMALLOC_INTERNAL_EXTENT_MMAP_EXTERNS_H 3 | 4 | extern bool opt_retain; 5 | 6 | void *extent_alloc_mmap(void *new_addr, size_t size, size_t alignment, 7 | bool *zero, bool *commit); 8 | bool extent_dalloc_mmap(void *addr, size_t size); 9 | 10 | #endif /* JEMALLOC_INTERNAL_EXTENT_MMAP_EXTERNS_H */ 11 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/extent_types.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_EXTENT_TYPES_H 2 | #define JEMALLOC_INTERNAL_EXTENT_TYPES_H 3 | 4 | typedef struct extent_s extent_t; 5 | typedef struct extents_s extents_t; 6 | 7 | typedef struct extent_util_stats_s extent_util_stats_t; 8 | typedef struct extent_util_stats_verbose_s extent_util_stats_verbose_t; 9 | 10 | #define EXTENT_HOOKS_INITIALIZER NULL 11 | 12 | /* 13 | * When reuse (and split) an active extent, (1U << opt_lg_extent_max_active_fit) 14 | * is the max ratio between the size of the active extent and the new extent. 15 | */ 16 | #define LG_EXTENT_MAX_ACTIVE_FIT_DEFAULT 6 17 | 18 | typedef enum { 19 | EXTENT_NOT_HEAD, 20 | EXTENT_IS_HEAD /* Only relevant for Windows && opt.retain. */ 21 | } extent_head_state_t; 22 | 23 | #endif /* JEMALLOC_INTERNAL_EXTENT_TYPES_H */ 24 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/private_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for symbol in `cat "$@"` ; do 4 | echo "#define ${symbol} JEMALLOC_N(${symbol})" 5 | done 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/public_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#define je_${n} JEMALLOC_N(${n})" 6 | done 7 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/public_unnamespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#undef je_${n}" 6 | done 7 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/safety_check.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_SAFETY_CHECK_H 2 | #define JEMALLOC_INTERNAL_SAFETY_CHECK_H 3 | 4 | void safety_check_fail(const char *format, ...); 5 | /* Can set to NULL for a default. */ 6 | void safety_check_set_abort(void (*abort_fn)()); 7 | 8 | JEMALLOC_ALWAYS_INLINE void 9 | safety_check_set_redzone(void *ptr, size_t usize, size_t bumped_usize) { 10 | assert(usize < bumped_usize); 11 | for (size_t i = usize; i < bumped_usize && i < usize + 32; ++i) { 12 | *((unsigned char *)ptr + i) = 0xBC; 13 | } 14 | } 15 | 16 | JEMALLOC_ALWAYS_INLINE void 17 | safety_check_verify_redzone(const void *ptr, size_t usize, size_t bumped_usize) 18 | { 19 | for (size_t i = usize; i < bumped_usize && i < usize + 32; ++i) { 20 | if (unlikely(*((unsigned char *)ptr + i) != 0xBC)) { 21 | safety_check_fail("Use after free error\n"); 22 | } 23 | } 24 | } 25 | 26 | #endif /*JEMALLOC_INTERNAL_SAFETY_CHECK_H */ 27 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/spin.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_SPIN_H 2 | #define JEMALLOC_INTERNAL_SPIN_H 3 | 4 | #define SPIN_INITIALIZER {0U} 5 | 6 | typedef struct { 7 | unsigned iteration; 8 | } spin_t; 9 | 10 | static inline void 11 | spin_cpu_spinwait() { 12 | # if HAVE_CPU_SPINWAIT 13 | CPU_SPINWAIT; 14 | # else 15 | volatile int x = 0; 16 | x = x; 17 | # endif 18 | } 19 | 20 | static inline void 21 | spin_adaptive(spin_t *spin) { 22 | volatile uint32_t i; 23 | 24 | if (spin->iteration < 5) { 25 | for (i = 0; i < (1U << spin->iteration); i++) { 26 | spin_cpu_spinwait(); 27 | } 28 | spin->iteration++; 29 | } else { 30 | #ifdef _WIN32 31 | SwitchToThread(); 32 | #else 33 | sched_yield(); 34 | #endif 35 | } 36 | } 37 | 38 | #undef SPIN_INLINE 39 | 40 | #endif /* JEMALLOC_INTERNAL_SPIN_H */ 41 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/test_hooks.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_TEST_HOOKS_H 2 | #define JEMALLOC_INTERNAL_TEST_HOOKS_H 3 | 4 | extern JEMALLOC_EXPORT void (*test_hooks_arena_new_hook)(); 5 | extern JEMALLOC_EXPORT void (*test_hooks_libc_hook)(); 6 | 7 | #define JEMALLOC_HOOK(fn, hook) ((void)(hook != NULL && (hook(), 0)), fn) 8 | 9 | #define open JEMALLOC_HOOK(open, test_hooks_libc_hook) 10 | #define read JEMALLOC_HOOK(read, test_hooks_libc_hook) 11 | #define write JEMALLOC_HOOK(write, test_hooks_libc_hook) 12 | #define readlink JEMALLOC_HOOK(readlink, test_hooks_libc_hook) 13 | #define close JEMALLOC_HOOK(close, test_hooks_libc_hook) 14 | #define creat JEMALLOC_HOOK(creat, test_hooks_libc_hook) 15 | #define secure_getenv JEMALLOC_HOOK(secure_getenv, test_hooks_libc_hook) 16 | /* Note that this is undef'd and re-define'd in src/prof.c. */ 17 | #define _Unwind_Backtrace JEMALLOC_HOOK(_Unwind_Backtrace, test_hooks_libc_hook) 18 | 19 | #endif /* JEMALLOC_INTERNAL_TEST_HOOKS_H */ 20 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/tsd_types.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_TSD_TYPES_H 2 | #define JEMALLOC_INTERNAL_TSD_TYPES_H 3 | 4 | #define MALLOC_TSD_CLEANUPS_MAX 2 5 | 6 | typedef struct tsd_s tsd_t; 7 | typedef struct tsdn_s tsdn_t; 8 | typedef bool (*malloc_tsd_cleanup_t)(void); 9 | 10 | #endif /* JEMALLOC_INTERNAL_TSD_TYPES_H */ 11 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/jemalloc/jemalloc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | objroot=$1 4 | 5 | cat < 5 | 6 | /* MSVC doesn't define _Bool or bool in C, but does have BOOL */ 7 | /* Note this doesn't pass autoconf's test because (bool) 0.5 != true */ 8 | /* Clang-cl uses MSVC headers, so needs msvc_compat, but has _Bool as 9 | * a built-in type. */ 10 | #ifndef __clang__ 11 | typedef BOOL _Bool; 12 | #endif 13 | 14 | #define bool _Bool 15 | #define true 1 16 | #define false 0 17 | 18 | #define __bool_true_false_are_defined 1 19 | 20 | #endif /* stdbool_h */ 21 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/include/msvc_compat/windows_extra.h: -------------------------------------------------------------------------------- 1 | #ifndef MSVC_COMPAT_WINDOWS_EXTRA_H 2 | #define MSVC_COMPAT_WINDOWS_EXTRA_H 3 | 4 | #include 5 | 6 | #endif /* MSVC_COMPAT_WINDOWS_EXTRA_H */ 7 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/jemalloc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | install_suffix=@install_suffix@ 6 | 7 | Name: jemalloc 8 | Description: A general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support. 9 | URL: http://jemalloc.net/ 10 | Version: @jemalloc_version_major@.@jemalloc_version_minor@.@jemalloc_version_bugfix@_@jemalloc_version_nrev@ 11 | Cflags: -I${includedir} 12 | Libs: -L${libdir} -ljemalloc${install_suffix} 13 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/msvc/ReadMe.txt: -------------------------------------------------------------------------------- 1 | 2 | How to build jemalloc for Windows 3 | ================================= 4 | 5 | 1. Install Cygwin with at least the following packages: 6 | * autoconf 7 | * autogen 8 | * gawk 9 | * grep 10 | * sed 11 | 12 | 2. Install Visual Studio 2015 or 2017 with Visual C++ 13 | 14 | 3. Add Cygwin\bin to the PATH environment variable 15 | 16 | 4. Open "x64 Native Tools Command Prompt for VS 2017" 17 | (note: x86/x64 doesn't matter at this point) 18 | 19 | 5. Generate header files: 20 | sh -c "CC=cl ./autogen.sh" 21 | 22 | 6. Now the project can be opened and built in Visual Studio: 23 | msvc\jemalloc_vc2017.sln 24 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/msvc/projects/vc2015/test_threads/test_threads.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | 22 | 23 | Header Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/msvc/projects/vc2017/test_threads/test_threads.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | 22 | 23 | Header Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/msvc/test_threads/test_threads.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int test_threads(); 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/msvc/test_threads/test_threads_main.cpp: -------------------------------------------------------------------------------- 1 | #include "test_threads.h" 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std::chrono_literals; 7 | 8 | int main(int argc, char** argv) { 9 | int rc = test_threads(); 10 | return rc; 11 | } 12 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/run_tests.sh: -------------------------------------------------------------------------------- 1 | $(dirname "$)")/scripts/gen_run_tests.py | bash 2 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/src/extent_mmap.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_EXTENT_MMAP_C_ 2 | #include "jemalloc/internal/jemalloc_preamble.h" 3 | #include "jemalloc/internal/jemalloc_internal_includes.h" 4 | 5 | #include "jemalloc/internal/assert.h" 6 | #include "jemalloc/internal/extent_mmap.h" 7 | 8 | /******************************************************************************/ 9 | /* Data. */ 10 | 11 | bool opt_retain = 12 | #ifdef JEMALLOC_RETAIN 13 | true 14 | #else 15 | false 16 | #endif 17 | ; 18 | 19 | /******************************************************************************/ 20 | 21 | void * 22 | extent_alloc_mmap(void *new_addr, size_t size, size_t alignment, bool *zero, 23 | bool *commit) { 24 | assert(alignment == ALIGNMENT_CEILING(alignment, PAGE)); 25 | void *ret = pages_map(new_addr, size, alignment, commit); 26 | if (ret == NULL) { 27 | return NULL; 28 | } 29 | assert(ret != NULL); 30 | if (*commit) { 31 | *zero = true; 32 | } 33 | return ret; 34 | } 35 | 36 | bool 37 | extent_dalloc_mmap(void *addr, size_t size) { 38 | if (!opt_retain) { 39 | pages_unmap(addr, size); 40 | } 41 | return opt_retain; 42 | } 43 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/src/hash.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_HASH_C_ 2 | #include "jemalloc/internal/jemalloc_preamble.h" 3 | #include "jemalloc/internal/jemalloc_internal_includes.h" 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/src/mutex_pool.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_MUTEX_POOL_C_ 2 | 3 | #include "jemalloc/internal/jemalloc_preamble.h" 4 | #include "jemalloc/internal/jemalloc_internal_includes.h" 5 | 6 | #include "jemalloc/internal/mutex.h" 7 | #include "jemalloc/internal/mutex_pool.h" 8 | 9 | bool 10 | mutex_pool_init(mutex_pool_t *pool, const char *name, witness_rank_t rank) { 11 | for (int i = 0; i < MUTEX_POOL_SIZE; ++i) { 12 | if (malloc_mutex_init(&pool->mutexes[i], name, rank, 13 | malloc_mutex_address_ordered)) { 14 | return true; 15 | } 16 | } 17 | return false; 18 | } 19 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/src/prng.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_PRNG_C_ 2 | #include "jemalloc/internal/jemalloc_preamble.h" 3 | #include "jemalloc/internal/jemalloc_internal_includes.h" 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/src/safety_check.c: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_preamble.h" 2 | #include "jemalloc/internal/jemalloc_internal_includes.h" 3 | 4 | static void (*safety_check_abort)(const char *message); 5 | 6 | void safety_check_set_abort(void (*abort_fn)(const char *)) { 7 | safety_check_abort = abort_fn; 8 | } 9 | 10 | void safety_check_fail(const char *format, ...) { 11 | char buf[MALLOC_PRINTF_BUFSIZE]; 12 | 13 | va_list ap; 14 | va_start(ap, format); 15 | malloc_vsnprintf(buf, MALLOC_PRINTF_BUFSIZE, format, ap); 16 | va_end(ap); 17 | 18 | if (safety_check_abort == NULL) { 19 | malloc_write(buf); 20 | abort(); 21 | } else { 22 | safety_check_abort(buf); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/src/test_hooks.c: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_preamble.h" 2 | 3 | /* 4 | * The hooks are a little bit screwy -- they're not genuinely exported in the 5 | * sense that we want them available to end-users, but we do want them visible 6 | * from outside the generated library, so that we can use them in test code. 7 | */ 8 | JEMALLOC_EXPORT 9 | void (*test_hooks_arena_new_hook)() = NULL; 10 | 11 | JEMALLOC_EXPORT 12 | void (*test_hooks_libc_hook)() = NULL; 13 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/src/ticker.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_TICKER_C_ 2 | #include "jemalloc/internal/jemalloc_preamble.h" 3 | #include "jemalloc/internal/jemalloc_internal_includes.h" 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/include/test/btalloc.h: -------------------------------------------------------------------------------- 1 | /* btalloc() provides a mechanism for allocating via permuted backtraces. */ 2 | void *btalloc(size_t size, unsigned bits); 3 | 4 | #define btalloc_n_proto(n) \ 5 | void *btalloc_##n(size_t size, unsigned bits); 6 | btalloc_n_proto(0) 7 | btalloc_n_proto(1) 8 | 9 | #define btalloc_n_gen(n) \ 10 | void * \ 11 | btalloc_##n(size_t size, unsigned bits) { \ 12 | void *p; \ 13 | \ 14 | if (bits == 0) { \ 15 | p = mallocx(size, 0); \ 16 | } else { \ 17 | switch (bits & 0x1U) { \ 18 | case 0: \ 19 | p = (btalloc_0(size, bits >> 1)); \ 20 | break; \ 21 | case 1: \ 22 | p = (btalloc_1(size, bits >> 1)); \ 23 | break; \ 24 | default: not_reached(); \ 25 | } \ 26 | } \ 27 | /* Intentionally sabotage tail call optimization. */ \ 28 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); \ 29 | return p; \ 30 | } 31 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/include/test/jemalloc_test_defs.h.in: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_internal_defs.h" 2 | #include "jemalloc/internal/jemalloc_internal_decls.h" 3 | 4 | /* 5 | * For use by SFMT. configure.ac doesn't actually define HAVE_SSE2 because its 6 | * dependencies are notoriously unportable in practice. 7 | */ 8 | #undef HAVE_SSE2 9 | #undef HAVE_ALTIVEC 10 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/include/test/mtx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mtx is a slightly simplified version of malloc_mutex. This code duplication 3 | * is unfortunate, but there are allocator bootstrapping considerations that 4 | * would leak into the test infrastructure if malloc_mutex were used directly 5 | * in tests. 6 | */ 7 | 8 | typedef struct { 9 | #ifdef _WIN32 10 | CRITICAL_SECTION lock; 11 | #elif (defined(JEMALLOC_OS_UNFAIR_LOCK)) 12 | os_unfair_lock lock; 13 | #else 14 | pthread_mutex_t lock; 15 | #endif 16 | } mtx_t; 17 | 18 | bool mtx_init(mtx_t *mtx); 19 | void mtx_fini(mtx_t *mtx); 20 | void mtx_lock(mtx_t *mtx); 21 | void mtx_unlock(mtx_t *mtx); 22 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/include/test/thd.h: -------------------------------------------------------------------------------- 1 | /* Abstraction layer for threading in tests. */ 2 | #ifdef _WIN32 3 | typedef HANDLE thd_t; 4 | #else 5 | typedef pthread_t thd_t; 6 | #endif 7 | 8 | void thd_create(thd_t *thd, void *(*proc)(void *), void *arg); 9 | void thd_join(thd_t thd, void **ret); 10 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/include/test/timer.h: -------------------------------------------------------------------------------- 1 | /* Simple timer, for use in benchmark reporting. */ 2 | 3 | typedef struct { 4 | nstime_t t0; 5 | nstime_t t1; 6 | } timedelta_t; 7 | 8 | void timer_start(timedelta_t *timer); 9 | void timer_stop(timedelta_t *timer); 10 | uint64_t timer_usec(const timedelta_t *timer); 11 | void timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen); 12 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/integration/extent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="junk:false" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/integration/malloc.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_zero_alloc) { 4 | void *res = malloc(0); 5 | assert(res); 6 | size_t usable = malloc_usable_size(res); 7 | assert(usable > 0); 8 | free(res); 9 | } 10 | TEST_END 11 | 12 | int 13 | main(void) { 14 | return test( 15 | test_zero_alloc); 16 | } 17 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/integration/mallocx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="junk:false" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/integration/slab_sizes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Some screwy-looking slab sizes. 4 | export MALLOC_CONF="slab_sizes:1-4096:17|100-200:1|128-128:2" 5 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/integration/smallocx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="junk:false" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/integration/xallocx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="junk:false" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/src/btalloc.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | void * 4 | btalloc(size_t size, unsigned bits) { 5 | return btalloc_0(size, bits); 6 | } 7 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/src/btalloc_0.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | btalloc_n_gen(0) 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/src/btalloc_1.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | btalloc_n_gen(1) 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/src/math.c: -------------------------------------------------------------------------------- 1 | #define MATH_C_ 2 | #include "test/jemalloc_test.h" 3 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/src/mq.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | /* 4 | * Sleep for approximately ns nanoseconds. No lower *nor* upper bound on sleep 5 | * time is guaranteed. 6 | */ 7 | void 8 | mq_nanosleep(unsigned ns) { 9 | assert(ns <= 1000*1000*1000); 10 | 11 | #ifdef _WIN32 12 | Sleep(ns / 1000); 13 | #else 14 | { 15 | struct timespec timeout; 16 | 17 | if (ns < 1000*1000*1000) { 18 | timeout.tv_sec = 0; 19 | timeout.tv_nsec = ns; 20 | } else { 21 | timeout.tv_sec = 1; 22 | timeout.tv_nsec = 0; 23 | } 24 | nanosleep(&timeout, NULL); 25 | } 26 | #endif 27 | } 28 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/src/thd.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifdef _WIN32 4 | void 5 | thd_create(thd_t *thd, void *(*proc)(void *), void *arg) { 6 | LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc; 7 | *thd = CreateThread(NULL, 0, routine, arg, 0, NULL); 8 | if (*thd == NULL) { 9 | test_fail("Error in CreateThread()\n"); 10 | } 11 | } 12 | 13 | void 14 | thd_join(thd_t thd, void **ret) { 15 | if (WaitForSingleObject(thd, INFINITE) == WAIT_OBJECT_0 && ret) { 16 | DWORD exit_code; 17 | GetExitCodeThread(thd, (LPDWORD) &exit_code); 18 | *ret = (void *)(uintptr_t)exit_code; 19 | } 20 | } 21 | 22 | #else 23 | void 24 | thd_create(thd_t *thd, void *(*proc)(void *), void *arg) { 25 | if (pthread_create(thd, NULL, proc, arg) != 0) { 26 | test_fail("Error in pthread_create()\n"); 27 | } 28 | } 29 | 30 | void 31 | thd_join(thd_t thd, void **ret) { 32 | pthread_join(thd, ret); 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/a0.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_a0) { 4 | void *p; 5 | 6 | p = a0malloc(1); 7 | assert_ptr_not_null(p, "Unexpected a0malloc() error"); 8 | a0dalloc(p); 9 | } 10 | TEST_END 11 | 12 | int 13 | main(void) { 14 | return test_no_malloc_init( 15 | test_a0); 16 | } 17 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/arena_reset_prof.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | #define ARENA_RESET_PROF_C_ 3 | 4 | #include "arena_reset.c" 5 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/arena_reset_prof.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export MALLOC_CONF="prof:true,lg_prof_sample:0" 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/binshard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export MALLOC_CONF="narenas:1,bin_shards:1-160:16|129-512:4|256-256:8" 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/decay.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export MALLOC_CONF="dirty_decay_ms:1000,muzzy_decay_ms:1000,lg_tcache_max:0" 4 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/div.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #include "jemalloc/internal/div.h" 4 | 5 | TEST_BEGIN(test_div_exhaustive) { 6 | for (size_t divisor = 2; divisor < 1000 * 1000; ++divisor) { 7 | div_info_t div_info; 8 | div_init(&div_info, divisor); 9 | size_t max = 1000 * divisor; 10 | if (max < 1000 * 1000) { 11 | max = 1000 * 1000; 12 | } 13 | for (size_t dividend = 0; dividend < 1000 * divisor; 14 | dividend += divisor) { 15 | size_t quotient = div_compute( 16 | &div_info, dividend); 17 | assert_zu_eq(dividend, quotient * divisor, 18 | "With divisor = %zu, dividend = %zu, " 19 | "got quotient %zu", divisor, dividend, quotient); 20 | } 21 | } 22 | } 23 | TEST_END 24 | 25 | int 26 | main(void) { 27 | return test_no_reentrancy( 28 | test_div_exhaustive); 29 | } 30 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/junk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="abort:false,zero:false,junk:true" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/junk_alloc.c: -------------------------------------------------------------------------------- 1 | #include "junk.c" 2 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/junk_alloc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="abort:false,zero:false,junk:alloc" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/junk_free.c: -------------------------------------------------------------------------------- 1 | #include "junk.c" 2 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/junk_free.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="abort:false,zero:false,junk:free" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Immediately purge to minimize fragmentation. 4 | export MALLOC_CONF="dirty_decay_ms:0,muzzy_decay_ms:0" 5 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/pages.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_pages_huge) { 4 | size_t alloc_size; 5 | bool commit; 6 | void *pages, *hugepage; 7 | 8 | alloc_size = HUGEPAGE * 2 - PAGE; 9 | commit = true; 10 | pages = pages_map(NULL, alloc_size, PAGE, &commit); 11 | assert_ptr_not_null(pages, "Unexpected pages_map() error"); 12 | 13 | if (init_system_thp_mode == thp_mode_default) { 14 | hugepage = (void *)(ALIGNMENT_CEILING((uintptr_t)pages, HUGEPAGE)); 15 | assert_b_ne(pages_huge(hugepage, HUGEPAGE), have_madvise_huge, 16 | "Unexpected pages_huge() result"); 17 | assert_false(pages_nohuge(hugepage, HUGEPAGE), 18 | "Unexpected pages_nohuge() result"); 19 | } 20 | 21 | pages_unmap(pages, alloc_size); 22 | } 23 | TEST_END 24 | 25 | int 26 | main(void) { 27 | return test( 28 | test_pages_huge); 29 | } 30 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/prof_accum.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/prof_active.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_thread_active_init:false,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/prof_gdump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_active:false,prof_gdump:true" 5 | fi 6 | 7 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/prof_idump.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static bool did_prof_dump_open; 4 | 5 | static int 6 | prof_dump_open_intercept(bool propagate_err, const char *filename) { 7 | int fd; 8 | 9 | did_prof_dump_open = true; 10 | 11 | fd = open("/dev/null", O_WRONLY); 12 | assert_d_ne(fd, -1, "Unexpected open() failure"); 13 | 14 | return fd; 15 | } 16 | 17 | TEST_BEGIN(test_idump) { 18 | bool active; 19 | void *p; 20 | 21 | test_skip_if(!config_prof); 22 | 23 | active = true; 24 | assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active, 25 | sizeof(active)), 0, 26 | "Unexpected mallctl failure while activating profiling"); 27 | 28 | prof_dump_open = prof_dump_open_intercept; 29 | 30 | did_prof_dump_open = false; 31 | p = mallocx(1, 0); 32 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 33 | dallocx(p, 0); 34 | assert_true(did_prof_dump_open, "Expected a profile dump"); 35 | } 36 | TEST_END 37 | 38 | int 39 | main(void) { 40 | return test( 41 | test_idump); 42 | } 43 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/prof_idump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export MALLOC_CONF="tcache:false" 4 | if [ "x${enable_prof}" = "x1" ] ; then 5 | export MALLOC_CONF="${MALLOC_CONF},prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0,lg_prof_interval:0" 6 | fi 7 | 8 | 9 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/prof_log.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/prof_reset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_active:false,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/prof_tctx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/prof_thread_name.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_active:false" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/safety_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/sc.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_update_slab_size) { 4 | sc_data_t data; 5 | memset(&data, 0, sizeof(data)); 6 | sc_data_init(&data); 7 | sc_t *tiny = &data.sc[0]; 8 | size_t tiny_size = (ZU(1) << tiny->lg_base) 9 | + (ZU(tiny->ndelta) << tiny->lg_delta); 10 | size_t pgs_too_big = (tiny_size * BITMAP_MAXBITS + PAGE - 1) / PAGE + 1; 11 | sc_data_update_slab_size(&data, tiny_size, tiny_size, (int)pgs_too_big); 12 | assert_zu_lt((size_t)tiny->pgs, pgs_too_big, "Allowed excessive pages"); 13 | 14 | sc_data_update_slab_size(&data, 1, 10 * PAGE, 1); 15 | for (int i = 0; i < data.nbins; i++) { 16 | sc_t *sc = &data.sc[i]; 17 | size_t reg_size = (ZU(1) << sc->lg_base) 18 | + (ZU(sc->ndelta) << sc->lg_delta); 19 | if (reg_size <= PAGE) { 20 | assert_d_eq(sc->pgs, 1, "Ignored valid page size hint"); 21 | } else { 22 | assert_d_gt(sc->pgs, 1, 23 | "Allowed invalid page size hint"); 24 | } 25 | } 26 | } 27 | TEST_END 28 | 29 | int 30 | main(void) { 31 | return test( 32 | test_update_slab_size); 33 | } 34 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/slab.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_arena_slab_regind) { 4 | szind_t binind; 5 | 6 | for (binind = 0; binind < SC_NBINS; binind++) { 7 | size_t regind; 8 | extent_t slab; 9 | const bin_info_t *bin_info = &bin_infos[binind]; 10 | extent_init(&slab, NULL, mallocx(bin_info->slab_size, 11 | MALLOCX_LG_ALIGN(LG_PAGE)), bin_info->slab_size, true, 12 | binind, 0, extent_state_active, false, true, true, 13 | EXTENT_NOT_HEAD); 14 | assert_ptr_not_null(extent_addr_get(&slab), 15 | "Unexpected malloc() failure"); 16 | for (regind = 0; regind < bin_info->nregs; regind++) { 17 | void *reg = (void *)((uintptr_t)extent_addr_get(&slab) + 18 | (bin_info->reg_size * regind)); 19 | assert_zu_eq(arena_slab_regind(&slab, binind, reg), 20 | regind, 21 | "Incorrect region index computed for size %zu", 22 | bin_info->reg_size); 23 | } 24 | free(extent_addr_get(&slab)); 25 | } 26 | } 27 | TEST_END 28 | 29 | int 30 | main(void) { 31 | return test( 32 | test_arena_slab_regind); 33 | } 34 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/spin.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #include "jemalloc/internal/spin.h" 4 | 5 | TEST_BEGIN(test_spin) { 6 | spin_t spinner = SPIN_INITIALIZER; 7 | 8 | for (unsigned i = 0; i < 100; i++) { 9 | spin_adaptive(&spinner); 10 | } 11 | } 12 | TEST_END 13 | 14 | int 15 | main(void) { 16 | return test( 17 | test_spin); 18 | } 19 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/test_hooks.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static bool hook_called = false; 4 | 5 | static void 6 | hook() { 7 | hook_called = true; 8 | } 9 | 10 | static int 11 | func_to_hook(int arg1, int arg2) { 12 | return arg1 + arg2; 13 | } 14 | 15 | #define func_to_hook JEMALLOC_HOOK(func_to_hook, test_hooks_libc_hook) 16 | 17 | TEST_BEGIN(unhooked_call) { 18 | test_hooks_libc_hook = NULL; 19 | hook_called = false; 20 | assert_d_eq(3, func_to_hook(1, 2), "Hooking changed return value."); 21 | assert_false(hook_called, "Nulling out hook didn't take."); 22 | } 23 | TEST_END 24 | 25 | TEST_BEGIN(hooked_call) { 26 | test_hooks_libc_hook = &hook; 27 | hook_called = false; 28 | assert_d_eq(3, func_to_hook(1, 2), "Hooking changed return value."); 29 | assert_true(hook_called, "Hook should have executed."); 30 | } 31 | TEST_END 32 | 33 | int 34 | main(void) { 35 | return test( 36 | unhooked_call, 37 | hooked_call); 38 | } 39 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/jemalloc/test/unit/zero.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="abort:false,junk:false,zero:true" 5 | fi 6 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/tests/malloc_conf_empty.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn malloc_conf_empty() { 3 | unsafe { 4 | assert!(tikv_jemalloc_sys::malloc_conf.is_none()); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/tests/unprefixed_malloc.rs: -------------------------------------------------------------------------------- 1 | #[cfg(prefixed)] 2 | #[test] 3 | fn malloc_is_prefixed() { 4 | assert_ne!(tikv_jemalloc_sys::malloc as usize, libc::malloc as usize) 5 | } 6 | 7 | #[cfg(not(prefixed))] 8 | #[test] 9 | fn malloc_is_overridden() { 10 | assert_eq!(tikv_jemalloc_sys::malloc as usize, libc::malloc as usize) 11 | } 12 | -------------------------------------------------------------------------------- /jemallocator/jemalloc-sys/update_jemalloc.md: -------------------------------------------------------------------------------- 1 | # Updating jemalloc 2 | 3 | Updating the `jemalloc` version requires generating new `configure` files, which 4 | requires `autoconf` to be installed. 5 | 6 | To generate the configuration files, go to the `jemalloc` source directory and 7 | run: 8 | 9 | ```shell 10 | autoconf 11 | ``` 12 | -------------------------------------------------------------------------------- /jemallocator/systest/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "systest" 3 | version = "0.1.0" 4 | authors = ["Alex Crichton "] 5 | build = "build.rs" 6 | edition = "2018" 7 | 8 | [dependencies] 9 | tikv-jemalloc-sys = { path = "../jemalloc-sys" } 10 | libc = "0.2" 11 | 12 | [build-dependencies] 13 | ctest = "0.2.22" 14 | -------------------------------------------------------------------------------- /jemallocator/systest/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::path::PathBuf; 3 | 4 | const FUNCTION_POINTER: &[&str] = &[ 5 | "extent_alloc_t", 6 | "extent_dalloc_t", 7 | "extent_destroy_t", 8 | "extent_commit_t", 9 | "extent_decommit_t", 10 | "extent_purge_t", 11 | "extent_split_t", 12 | "extent_merge_t", 13 | ]; 14 | 15 | fn main() { 16 | let root = PathBuf::from(env::var_os("DEP_JEMALLOC_ROOT").unwrap()); 17 | 18 | let mut cfg = ctest::TestGenerator::new(); 19 | cfg.header("jemalloc/jemalloc.h") 20 | .include(root.join("include")) 21 | .cfg("prefixed", None) 22 | .fn_cname(|rust, link_name| link_name.unwrap_or(rust).to_string()) 23 | .skip_signededness(|c| c.ends_with("_t")) 24 | // No need to test pure C function pointer. 25 | .skip_type(|name| FUNCTION_POINTER.contains(&name)); 26 | 27 | if cfg!(target_os = "linux") { 28 | cfg.skip_fn(|f| f == "malloc_usable_size"); 29 | } 30 | 31 | cfg.generate("../jemalloc-sys/src/lib.rs", "all.rs"); 32 | } 33 | -------------------------------------------------------------------------------- /jemallocator/systest/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(bad_style, improper_ctypes, dead_code, unused_imports)] 2 | 3 | use std::alloc::System; 4 | 5 | #[global_allocator] 6 | static A: System = System; 7 | 8 | use libc::{c_char, c_int, c_void}; 9 | use tikv_jemalloc_sys::*; 10 | 11 | include!(concat!(env!("OUT_DIR"), "/all.rs")); 12 | -------------------------------------------------------------------------------- /jemallocator/tests/background_thread_defaults.rs: -------------------------------------------------------------------------------- 1 | //! Test background threads run-time default settings. 2 | 3 | use tikv_jemallocator::Jemalloc; 4 | 5 | #[global_allocator] 6 | static A: Jemalloc = Jemalloc; 7 | 8 | // Returns true if background threads are enabled. 9 | fn background_threads() -> bool { 10 | tikv_jemalloc_ctl::opt::background_thread::read().unwrap() 11 | } 12 | 13 | #[test] 14 | fn background_threads_runtime_defaults() { 15 | if !cfg!(feature = "background_threads_runtime_support") { 16 | // If the crate was compiled without background thread support, 17 | // then background threads are always disabled at run-time by default: 18 | assert_eq!(background_threads(), false); 19 | return; 20 | } 21 | 22 | if cfg!(feature = "background_threads") { 23 | // The crate was compiled with background-threads enabled by default: 24 | assert_eq!(background_threads(), true); 25 | } else { 26 | // The crate was compiled with background-threads disabled by default: 27 | assert_eq!(background_threads(), false); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /jemallocator/tests/smoke.rs: -------------------------------------------------------------------------------- 1 | use std::alloc::{GlobalAlloc, Layout}; 2 | use tikv_jemallocator::Jemalloc; 3 | 4 | #[global_allocator] 5 | static A: Jemalloc = Jemalloc; 6 | 7 | #[test] 8 | fn smoke() { 9 | let mut a = Vec::new(); 10 | a.push(3); 11 | } 12 | 13 | /// https://github.com/rust-lang/rust/issues/45955 14 | #[test] 15 | fn overaligned() { 16 | let size = 8; 17 | let align = 16; // greater than size 18 | let iterations = 100; 19 | unsafe { 20 | let pointers: Vec<_> = (0..iterations) 21 | .map(|_| { 22 | let ptr = Jemalloc.alloc(Layout::from_size_align(size, align).unwrap()); 23 | assert!(!ptr.is_null()); 24 | ptr 25 | }) 26 | .collect(); 27 | for &ptr in &pointers { 28 | assert_eq!( 29 | (ptr as usize) % align, 30 | 0, 31 | "Got a pointer less aligned than requested" 32 | ) 33 | } 34 | 35 | // Clean up 36 | for &ptr in &pointers { 37 | Jemalloc.dealloc(ptr, Layout::from_size_align(size, align).unwrap()) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /jemallocator/tests/smoke_ffi.rs: -------------------------------------------------------------------------------- 1 | // Work around https://github.com/gnzlbg/jemallocator/issues/19 2 | #[global_allocator] 3 | static A: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; 4 | 5 | #[test] 6 | fn smoke() { 7 | unsafe { 8 | let ptr = tikv_jemalloc_sys::malloc(4); 9 | *(ptr as *mut u32) = 0xDECADE; 10 | assert_eq!(*(ptr as *mut u32), 0xDECADE); 11 | tikv_jemalloc_sys::free(ptr); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /jemallocator/tests/usable_size.rs: -------------------------------------------------------------------------------- 1 | use tikv_jemallocator::Jemalloc; 2 | 3 | #[global_allocator] 4 | static A: Jemalloc = Jemalloc; 5 | 6 | #[test] 7 | fn smoke() { 8 | let a = Box::new(3_u32); 9 | assert!(unsafe { tikv_jemallocator::usable_size(&*a) } >= 4); 10 | } 11 | -------------------------------------------------------------------------------- /lz4-compress/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lz4-compress" 3 | version = "0.1.1" 4 | authors = ["ticki "] 5 | description = "Pure Rust implementation of raw LZ4 compression/decompression." 6 | repository = "https://github.com/ticki/tfs" 7 | documentation = "https://docs.rs/lz4-compress" 8 | license = "MIT" 9 | keywords = ["compression", "lz4", "compress", "decompression", "decompress"] 10 | exclude = ["target", "Cargo.lock"] 11 | 12 | [dependencies] 13 | byteorder = "1" 14 | quick-error = "1" 15 | -------------------------------------------------------------------------------- /lz4-compress/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Ticki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lz4-compress/README.md: -------------------------------------------------------------------------------- 1 | This is a fork of https://github.com/redox-os/tfs/tree/master/lz4 2 | -------------------------------------------------------------------------------- /lz4-compress/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Pure Rust implementation of LZ4 compression. 2 | //! 3 | //! A detailed explanation of the algorithm can be found [here](http://ticki.github.io/blog/how-lz4-works/). 4 | 5 | #![warn(missing_docs)] 6 | 7 | extern crate byteorder; 8 | #[macro_use] 9 | extern crate quick_error; 10 | 11 | mod decompress; 12 | mod compress; 13 | #[cfg(test)] 14 | mod tests; 15 | 16 | pub use decompress::{ 17 | decompress, 18 | decompress_into 19 | }; 20 | pub use compress::{ 21 | compress, 22 | compress_into 23 | }; 24 | -------------------------------------------------------------------------------- /mimalloc_rust/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock -------------------------------------------------------------------------------- /mimalloc_rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mimalloc" 3 | version = "0.1.29" 4 | authors = [ 5 | "Octavian Oncescu ", 6 | "Vincent Rouillé ", 7 | "Thom Chiovoloni ", 8 | ] 9 | edition = "2018" 10 | repository = "https://github.com/purpleprotocol/mimalloc_rust" 11 | keywords = ["mimalloc", "allocator", "encrypted-heap", "performance"] 12 | categories = ["memory-management", "api-bindings"] 13 | description = "Performance and security oriented drop-in allocator" 14 | license = "MIT" 15 | readme = "README.md" 16 | 17 | [badges] 18 | travis-ci = { repository = "purpleprotocol/mimalloc_rust" } 19 | 20 | [dependencies] 21 | libmimalloc-sys = { path = "libmimalloc-sys", version = "0.1.25", default-features = false } 22 | 23 | [features] 24 | default = ["secure"] 25 | secure = ["libmimalloc-sys/secure"] 26 | override = ["libmimalloc-sys/override"] 27 | debug = ["libmimalloc-sys/debug"] 28 | debug_in_debug = ["libmimalloc-sys/debug_in_debug"] 29 | local_dynamic_tls = ["libmimalloc-sys/local_dynamic_tls"] 30 | -------------------------------------------------------------------------------- /mimalloc_rust/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2019 Octavian Oncescu 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libmimalloc-sys" 3 | version = "0.1.25" 4 | authors = ["Octavian Oncescu "] 5 | edition = "2018" 6 | repository = "https://github.com/purpleprotocol/mimalloc_rust/tree/master/libmimalloc-sys" 7 | keywords = ["allocator", "encrypted-heap", "performance"] 8 | categories = ["memory-management", "api-bindings"] 9 | description = "Sys crate wrapping the mimalloc allocator" 10 | license = "MIT" 11 | links = "mimalloc" 12 | 13 | [dependencies] 14 | cty = { version = "0.2", optional = true } 15 | 16 | [build-dependencies] 17 | cc = "1.0" 18 | 19 | [features] 20 | secure = [] 21 | debug = [] 22 | debug_in_debug = [] 23 | override = [] 24 | extended = ["cty"] 25 | local_dynamic_tls = [] 26 | 27 | # Show `extended` on docs.rs since it's the full API surface. 28 | [package.metadata.docs.rs] 29 | features = ["extended"] 30 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/.gitattributes: -------------------------------------------------------------------------------- 1 | # default behavior is to always use unix style line endings 2 | * text eol=lf 3 | *.png binary 4 | *.pdn binary 5 | *.jpg binary 6 | *.sln binary 7 | *.suo binary 8 | *.vcproj binary 9 | *.patch binary 10 | *.dll binary 11 | *.lib binary 12 | *.exe binary 13 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/.gitignore: -------------------------------------------------------------------------------- 1 | ide/vs20??/*.db 2 | ide/vs20??/*.opendb 3 | ide/vs20??/*.user 4 | ide/vs20??/*.vcxproj.filters 5 | ide/vs20??/.vs 6 | out/ 7 | docs/ 8 | *.zip 9 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/mimalloc-redirect.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/mimalloc-redirect.dll -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/mimalloc-redirect.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/mimalloc-redirect.lib -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/mimalloc-redirect32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/mimalloc-redirect32.dll -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/mimalloc-redirect32.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/mimalloc-redirect32.lib -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/minject.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/minject.exe -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/minject32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/bin/minject32.exe -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/cmake/mimalloc-config-version.cmake: -------------------------------------------------------------------------------- 1 | set(mi_version_major 2) 2 | set(mi_version_minor 0) 3 | set(mi_version_patch 6) 4 | set(mi_version ${mi_version_major}.${mi_version_minor}) 5 | 6 | set(PACKAGE_VERSION ${mi_version}) 7 | if(PACKAGE_FIND_VERSION_MAJOR) 8 | if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "${mi_version_major}") 9 | if ("${PACKAGE_FIND_VERSION_MINOR}" EQUAL "${mi_version_minor}") 10 | set(PACKAGE_VERSION_EXACT TRUE) 11 | elseif("${PACKAGE_FIND_VERSION_MINOR}" LESS "${mi_version_minor}") 12 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 13 | else() 14 | set(PACKAGE_VERSION_UNSUITABLE TRUE) 15 | endif() 16 | else() 17 | set(PACKAGE_VERSION_UNSUITABLE TRUE) 18 | endif() 19 | endif() 20 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/cmake/mimalloc-config.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/mimalloc.cmake) 2 | get_filename_component(MIMALLOC_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}" PATH) # one up from the cmake dir, e.g. /usr/local/lib/cmake/mimalloc-2.0 3 | get_filename_component(MIMALLOC_VERSION_DIR "${CMAKE_CURRENT_LIST_DIR}" NAME) 4 | string(REPLACE "/lib/cmake" "/lib" MIMALLOC_LIBRARY_DIR "${MIMALLOC_CMAKE_DIR}") 5 | if("${MIMALLOC_VERSION_DIR}" EQUAL "mimalloc") 6 | # top level install 7 | string(REPLACE "/lib/cmake" "/include" MIMALLOC_INCLUDE_DIR "${MIMALLOC_CMAKE_DIR}") 8 | set(MIMALLOC_OBJECT_DIR "${MIMALLOC_LIBRARY_DIR}") 9 | else() 10 | # versioned 11 | string(REPLACE "/lib/cmake/" "/include/" MIMALLOC_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}") 12 | string(REPLACE "/lib/cmake/" "/lib/" MIMALLOC_OBJECT_DIR "${CMAKE_CURRENT_LIST_DIR}") 13 | endif() 14 | set(MIMALLOC_TARGET_DIR "${MIMALLOC_LIBRARY_DIR}") # legacy 15 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/ds-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/ds-logo.jpg -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/ds-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/ds-logo.png -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/mimalloc-doxygen.css: -------------------------------------------------------------------------------- 1 | #projectlogo img { 2 | padding: 1ex; 3 | } 4 | tt, code, kbd, samp, div.memproto, div.fragment, div.line, table.memname { 5 | font-family: Consolas, Monaco, Inconsolata, "Courier New", monospace; 6 | } 7 | .image img, .textblock img { 8 | max-width: 99%; 9 | max-height: 350px; 10 | } 11 | table.memname, .memname{ 12 | font-weight: bold; 13 | } 14 | code { 15 | background-color: #EEE; 16 | padding: 0ex 0.25ex; 17 | } 18 | body { 19 | margin: 1ex 1ex 0ex 1ex; 20 | border: 1px solid black; 21 | } 22 | .contents table, .contents div, .contents p, .contents dl { 23 | font-size: 16px; 24 | line-height: 1.44; 25 | } 26 | body #nav-tree .label { 27 | font-size: 14px; 28 | } 29 | a{ 30 | text-decoration: underline; 31 | } 32 | #side-nav { 33 | margin-left: 1ex; 34 | border-left: 1px solid black; 35 | } 36 | #nav-tree { 37 | padding-left: 1ex; 38 | } 39 | #nav-path { 40 | display: none; 41 | } 42 | div.fragment { 43 | background-color: #EEE; 44 | padding: 0.25ex 0.5ex; 45 | border-color: black; 46 | } 47 | #nav-sync img { 48 | display: none; 49 | } 50 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/mimalloc-logo-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/mimalloc-logo-100.png -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/mimalloc-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/mimalloc-logo.png -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/spades-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/mimalloc_rust/libmimalloc-sys/c_src/mimalloc/doc/spades-logo.png -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/test/main-override.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | int main() { 9 | mi_version(); // ensure mimalloc library is linked 10 | void* p1 = malloc(78); 11 | void* p2 = malloc(24); 12 | free(p1); 13 | p1 = malloc(8); 14 | //char* s = strdup("hello\n"); 15 | free(p2); 16 | p2 = malloc(16); 17 | p1 = realloc(p1, 32); 18 | free(p1); 19 | free(p2); 20 | //free(s); 21 | //mi_collect(true); 22 | 23 | /* now test if override worked by allocating/freeing across the api's*/ 24 | //p1 = mi_malloc(32); 25 | //free(p1); 26 | //p2 = malloc(32); 27 | //mi_free(p2); 28 | p1 = malloc(24); 29 | p2 = reallocarray(p1, 16, 16); 30 | free(p2); 31 | p1 = malloc(24); 32 | assert(reallocarr(&p1, 16, 16) == 0); 33 | free(p1); 34 | mi_stats_print(NULL); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void test_heap(void* p_out) { 6 | mi_heap_t* heap = mi_heap_new(); 7 | void* p1 = mi_heap_malloc(heap,32); 8 | void* p2 = mi_heap_malloc(heap,48); 9 | mi_free(p_out); 10 | mi_heap_destroy(heap); 11 | //mi_heap_delete(heap); mi_free(p1); mi_free(p2); 12 | } 13 | 14 | void test_large() { 15 | const size_t N = 1000; 16 | 17 | for (size_t i = 0; i < N; ++i) { 18 | size_t sz = 1ull << 21; 19 | char* a = mi_mallocn_tp(char,sz); 20 | for (size_t k = 0; k < sz; k++) { a[k] = 'x'; } 21 | mi_free(a); 22 | } 23 | } 24 | 25 | int main() { 26 | void* p1 = mi_malloc(16); 27 | void* p2 = mi_malloc(1000000); 28 | mi_free(p1); 29 | mi_free(p2); 30 | p1 = mi_malloc(16); 31 | p2 = mi_malloc(16); 32 | mi_free(p1); 33 | mi_free(p2); 34 | 35 | test_heap(mi_malloc(32)); 36 | 37 | p1 = mi_malloc_aligned(64, 16); 38 | p2 = mi_malloc_aligned(160,24); 39 | mi_free(p2); 40 | mi_free(p1); 41 | //test_large(); 42 | 43 | mi_collect(true); 44 | mi_stats_print(NULL); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/c_src/mimalloc/test/readme.md: -------------------------------------------------------------------------------- 1 | Testing allocators is difficult as bugs may only surface after particular 2 | allocation patterns. The main approach to testing _mimalloc_ is therefore 3 | to have extensive internal invariant checking (see `page_is_valid` in `page.c` 4 | for example), which is enabled in debug mode with `-DMI_DEBUG_FULL=ON`. 5 | The main testing strategy is then to run [`mimalloc-bench`][bench] using full 6 | invariant checking to catch any potential problems over a wide range of intensive 7 | allocation benchmarks and programs. 8 | 9 | However, this does not test well for the entire API surface and this is tested 10 | with `test-api.c` when using `make test` (from `out/debug` etc). (This is 11 | not complete yet, please add to it.) 12 | 13 | The `main.c` and `main-override.c` are there to test if building and overriding 14 | from a local install works and therefore these build a separate `test/CMakeLists.txt`. 15 | 16 | [bench]: https://github.com/daanx/mimalloc-bench 17 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/sys-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libmimalloc-sys-test" 3 | version = "0.1.0" 4 | authors = ["Thom Chiovoloni "] 5 | edition = "2018" 6 | description = "Bindings test for libmimalloc-sys" 7 | license = "MIT" 8 | publish = false 9 | 10 | [dependencies] 11 | libmimalloc-sys = { path = "..", features = ["extended"] } 12 | libc = "0.2" 13 | 14 | [build-dependencies] 15 | ctest2 = "0.4" 16 | -------------------------------------------------------------------------------- /mimalloc_rust/libmimalloc-sys/sys-test/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(bad_style, clippy::all)] 2 | 3 | use libmimalloc_sys::*; 4 | 5 | include!(concat!(env!("OUT_DIR"), "/all.rs")); 6 | -------------------------------------------------------------------------------- /preload/src/arch.rs: -------------------------------------------------------------------------------- 1 | pub const TARGET_ARCH: &str = std::env::consts::ARCH; 2 | 3 | #[cfg(target_endian = "little")] 4 | pub const IS_LITTLE_ENDIAN: bool = true; 5 | 6 | #[cfg(target_endian = "big")] 7 | pub const IS_LITTLE_ENDIAN: bool = false; 8 | -------------------------------------------------------------------------------- /preload/src/nohash.rs: -------------------------------------------------------------------------------- 1 | #[derive(Default)] 2 | pub struct NoHash; 3 | 4 | impl std::hash::BuildHasher for NoHash { 5 | type Hasher = NoHasher; 6 | fn build_hasher( &self ) -> Self::Hasher { 7 | NoHasher( 0 ) 8 | } 9 | } 10 | 11 | pub struct NoHasher( u64 ); 12 | impl std::hash::Hasher for NoHasher { 13 | fn finish( &self ) -> u64 { 14 | self.0 15 | } 16 | 17 | fn write( &mut self, _bytes: &[u8] ) { 18 | unimplemented!() 19 | } 20 | 21 | fn write_u32( &mut self, value: u32 ) { 22 | self.0 ^= value as u64; 23 | } 24 | 25 | fn write_u64( &mut self, value: u64 ) { 26 | self.0 ^= value; 27 | } 28 | 29 | fn write_usize( &mut self, value: usize ) { 30 | self.0 ^= value as u64; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /preload/src/timestamp.rs: -------------------------------------------------------------------------------- 1 | use libc; 2 | 3 | pub use common::Timestamp; 4 | 5 | pub fn get_timestamp() -> Timestamp { 6 | let mut timespec = libc::timespec { 7 | tv_sec: 0, 8 | tv_nsec: 0 9 | }; 10 | 11 | unsafe { 12 | libc::clock_gettime( libc::CLOCK_MONOTONIC, &mut timespec ); 13 | } 14 | 15 | Timestamp::from_timespec( timespec.tv_sec as u64, timespec.tv_nsec as u64 ) 16 | } 17 | 18 | pub fn get_wall_clock() -> (Timestamp, u64, u64) { 19 | let timestamp = get_timestamp(); 20 | let mut timespec = libc::timespec { 21 | tv_sec: 0, 22 | tv_nsec: 0 23 | }; 24 | 25 | unsafe { 26 | libc::clock_gettime( libc::CLOCK_REALTIME, &mut timespec ); 27 | } 28 | 29 | (timestamp, timespec.tv_sec as u64, timespec.tv_nsec as u64) 30 | } 31 | -------------------------------------------------------------------------------- /replay/Makefile: -------------------------------------------------------------------------------- 1 | all: replay 2 | 3 | replay: replay.cpp generated.inc 4 | c++ replay.cpp -O1 -fno-tree-tail-merge -fno-inline -fasynchronous-unwind-tables -o replay -ldl -pthread 5 | 6 | generated.inc: generate.sh 7 | ./generate.sh 8 | -------------------------------------------------------------------------------- /replay/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | FRAME_COUNT=8192 4 | 5 | echo "" > generated.inc 6 | echo "frame_t FRAMES[] = {" >> generated.inc 7 | 8 | for i in $(seq 0 $(($FRAME_COUNT-2))); do 9 | echo " frame_n<$i>," >> generated.inc 10 | done 11 | 12 | echo " frame_n<$(($FRAME_COUNT-1))>" >> generated.inc 13 | 14 | echo "};" >> generated.inc 15 | echo "size_t FRAME_COUNT = $FRAME_COUNT;" >> generated.inc 16 | -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | nightly-2022-10-13 -------------------------------------------------------------------------------- /screenshot_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/screenshot_graph.png -------------------------------------------------------------------------------- /screenshot_gui_group_by_backtrace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/screenshot_gui_group_by_backtrace.png -------------------------------------------------------------------------------- /screenshot_gui_memory_usage_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/screenshot_gui_memory_usage_graph.png -------------------------------------------------------------------------------- /screenshot_gui_scripting_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/screenshot_gui_scripting_console.png -------------------------------------------------------------------------------- /server-core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "server-core" 3 | version = "0.11.0" 4 | authors = ["Jan Bujak "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | log = "0.4" 9 | actix = "0.8" 10 | actix-web = { version = "1.0", default-features = false } 11 | actix-cors = "0.1" 12 | serde = "1" 13 | serde_json = "1" 14 | serde_derive = "1" 15 | cli-core = { path = "../cli-core" } 16 | futures = "0.1" 17 | serde_urlencoded = "0.5" 18 | regex = "1" 19 | bytes = "0.4" 20 | lru = "0.6" 21 | parking_lot = "0.12" 22 | common = { path = "../common" } 23 | ahash = "0.7" 24 | rayon = "1" 25 | md5 = "0.7" 26 | 27 | [build-dependencies] 28 | semalock = "0.2" 29 | -------------------------------------------------------------------------------- /server-core/src/streaming_serializer.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Serializer}; 2 | use std::cell::RefCell; 3 | 4 | pub struct StreamingSerializer< F, R, T > 5 | where F: FnOnce() -> R, 6 | R: Iterator< Item = T > 7 | { 8 | callback: RefCell< Option< F > > 9 | } 10 | 11 | impl< F, R, T > StreamingSerializer< F, R, T > 12 | where F: FnOnce() -> R, 13 | R: Iterator< Item = T >, 14 | T: Serialize 15 | { 16 | pub fn new( callback: F ) -> Self { 17 | StreamingSerializer { callback: RefCell::new( Some( callback ) ) } 18 | } 19 | } 20 | 21 | impl< F, R, T > Serialize for StreamingSerializer< F, R, T > 22 | where F: FnOnce() -> R, 23 | R: Iterator< Item = T >, 24 | T: Serialize 25 | { 26 | fn serialize< S: Serializer >( &self, serializer: S ) -> Result< S::Ok, S::Error > { 27 | use serde::ser::SerializeSeq; 28 | 29 | let iter = (self.callback.borrow_mut().take().unwrap())(); 30 | let mut seq = serializer.serialize_seq( None )?; 31 | for element in iter { 32 | seq.serialize_element( &element )?; 33 | } 34 | 35 | seq.end() 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /simulation/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /simulation/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "simulation" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | oorandom = "11" 10 | jemallocator = { version = "0.3", optional = true } 11 | 12 | [workspace] 13 | -------------------------------------------------------------------------------- /simulation/generate-simulation-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | cd "$(dirname $(readlink -f "$0"))" 5 | 6 | echo "Building the simulation..." 7 | cargo build 8 | cd .. 9 | 10 | echo "Building the profiler..." 11 | cargo build -p bytehound-preload 12 | 13 | echo "Building the CLI..." 14 | cargo build -p bytehound-cli 15 | 16 | echo "Profiling the simulation..." 17 | export MEMORY_PROFILER_OUTPUT=simulation/memory-profiling-simulation-raw.dat 18 | LD_PRELOAD=target/debug/libbytehound.so simulation/target/debug/simulation 19 | 20 | target/debug/bytehound postprocess --anonymize=partial -o simulation/memory-profiling-simulation.dat simulation/memory-profiling-simulation-raw.dat 21 | rm -f simulation/memory-profiling-simulation-raw.dat 22 | 23 | echo "Profiling data generated: memory-profiling-simulation.dat" 24 | -------------------------------------------------------------------------------- /simulation/memory-profiling-simulation.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koute/bytehound/f8397e70efcdad1d48c4999d609d786ed8ab988b/simulation/memory-profiling-simulation.dat -------------------------------------------------------------------------------- /webui/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [], 3 | "plugins": [] 4 | } 5 | -------------------------------------------------------------------------------- /webui/README.md: -------------------------------------------------------------------------------- 1 | ## Fixing `ENOSPC: no space left on device` error when running `yarn start` 2 | 3 | sudo sysctl fs.inotify.max_user_watches=131072 4 | -------------------------------------------------------------------------------- /webui/src/Feather.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import FEATHER_SPRITE_URL from "feather-icons/dist/feather-sprite.svg"; 3 | 4 | export default class Feather extends React.Component { 5 | render() { 6 | const src = FEATHER_SPRITE_URL + "#" + this.props.name; 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /webui/src/import-bootstrap.js: -------------------------------------------------------------------------------- 1 | import "./import-jquery.js"; 2 | import "./import-popper.js"; 3 | import "bootstrap/dist/css/bootstrap.min.css"; 4 | import "bootstrap/dist/js/bootstrap.min.js"; 5 | -------------------------------------------------------------------------------- /webui/src/import-jquery.js: -------------------------------------------------------------------------------- 1 | import jquery from "jquery/dist/jquery.slim.min.js"; 2 | export default (window.$ = window.jQuery = jquery); 3 | -------------------------------------------------------------------------------- /webui/src/import-popper.js: -------------------------------------------------------------------------------- 1 | import "popper.js/dist/popper.min.js" 2 | -------------------------------------------------------------------------------- /webui/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /webui/src/index.js: -------------------------------------------------------------------------------- 1 | import "./import-bootstrap.js"; 2 | import "bootswatch/dist/spacelab/bootstrap.min.css"; 3 | import "font-awesome/css/font-awesome.min.css"; 4 | import "react-table/react-table.css"; 5 | 6 | import React from "react"; 7 | import ReactDOM from "react-dom"; 8 | import { HashRouter, withRouter } from "react-router-dom"; 9 | 10 | import App from "./App"; 11 | 12 | import "./index.css"; 13 | 14 | const AppWithRouter = withRouter(App); 15 | 16 | let sourceUrl; 17 | 18 | // Is there a better way to detect that we're running under Parcel? 19 | if( module.hot ) { 20 | sourceUrl = "http://localhost:8080"; 21 | } else { 22 | sourceUrl = window.location.origin; 23 | } 24 | 25 | ReactDOM.render( 26 | 27 | 28 | , 29 | document.getElementById( "root" ) 30 | ); 31 | 32 | if( module.hot ) { 33 | module.hot.accept(); 34 | } 35 | --------------------------------------------------------------------------------