[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings\n# but database connection strings (with potential passwords) will be unencrypted\n#*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n/BenchmarkDotNet.Artifacts/results\n/jemalloc.Cli/BenchmarkDotNet.Artifacts/results\n/jemalloc.Cli/Properties/launchSettings.json\n/*.ppm\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"jemalloc\"]\n\tpath = jemalloc\n\turl = https://github.com/allisterb/jemalloc.git\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Allister Beharry\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# jemalloc.NET: A native memory manager for .NET\n\n![jembench](https://lh3.googleusercontent.com/QtV_Eviddx-ORMhVoU7L6N5aC5t8AQKqq_Un-GN8vtpAal2myXTM8G8zWnQUnV9STwtu7UewFzgNU4v2bjZHskicjV5xFFO_078aIJu842O3fbEZ4kD1jjQ5ffIArPafQ_860zxRaw=w1224-h693-no)\n\nGet the latest 0.2.x release from the [releases](https://github.com/allisterb/jemalloc.NET/releases) page.\n\njemalloc.NET is a .NET API over the [jemalloc](http://jemalloc.net/) native memory allocator and provides .NET applications with efficient data structures backed by native memory for large scale in-memory computation scenarios. jemalloc is \"a general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support\" that is [widely used](https://github.com/jemalloc/jemalloc/wiki/Background#adoption) in the industry, particularly in applications that must [scale and utilize](http://highscalability.com/blog/2015/3/17/in-memory-computing-at-aerospike-scale-when-to-choose-and-ho.html) large amounts of memory. In addition to its fragmentation and concurrency optimizations, jemalloc provides an array of developer options for debugging, monitoring and tuning allocations that makes it a great choice for use in developing memory-intensive applications.\n\nThe jemalloc.NET project provides:\n* A low-level .NET API over the native jemalloc API functions like je_malloc, je_calloc, je_free, je_mallctl...\n* A safety-focused high-level .NET API providing data structures like arrays backed by native memory allocated using jemalloc together with management features like reference counting and acceleration features like SIMD vectorized operations via the `Vector<T>` .NET type.\n* A benchmark CLI program: `jembench` which uses the excellent [BenchmarkDotNet](http://benchmarkdotnet.org/index.htm) library for easy and accurate benchmarking operations on native data structures vs managed objects using different parameters.\n\nThe high-level .NET API makes use of newly introduced C# and .NET features and classes like ref returns, `Span<T>`, `Vector<T>`, and `Unsafe<T>` from the `System.Runtime.CompilerServices.Unsafe` libraries, for working effectively with pointers to managed and unmanaged memory.\n\nData structures provided by the high-level API are more efficient than managed .NET arrays and objects at the scale of millions of elements, and memory allocation is much more resistant to fragmentation, while still providing necessary safety features like array bounds checking. Large .NET arrays must be allocated on the Large Object Heap and are not relocatable which leads to fragmentation and lower performance. In a [benchmark](https://github.com/allisterb/jemalloc.NET/blob/5d00a6969faf828261ce8f28492b0df2e7297dad/jemalloc.Benchmarks/Benchmarks/MallocVsArray.cs#L136) specifically designed to fragment managed and unmanaged memory using arrays of `Int32`, jemalloc.NET performs a order of magnitude better that the .NET managed heap allocator at the cost of higher memory utilization:\n\n``` ini\n\nBenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)\nProcessor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8\nFrequency=2531251 Hz, Resolution=395.0616 ns, Timer=TSC\n.NET Core SDK=2.1.2\n  [Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT\n\nJob=JemBenchmark  Jit=RyuJit  Platform=X64  \nRuntime=Core  AllowVeryLargeObjects=True  Toolchain=InProcessToolchain  \nRunStrategy=ColdStart  \n\n```\n|                                                                                       Method | Parameter |      Mean |     Error |    StdDev | PrivateMemory | Scaled | ScaledSD |       Gen 0 |       Gen 1 |       Gen 2 |   Allocated |\n|--------------------------------------------------------------------------------------------- |---------- |----------:|----------:|----------:|--------------:|-------:|---------:|------------:|------------:|------------:|------------:|\n|                       'Run an allocation pattern that won't fragment the Large Object Heap.' |       100 | 763.74 ms |  7.536 ms |  7.049 ms |       42.1 MB |   1.00 |     0.00 | 101000.0000 | 101000.0000 | 101000.0000 | 45436.08 MB |\n|                            'Run an allocation pattern that fragments the Large Object Heap.' |       100 | 786.95 ms | 15.568 ms | 19.689 ms |       76.0 MB |   1.03 |     0.03 | 101000.0000 | 101000.0000 | 101000.0000 | 45436.09 MB |\n| 'Run an allocation pattern that fragments the Large Object Heap with regular GC compaction.' |       100 | 790.30 ms | 15.392 ms | 19.466 ms |       75.9 MB |   1.03 |     0.03 | 111000.0000 | 111000.0000 | 111000.0000 | 45436.08 MB |\n|                          'Run an allocation pattern that won't fragment the unmanaged heap.' |       100 |  59.63 ms |  2.205 ms |  6.502 ms |       52.6 MB |   0.08 |     0.01 |   1000.0000 |   1000.0000 |   1000.0000 |     1.97 MB |\n|                               'Run an allocation pattern that fragments the unmanaged heap.' |       100 |  69.48 ms |  1.376 ms |  2.810 ms |       90.7 MB |   0.09 |     0.00 |   1000.0000 |   1000.0000 |   1000.0000 |     2.59 MB |\n\nYou can run this benchmark with the jembench command: `jembench malloc --fragment 100 -u -b --cold-start`\n\n\n\nIn the following `jembench` benchmark, simply filling an array is more or less the same across different kinds of memory and scales linearly depending on the size of the array, but *allocating* and filling a `UInt64[]` managed array of size 10000000 and 100000000 is more than 2x slower than using an equivalent native array provided by jemalloc.NET:\n\n``` ini\n\nBenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)\nProcessor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8\nFrequency=2531251 Hz, Resolution=395.0616 ns, Timer=TSC\n.NET Core SDK=2.1.2\n  [Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT\n\nJob=JemBenchmark  Jit=RyuJit  Platform=X64  \nRuntime=Core  AllowVeryLargeObjects=True  Toolchain=InProcessToolchain  \nRunStrategy=Throughput  \n\n```\n|                                                                          Method | Parameter |       Mean |     Error |    StdDev |     Median |    Gen 0 |    Gen 1 |    Gen 2 |   Allocated |\n|-------------------------------------------------------------------------------- |---------- |-----------:|----------:|----------:|-----------:|---------:|---------:|---------:|------------:|\n|                                     **'Fill a managed array with a single value.'** |  **10000000** |   **9.059 ms** | **0.1745 ms** | **0.4777 ms** |   **8.913 ms** |        **-** |        **-** |        **-** |       **208 B** |\n|            'Fill a SafeArray on the system unmanaged heap with a single value.' |  10000000 |   8.715 ms | 0.1682 ms | 0.2466 ms |   8.623 ms |        - |        - |        - |       208 B |\n|                          'Create and Fill a managed array with a single value.' |  10000000 |  32.867 ms | 0.9156 ms | 1.3420 ms |  32.175 ms | 142.8571 | 142.8571 | 142.8571 |  80000769 B |\n| 'Create and Fill a SafeArray on the system unmanaged heap with a single value.' |  10000000 |  13.809 ms | 0.2679 ms | 0.2506 ms |  13.727 ms |        - |        - |        - |       192 B |\n|                                     **'Fill a managed array with a single value.'** | **100000000** |  **90.326 ms** | **1.7718 ms** | **2.4253 ms** |  **89.468 ms** |        **-** |        **-** |        **-** |       **208 B** |\n|            'Fill a SafeArray on the system unmanaged heap with a single value.' | 100000000 |  88.377 ms | 0.9775 ms | 0.8665 ms |  88.505 ms |        - |        - |        - |       208 B |\n|                          'Create and Fill a managed array with a single value.' | 100000000 | 310.880 ms | 5.9732 ms | 8.1762 ms | 306.952 ms | 125.0000 | 125.0000 | 125.0000 | 800000624 B |\n| 'Create and Fill a SafeArray on the system unmanaged heap with a single value.' | 100000000 | 137.288 ms | 0.9710 ms | 0.9083 ms | 137.111 ms |        - |        - |        - |       192 B |\n\n\nYou can run this benchmark with the command `jembench array --fill 10000000 100000000 -l -u`. In this case we see that using the managed array of size 10 million elements allocated 800 MB on the managed heap while using the native array did not cause any allocations on the managed heap for the array data. Avoiding the managed heap for very large but simple data structures like arrays is a key optimizarion for apps that do large-scale in-memory computation.\n\n\nManaged .NET arays are also limited to `Int32` indexing and a maximum size of about 2.15 billion elements. jemalloc.NET provides huge arrays through the `HugeArray<T>` class which allows you to access all available memory as a flat contiguous buffer using array semantics. In the next benchmark `jembench hugearray --fill -i 4200000000`:\n\n``` ini\n\nBenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)\nProcessor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8\nFrequency=2531251 Hz, Resolution=395.0616 ns, Timer=TSC\n.NET Core SDK=2.1.2\n  [Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT\n\nJob=JemBenchmark  Jit=RyuJit  Platform=X64  \nRuntime=Core  AllowVeryLargeObjects=True  Toolchain=InProcessToolchain  \nRunStrategy=ColdStart  TargetCount=7  WarmupCount=-1  \n\n```\n|                                                                         Method |  Parameter |    Mean |    Error |   StdDev |    Allocated |\n|------------------------------------------------------------------------------- |----------- |--------:|---------:|---------:|-------------:|\n| 'Fill a managed array with the maximum size [2146435071] with a single value.' | 4200000000 | 3.177 s | 0.1390 s | 0.0617 s | 8585740456 B |\n|           'Fill a HugeArray on the system unmanaged heap with a single value.' | 4200000000 | 4.029 s | 3.2233 s | 1.4312 s |          0 B |\n\n\nan `Int32[]` of maximum size can be allocated and filled in 3.2s. This array consumes 8.6GB on the managed heap. But a jemalloc.NET `HugeArray<Int32>` of nearly double the size at 4.2 billion elements can be allocated in only 4 s and again consumes no memory on the managed heap. The only limit on the size of a `HugeArray<T>` is the available system memory.\n\nPerhaps the killer feature of the [recently introduced](https://blogs.msdn.microsoft.com/dotnet/2017/11/15/welcome-to-c-7-2-and-span/) `Span<T>` class in .NET is its ability to efficiently zero-copy reinterpret numeric data structures (`Int32, Int64` and their siblings) into other structures like the `Vector<T>` SIMD-enabled data types introduced in 2016. `Vector<T>` types are special in that the .NET RyuJIT compiler can compile operations on Vectors to use SIMD instructions like SSE, SSE2, and AVX for parallelizing operations on data on a single CPU core.\n\nUsing the SIMD-enabled `SafeBuffer<T>.VectorMultiply(n)` method provided by the jemalloc.NET API yields a more than 12x speedup for a simple in-place multiplication of a `UInt64[]` array of 10 million elements, compared to the unoptimized linear approach, allowing the operation to complete in 60 ms:\n\n``` ini\n\nBenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)\nProcessor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8\nFrequency=2531251 Hz, Resolution=395.0616 ns, Timer=TSC\n.NET Core SDK=2.1.2\n  [Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT\n\nJob=JemBenchmark  Jit=RyuJit  Platform=X64  \nRuntime=Core  AllowVeryLargeObjects=True  Toolchain=InProcessToolchain  \nRunStrategy=Throughput  \n\n```\n|                                                              Method | Parameter |      Mean |     Error |   StdDev |       Gen 0 |   Gen 1 |   Allocated |\n|-------------------------------------------------------------------- |---------- |----------:|----------:|---------:|------------:|--------:|------------:|\n|       'Multiply all values of a managed array with a single value.' |  10000000 | 761.10 ms | 10.367 ms | 9.190 ms | 254250.0000 | 62.5000 | 800000304 B |\n| 'Vector multiply all values of a native array with a single value.' |  10000000 |  59.23 ms |  1.170 ms | 1.149 ms |           - |       - |       360 B |\n\n\nFor huge arrays of `UInt16[]` we see similar speedups:\n``` ini\n\nBenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)\nProcessor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8\nFrequency=2531251 Hz, Resolution=395.0616 ns, Timer=TSC\n.NET Core SDK=2.1.2\n  [Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT\n\nJob=JemBenchmark  Jit=RyuJit  Platform=X64  \nRuntime=Core  AllowVeryLargeObjects=True  Toolchain=InProcessToolchain  \nRunStrategy=ColdStart  TargetCount=1  \n\n```\n|                                                                                           Method |  Parameter |    Mean | Error |         Gen 0 |     Gen 1 |     Allocated |\n|------------------------------------------------------------------------------------------------- |----------- |--------:|------:|--------------:|----------:|--------------:|\n| 'Multiply all values of a managed array with the maximum size [2146435071] with a single value.' | 4096000000 | 34.25 s |    NA | 16375000.0000 | 3000.0000 | 51514441704 B |\n|                              'Vector multiply all values of a native array with a single value.' | 4096000000 | 12.06 s |    NA |             - |         - |           0 B |\n\n\nFor a huge array with 4.1 billion `UInt16` values it takes 12 seconds to do a SIMD-enabled multiplication operation on all the elements of the array. This is still 3x the performance of doing the same non-vectorized operation on a managed array of half the size.\n\nInside a .NET application, jemalloc.NET native arrays and data structures can be straightforwardly accessed by native libraries without the need to make additional copies or allocations. The goal of the jemalloc.NET project is to make accessible to .NET the kind of big-data in-memory numeric, scientific and other computing that typically would require coding in a low-level language like C/C++ or assembly.\n\n## How it works\nMemory allocations are made using the jemalloc C functions like `je_malloc`, `je_calloc` etc, and returned as `IntPtr` pointers. Memory alignment is handled by jemalloc and memory allocations (called extents) are aligned to a multiple of the jemalloc page size e.g 4K. Inside extents, elements are aligned according to the .NET struct alignment specified using the `StructLayout` and other attributes. In the future the ability to manually align structures inside an extend and jemalloc's ability to manually align each extent (e.g using the `je_posix_memalign` function) may be exposed to alleviate potential [performance problems](http://adrianchadd.blogspot.se/2015/03/cache-line-aliasing-2-or-what-happens.html) with the default jemalloc page alignment.\n\nEach allocation pointer is tracked in a thread-safe allocations ledger together with a reference count. Each valid Jem.NET data structure has a pointer in the allocations ledger. There are other allocation ledgers that track details of different data structures like `FixedBufferAllocation`. When a pointer to an extent is released by a data stucture it is removed from all allocation ledgers. During the free operation the memory extent is filled with junk values by jemalloc as a safety feature however this feature and many other aspects of jemalloc can be turned off or on by the user.\n\nAny attempt to read or write data structure memory locations is guarded by checking that the data structure owns a valid pointer to the memory location. Since there can't be two pointers allocated with the same address at the same time, pointers act as a unique Id for tracking the active memory extents. Data structures are provided with reference counting methods like `Acquire()` and `Release()` to manage their lifetimes. Attempts to free or dispose of a data structure with a non-zero reference count will throw an exception. Unlike the stack-only `Span<T>` you are allowed to use class fields and properties to hold Jem.NET data structures like `FixedBuffer<T>` because `FixedBuffer<T>` guards every access to memory by first checking if the memory extent it is assigned is still valid. However you must take responsibility for using the reference counting features correctly i.e when sharing data structures between methods and threads you should always call `FixedBuffer<T>`.Acquire() to prevent a nethod from accidentally releasing the buffer's memory when it is in use. \n\nIn data structures like `FixedBuffer<T>` the primitive .NET types are always correctly aligned for SIMD vectorized operations and such operations like `FixedBuffer<T>.VectorMultiply()` can be significatnly faster than the non-optimized variants. E.g. an in-place multiplication of a `FixedBuffer<Uint16>` is many times faster than the same operation on a .NET `Uint16[]`:   \n\n``` ini\n\nBenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)\nProcessor=Intel Core i7-6700HQ CPU 2.60GHz (Skylake), ProcessorCount=8\nFrequency=2531251 Hz, Resolution=395.0616 ns, Timer=TSC\n.NET Core SDK=2.1.2\n  [Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT\n\nJob=JemBenchmark  Jit=RyuJit  Platform=X64  \nRuntime=Core  AllowVeryLargeObjects=True  Toolchain=InProcessToolchain  \nRunStrategy=Throughput  \n\n```\n|                                                              Method | Parameter |      Mean |     Error |    StdDev |       Gen 0 |  Gen 1 |   Allocated |\n|-------------------------------------------------------------------- |---------- |----------:|----------:|----------:|------------:|-------:|------------:|\n|       'Multiply all values of a managed array with a single value.' |  10000000 | 606.33 ms | 4.1602 ms | 3.4740 ms | 228875.0000 | 4.1667 | 703125.3 KB |\n| 'Vector multiply all values of a native array with a single value.' |  10000000 |  36.40 ms | 0.5256 ms | 0.4659 ms |           - |      - |     1.32 KB |\n\nPointers to data structure memory extents can be passed directly to unmanaged functions and libraries without the need for marshalling or more allocations. This is important when you want to build high-performance apps that use libraries written in C or assembly that process large amounts of in-memory data.\n## Installation\n### Requirements\nCurrently only runs on 64bit Windows; support for Linux 64bit and other 64bit platforms supported by .NET Core will be added\nsoon. \n\n#### Windows\n* The latest [.NET Core 2.0 x64 runtime](https://www.microsoft.com/net/download/thank-you/dotnet-runtime-2.0.3-windows-x64-installer)\n* The latest version of the [Microsoft Visual C++ Redistributable for Visual Studio 2017](https://go.microsoft.com/fwlink/?LinkId=746572) \n\n### Steps\nGrab the latest release from the [releases](https://github.com/allisterb/jemalloc.NET/releases) page and unzip to a folder. Type `jembench` to run the benchmark CLI program and you should see the program version and options printed. NuGet packagees can be found in x64\\Release. The API library assembly files themselves are in x64\\Release\\netstandard2.0\n\nNote that if using jemalloc.NET in your own projects you must put the native jemallocd.dll library somewhere where it can be  located by the .NET runtime. You can create a post-build step to copy it to the output folder of your project or put it somewhere on your %PATH%. \n\n\n## Usage\n\n### High-level API\n\nCurrently there are 4 implemented native memory data structures:\n### 1. `FixedBuffer<T>`\n`FixedBuffer<T>` is a fixed-length array of data backed by memory on the unmanaged heap, that is implemented as .NET `struct`. The underlying data type of a `FixedBuffer<T>` must be a [primitive](https://msdn.microsoft.com/en-us/library/system.type.isprimitive.aspx) type: Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, or Single. \n```\nFixedBuffer<Int64> buffer = new FixedBuffer<Int64>(1000000); // Create an array of 1 million Int64 integers.\nbuffer.Fill(100);\nlong a = buffer[10]; //copy on read\nref long b = ref buffer[10]; // no copy...b is an alias to the memory location of buffer[10]\n```\n\nPrimitives types have a maximum width of 64bits and (assuming correct memory alignment) can be read and updated atomically on machines with a 64bit word-size. This eliminates the possibility of 'struct tearing', or struct fields being read or written to inconsistently by multiple concurrent operations, because reads and writes to `FixedBuffer<T>` elements are only done directly to the underlying memory location for the data element. \n\nAll properties and fields of `FixedBuffer<T>` are readonly with only the index operator `[]` returing a `ref T` to the underlying data element. To use copy-on-read semantics simply create and assign variables to elements in the array. Use `ref` variables to get an alias to the memory location itself: \n\n\t\tFixedBuffer<int> b = ...;\n        int num = b[15];\n        num = 6; // b[15] is still 6\n        ref int r = ref b[15]; //get an alias to b[15]\n        r = 23; // b[15] is now\n\nAlthough `FixedBuffer<T>` is a .NET value type, only the metadata about the data structure is copied from one variable assignment to another. The actual data of a `FixedBuffer<T>` resides at a single memory location only. Each data access to a `<T>` element in a `FixedBuffer<T>` from all copies of a `FixedBuffer<T>` will read and write the same memory and makes the same guard checks against the same pointer in the allocations ledger. When the pointer used by a FixedBuffer<T> is released then every copy of a `FixedBuffer<T>` automatically becomes invalid. e.g:\n```\nFixedBuffer<int> array = new FixedBuffer<int>(100);\narray[16] = 1;\nFixedBuffer<int> copy = array;\nint a = copy[16]; // a is 16;\ncopy[5] = 99;\nint b = array[5]; // b is 99\ncopy.Free(); Invalidate the buffer from the copy\nint c = array[16]; //InvalidOperationException thrown here\n\n```    \n\nYou can create user-defined structures that contain `FixedBuffer<T>` e.g\n\n\t\tpublic struct Employee : IEquatable<Employee>\n        {\n        \t...\n        \tpublic DateTime? DOB { get; set; }         \n        \tpublic decimal Balance { get; set; }      \n        \tpublic FixedBuffer<float> BonusPayments { get; set; }          \n        \tpublic FixedBuffer<byte> Photo { get; set; } //8\n        }\nThe `FixedUtf8String` [type](https://github.com/allisterb/jemalloc.NET/blob/master/jemalloc.Api/FixedUtf8String.cs) is another `struct` that uses a `FixedBuffer<byte>` for storage of string data. \n\n```\n \t\t\n        public readonly struct FixedUtf8String : IEquatable<FixedUtf8String>, IRetainable, IDisposable\n\t\t{\n    \t\t...\n            \n            #region Fields\n        \t\n        \tprivate readonly FixedBuffer<byte> buffer;\n\n        \tprivate const int StringNotFound = -1;\n\n        \t...\n```\nEach `FixedBuffer<T>` has a constructor from `T[]` which copies the data from the managed array to the unmanaged buffer allocated. \n\n```\npublic static TestUDT MakeTestRecord(Random rng)\n        {\n            Guid _id = Guid.NewGuid();\n            string _ids = _id.ToString(\"N\");\n            byte[] photo = new byte[4096];\n            rng.NextBytes(photo);\n            return new TestUDT()\n            {\n                ID = _id,\n                FirstName = new FixedUtf8String(\"Gavial-\" + _id.ToString(\"D\").Substring(0, 4)),\n                LastName = new FixedUtf8String(\"Buxarinovich-\" + _id.ToString(\"D\").Substring(0, 4)),\n                DOB = _ids.StartsWith(\"7\") ? (DateTime?)null : DateTime.UtcNow,\n                Balance = 2131m,\n                Photo = new FixedBuffer<byte>(photo)\n            };\n        }\n```\nArrays of these kinds of user-defined structures can also be stored in native memory using the `SafeBuffer<T>` class.\n\n### 2. `SafeBuffer<T>` \n\n`SafeBuffer<T>` is a fixed-length array of data backed by memory on the unmanaged heap that inherits from the .NET `SafeHandle` class and is implemented as .NET `class` i.e a reference type. `SafeBuffer<T>` is an abstract class that can be used as the base to create data-structures like arrays or trees that are backed by unmanaged memory. The implemented `SafeArray<T>` class is the simplest concrete class that derives from `SafeBuffer`. `SafeArray<T>` can contain both primitive types and user-defined structures e.g:\n\n```\n public struct Employee : IEquatable<Employee>\n{\n        public Guid ID { get; set; }               \n        public FixedUtf8String FirstName { get; set; }      \n        public FixedUtf8String LastName { get; set; }       \n        public DateTime? DOB { get; set; }         \n        public decimal Salary { get; set; }       \n        public FixedBuffer<float> Bonuses { get; set; }          \n        public FixedBuffer<byte> Photo { get; set; } \n}\n...\npublic SafeArray<Employee> employees = new SafeArray<Employee>(100);\n```\nThe only restrictions on the type `T` of a `SafeBuffer<T>` is that it must be a struct and it must implement `IEquatable<T>`\n\n### 3. `FixedUtf8Buffer` \n`FixedUtf8Buffer`is a fixed-length immutable string type using UTF-8 encoding that is backed by memory on the unmanaged heap and is implemented as a .NET `struct` You can create user-defined structures that contain a `FixedUtf8Buffer` or create a `SafeBuffer<FixedUtf8Buffer>` for representing arrays of stringd. Some commmon string operations are implemented like `IndexOf()` and `Substring()` and there is a constructor taking a .NET `String`.\n\n### 4. `HugeBuffer<T>`\n`HugeBuffer<T>` is similar to `SafeBuffer<T>` but with the ability to store and index up to `Int64.MaxValue` array elements. `HugeBuffer<T>` lets you treat all available memory as a linear contiguous buffer.\n\n### Tuning jemalloc\nThe jemalloc allocator contains many parameters that can be adjusted to suit the workload and allocation patterns of the application. \n\n`Jem.Init(string conf)`\n`Jem.SetMallCtlInt32(int value)`\n\n\n### jembench CLI\nExamples:\n* `jembench hugearray -l -u --math --cold-start -t 3 4096000000` Benchmark math operations on `HugeArray<UInt64>` arrays of size 4096000000 without benchmark warmup and only using 3 iterations of the target methods. Benchmarks on huge arrays can be lengthy so you should carefully choose the benchmark parameters affecting how long you want the benchmark to run,\n\n## Building from source\nCurrently build instuctions are only provided for Visual Studio 2017 on Windows but instructions for building on Linux will also be provided. jemalloc.NET is a 64-bit library only.\n### Requirements\n[Visual Studio 2017 15.5](https://www.visualstudio.com/en-us/news/releasenotes/vs2017-relnotes#15.5.1) with at least the following components:\n* C# 7.2 compiler\n* .NET Core 2.x SDK x64\n* MSVC 2017 compiler toolset v141 or higher\n* Windows 10 SDK for Desktop C++ version 10.0.10.15603 or higher. Note that if you only have higher versions installed you will need to retarget the jemalloc MSVC project to your SDK version from Visual Studio.  \n\nPer the instructions for building the native jemalloc library for Windows, you will also need Cygwin (32- or 64-bit )with the following packages:\n   * autoconf\n   * autogen\n   * gcc\n   * gawk\n   * grep\n   * sed\n\nCygwin tools aren't actually used for compiling jemalloc but for generating the header files. jemalloc on Windows is built using MSVC.\n\n### Steps\n0. You must add the [.NET Core](https://dotnet.myget.org/gallery/dotnet-core) NuGet [feed](https://dotnet.myget.org/F/dotnet-core/api/v3/index.json) on MyGet and also the [CoreFxLab](https://dotnet.myget.org/gallery/dotnet-corefxlab) [feed](https://dotnet.myget.org/F/dotnet-core/api/v3/index.json) to your NuGet package sources. You can do this in Visual Studio 2017 from Tools->Options->NuGet Package Manager menu item.\n1. Clone the project: `git clone https://github.com/alllisterb/jemalloc.NET` and init the submodules: `git submodule update --init --recursive`\n2. Open a x64 Native Tools Command Prompt for VS 2017 and temporarily add `Cygwin\\bin` to the PATH e.g `set PATH=%PATH%;C:\\cygwin\\bin`. Switch to the `jemalloc` subdirectory in your jemalloc.NET solution dir and run `sh -c \"CC=cl ./autogen.sh\"`. This will generate some files in the `jemalloc` subdirectory and only needs to be done once.\n4. From a Visual Studio 2017 Developer Command prompt run `build.cmd`. Alternatively you can load the solution in Visual Studio and using the \"Benchmark\" solution configuration build the entire solution. \n5. The solution should build without errors.\n6. Run `jembench` from the solution folder to see the project version and help."
  },
  {
    "path": "build.cmd",
    "content": "@echo off\n@setlocal\nset ERROR_CODE=0\ndotnet restore jemalloc.NET.sln\nif not %ERRORLEVEL%==0  (\n    echo Error restoring NuGet packages for jemalloc.NET.sln.\n    set ERROR_CODE=1\n    goto End\n)\nif [%1]==[] (\n    msbuild jemalloc.NET.sln /p:Configuration=Benchmark /p:Platform=x64\n) else (\n\tmsbuild jemalloc.NET.sln /p:Configuration=Benchmark /p:Platform=x64;%*\n)\nif not %ERRORLEVEL%==0  (\n    echo Error building jemalloc.NET.sln.\n    set ERROR_CODE=2\n    goto End\n)\n\n:End\n@endlocal\nexit /B %ERROR_CODE%\n\n"
  },
  {
    "path": "jemalloc.Api/Buffer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\n\nnamespace jemalloc\n{\n    public ref struct Buffer<T> where T : struct\n    {\n        public Buffer(int length)\n        {\n            _Ptr = IntPtr.Zero;\n            _Length = 0;\n            _SizeInBytes = 0;\n            _Timestamp = 0;\n            _Span = new Span<T>();\n            unsafe\n            {\n                _VoidPointer = (void*)_Ptr;\n            }\n            Allocate(length);\n        }\n        \n        #region Properties\n        public bool IsInvalid\n        {\n            get\n            {\n                return _Ptr == IntPtr.Zero;\n            }\n        }\n        public int Length\n        {\n            get\n            {\n                if (IsInvalid)\n                {\n                    return 0;\n                }\n                else\n                {\n                    return _Length;\n                }\n            }\n            \n        }\n\n        public ulong Size\n        {\n            get\n            {\n                if (IsInvalid)\n                {\n                    return 0;\n                }\n                else\n                {\n                    return _SizeInBytes;\n                }\n            }\n\n        }\n\n        public IntPtr Ptr\n        {\n            get\n            {\n                return _Ptr;\n                \n            }\n\n        }\n\n        public Span<T> Span\n        {\n            get\n            {\n                if (IsInvalid)\n                {\n                    throw new InvalidOperationException(\"The buffer is invalid.\");\n                }\n                else\n                {\n                    return _Span;\n                }\n            }\n\n        }\n\n        #endregion\n\n        #region Methods\n        private unsafe bool Allocate(int length)\n        {\n            _Ptr = Jem.Calloc((ulong) length, ElementSizeInBytes);\n            if (_Ptr != IntPtr.Zero)\n            {\n                _Length = length;\n                _SizeInBytes = (ulong)_Length * ElementSizeInBytes;\n                _Timestamp = DateTime.Now.Ticks;\n                _VoidPointer = _Ptr.ToPointer();\n                _Span = new Span<T>(_VoidPointer, _Length);\n                return true;\n            }\n            else return false;\n        }\n\n        public void Release()\n        {\n            if (IsInvalid)\n            {\n                return;\n            }\n            else if (Interlocked.Exchange(ref _Ptr, IntPtr.Zero) != IntPtr.Zero)\n            {\n                Jem.Free(_Ptr);\n            }\n        }\n\n       \n        public void Fill(T value)\n        {\n            if (IsInvalid)\n                throw new InvalidOperationException(\"The buffer is invalid.\");\n            Span.Fill(value);\n        }\n        #endregion\n\n        public ref T this[int index]\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get\n            {\n                if (IsInvalid)\n                    throw new InvalidOperationException(\"The buffer is invalid.\");\n                if (index >= (Length))\n                    throw new IndexOutOfRangeException();\n                unsafe\n                {\n                    return ref Unsafe.Add(ref Unsafe.AsRef<T>(_VoidPointer), index);\n                }\n            }\n        }\n\n        #region Fields\n        private static readonly Type ElementType = typeof(T);\n        private static readonly ulong ElementSizeInBytes = (ulong) JemUtil.SizeOfStruct<T>();\n        private ulong _SizeInBytes;\n        private int _Length;\n        private IntPtr _Ptr;\n        private unsafe void* _VoidPointer;\n        private long _Timestamp;\n        private Span<T> _Span;\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/BufferHelpers.cs",
    "content": "//Based on SpanHelpers.cs\n// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Diagnostics;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Runtime.CompilerServices;\n\nnamespace jemalloc\n{\n    internal static partial class BufferHelpers\n    {\n        public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)\n        {\n            Debug.Assert(searchSpaceLength >= 0);\n            Debug.Assert(valueLength >= 0);\n\n            if (valueLength == 0)\n                return 0;  // A zero-length sequence is always treated as \"found\" at the start of the search space.\n\n            byte valueHead = value;\n            ref byte valueTail = ref Unsafe.Add(ref value, 1);\n            int valueTailLength = valueLength - 1;\n\n            int index = 0;\n            for (; ; )\n            {\n                Debug.Assert(0 <= index && index <= searchSpaceLength); // Ensures no deceptive underflows in the computation of \"remainingSearchSpaceLength\".\n                int remainingSearchSpaceLength = searchSpaceLength - index - valueTailLength;\n                if (remainingSearchSpaceLength <= 0)\n                    break;  // The unsearched portion is now shorter than the sequence we're looking for. So it can't be there.\n\n                // Do a quick search for the first element of \"value\".\n                int relativeIndex = IndexOf(ref Unsafe.Add(ref searchSpace, index), valueHead, remainingSearchSpaceLength);\n                if (relativeIndex == -1)\n                    break;\n                index += relativeIndex;\n\n                // Found the first element of \"value\". See if the tail matches.\n                if (SequenceEqual(ref Unsafe.Add(ref searchSpace, index + 1), ref valueTail, valueTailLength))\n                    return index;  // The tail matched. Return a successful find.\n\n                index++;\n            }\n            return -1;\n        }\n\n        public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)\n        {\n            Debug.Assert(searchSpaceLength >= 0);\n            Debug.Assert(valueLength >= 0);\n\n            if (valueLength == 0)\n                return 0;  // A zero-length sequence is always treated as \"found\" at the start of the search space.\n\n            int index = -1;\n            for (int i = 0; i < valueLength; i++)\n            {\n                var tempIndex = IndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength);\n                if (tempIndex != -1)\n                {\n                    index = (index == -1 || index > tempIndex) ? tempIndex : index;\n                }\n            }\n            return index;\n        }\n\n\n\n        private const ulong XorPowerOfTwoToHighByte = (0x07ul |\n                                                       0x06ul << 8 |\n                                                       0x05ul << 16 |\n                                                       0x04ul << 24 |\n                                                       0x03ul << 32 |\n                                                       0x02ul << 40 |\n                                                       0x01ul << 48) + 1;\n\n        public static int IndexOf<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength)\n            where T : IEquatable<T>\n        {\n            Debug.Assert(searchSpaceLength >= 0);\n            Debug.Assert(valueLength >= 0);\n\n            if (valueLength == 0)\n                return 0;  // A zero-length sequence is always treated as \"found\" at the start of the search space.\n\n            T valueHead = value;\n            ref T valueTail = ref Unsafe.Add(ref value, 1);\n            int valueTailLength = valueLength - 1;\n\n            int index = 0;\n            for (;;)\n            {\n                Debug.Assert(0 <= index && index <= searchSpaceLength); // Ensures no deceptive underflows in the computation of \"remainingSearchSpaceLength\".\n                int remainingSearchSpaceLength = searchSpaceLength - index - valueTailLength;\n                if (remainingSearchSpaceLength <= 0)\n                    break;  // The unsearched portion is now shorter than the sequence we're looking for. So it can't be there.\n\n                // Do a quick search for the first element of \"value\".\n                int relativeIndex = IndexOf(ref Unsafe.Add(ref searchSpace, index), valueHead, remainingSearchSpaceLength);\n                if (relativeIndex == -1)\n                    break;\n                index += relativeIndex;\n\n                // Found the first element of \"value\". See if the tail matches.\n                if (SequenceEqual(ref Unsafe.Add(ref searchSpace, index + 1), ref valueTail, valueTailLength))\n                    return index;  // The tail matched. Return a successful find.\n\n                index++;\n            }\n            return -1;\n        }\n\n        public static unsafe int IndexOf<T>(ref T searchSpace, T value, int length)\n            where T : IEquatable<T>\n        {\n            Debug.Assert(length >= 0);\n\n            IntPtr index = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations\n            while (length >= 8)\n            {\n                length -= 8;\n\n                if (value.Equals(Unsafe.Add(ref searchSpace, index)))\n                    goto Found;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 1)))\n                    goto Found1;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 2)))\n                    goto Found2;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 3)))\n                    goto Found3;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 4)))\n                    goto Found4;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 5)))\n                    goto Found5;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 6)))\n                    goto Found6;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 7)))\n                    goto Found7;\n\n                index += 8;\n            }\n\n            if (length >= 4)\n            {\n                length -= 4;\n\n                if (value.Equals(Unsafe.Add(ref searchSpace, index)))\n                    goto Found;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 1)))\n                    goto Found1;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 2)))\n                    goto Found2;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 3)))\n                    goto Found3;\n\n                index += 4;\n            }\n\n            while (length > 0)\n            {\n                if (value.Equals(Unsafe.Add(ref searchSpace, index)))\n                    goto Found;\n\n                index += 1;\n                length--;\n            }\n            return -1;\n\n        Found: // Workaround for https://github.com/dotnet/coreclr/issues/13549\n            return (int)(byte*)index;\n        Found1:\n            return (int)(byte*)(index + 1);\n        Found2:\n            return (int)(byte*)(index + 2);\n        Found3:\n            return (int)(byte*)(index + 3);\n        Found4:\n            return (int)(byte*)(index + 4);\n        Found5:\n            return (int)(byte*)(index + 5);\n        Found6:\n            return (int)(byte*)(index + 6);\n        Found7:\n            return (int)(byte*)(index + 7);\n        }\n\n        public static bool SequenceEqual<T>(ref T first, ref T second, int length)\n            where T : IEquatable<T>\n        {\n            Debug.Assert(length >= 0);\n\n            if (Unsafe.AreSame(ref first, ref second))\n                goto Equal;\n\n            IntPtr index = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations\n            while (length >= 8)\n            {\n                length -= 8;\n\n                if (!Unsafe.Add(ref first, index).Equals(Unsafe.Add(ref second, index)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 1).Equals(Unsafe.Add(ref second, index + 1)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 2).Equals(Unsafe.Add(ref second, index + 2)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 3).Equals(Unsafe.Add(ref second, index + 3)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 4).Equals(Unsafe.Add(ref second, index + 4)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 5).Equals(Unsafe.Add(ref second, index + 5)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 6).Equals(Unsafe.Add(ref second, index + 6)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 7).Equals(Unsafe.Add(ref second, index + 7)))\n                    goto NotEqual;\n\n                index += 8;\n            }\n\n            if (length >= 4)\n            {\n                length -= 4;\n\n                if (!Unsafe.Add(ref first, index).Equals(Unsafe.Add(ref second, index)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 1).Equals(Unsafe.Add(ref second, index + 1)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 2).Equals(Unsafe.Add(ref second, index + 2)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 3).Equals(Unsafe.Add(ref second, index + 3)))\n                    goto NotEqual;\n\n                index += 4;\n            }\n\n            while (length > 0)\n            {\n                if (!Unsafe.Add(ref first, index).Equals(Unsafe.Add(ref second, index)))\n                    goto NotEqual;\n                index += 1;\n                length--;\n            }\n\n        Equal:\n            return true;\n\n        NotEqual: // Workaround for https://github.com/dotnet/coreclr/issues/13549\n            return false;\n        }\n\n        /// <summary>\n        /// Implements the copy functionality used by Span and ReadOnlySpan.\n        ///\n        /// NOTE: Fast span implements TryCopyTo in corelib and therefore this implementation\n        ///       is only used by portable span. The code must live in code that only compiles\n        ///       for portable span which means either each individual span implementation\n        ///       of this shared code file. Other shared SpanHelper.X.cs files are compiled\n        ///       for both portable and fast span implementations.\n        /// </summary>\n        public static unsafe void CopyTo<T>(ref T dst, int dstLength, ref T src, int srcLength)\n        {\n            Debug.Assert(dstLength != 0);\n\n            IntPtr srcByteCount = Unsafe.ByteOffset(ref src, ref Unsafe.Add(ref src, srcLength));\n            IntPtr dstByteCount = Unsafe.ByteOffset(ref dst, ref Unsafe.Add(ref dst, dstLength));\n\n            IntPtr diff = Unsafe.ByteOffset(ref src, ref dst);\n\n            bool isOverlapped = (sizeof(IntPtr) == sizeof(int))\n                ? (uint)diff < (uint)srcByteCount || (uint)diff > (uint)-(int)dstByteCount\n                : (ulong)diff < (ulong)srcByteCount || (ulong)diff > (ulong)-(long)dstByteCount;\n\n            if (!isOverlapped && !BufferHelpers.IsReferenceOrContainsReferences<T>())\n            {\n                ref byte dstBytes = ref Unsafe.As<T, byte>(ref dst);\n                ref byte srcBytes = ref Unsafe.As<T, byte>(ref src);\n                ulong byteCount = (ulong)srcByteCount;\n                ulong index = 0;\n\n                while (index < byteCount)\n                {\n                    uint blockSize = (byteCount - index) > uint.MaxValue ? uint.MaxValue : (uint)(byteCount - index);\n                    Unsafe.CopyBlock(\n                        ref Unsafe.Add(ref dstBytes, (IntPtr)index),\n                        ref Unsafe.Add(ref srcBytes, (IntPtr)index),\n                        blockSize);\n                    index += blockSize;\n                }\n            }\n            else\n            {\n                bool srcGreaterThanDst = (sizeof(IntPtr) == sizeof(int))\n                    ? (uint)diff > (uint)-(int)dstByteCount\n                    : (ulong)diff > (ulong)-(long)dstByteCount;\n\n                int direction = srcGreaterThanDst ? 1 : -1;\n                int runCount = srcGreaterThanDst ? 0 : srcLength - 1;\n\n                int loopCount = 0;\n                for (; loopCount < (srcLength & ~7); loopCount += 8)\n                {\n                    Unsafe.Add<T>(ref dst, runCount + direction * 0) = Unsafe.Add<T>(ref src, runCount + direction * 0);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 1) = Unsafe.Add<T>(ref src, runCount + direction * 1);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 2) = Unsafe.Add<T>(ref src, runCount + direction * 2);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 3) = Unsafe.Add<T>(ref src, runCount + direction * 3);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 4) = Unsafe.Add<T>(ref src, runCount + direction * 4);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 5) = Unsafe.Add<T>(ref src, runCount + direction * 5);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 6) = Unsafe.Add<T>(ref src, runCount + direction * 6);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 7) = Unsafe.Add<T>(ref src, runCount + direction * 7);\n                    runCount += direction * 8;\n                }\n                if (loopCount < (srcLength & ~3))\n                {\n                    Unsafe.Add<T>(ref dst, runCount + direction * 0) = Unsafe.Add<T>(ref src, runCount + direction * 0);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 1) = Unsafe.Add<T>(ref src, runCount + direction * 1);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 2) = Unsafe.Add<T>(ref src, runCount + direction * 2);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 3) = Unsafe.Add<T>(ref src, runCount + direction * 3);\n                    runCount += direction * 4;\n                    loopCount += 4;\n                }\n                for (; loopCount < srcLength; ++loopCount)\n                {\n                    Unsafe.Add<T>(ref dst, runCount) = Unsafe.Add<T>(ref src, runCount);\n                    runCount += direction;\n                }\n            }\n        }\n\n        /// <summary>\n        /// Computes \"start + index * sizeof(T)\", using the unsigned IntPtr-sized multiplication for 32 and 64 bits.\n        ///\n        /// Assumptions:\n        ///     Start and index are non-negative, and already pre-validated to be within the valid range of their containing Span.\n        ///\n        ///     If the byte length (Span.Length * sizeof(T)) does an unsigned overflow (i.e. the buffer wraps or is too big to fit within the address space),\n        ///     the behavior is undefined.\n        ///\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public static IntPtr Add<T>(this IntPtr start, int index)\n        {\n            Debug.Assert(start.ToInt64() >= 0);\n            Debug.Assert(index >= 0);\n\n            unsafe\n            {\n                if (sizeof(IntPtr) == sizeof(int))\n                {\n                    // 32-bit path.\n                    uint byteLength = (uint)index * (uint)Unsafe.SizeOf<T>();\n                    return (IntPtr)(((byte*)start) + byteLength);\n                }\n                else\n                {\n                    // 64-bit path.\n                    ulong byteLength = (ulong)index * (ulong)Unsafe.SizeOf<T>();\n                    return (IntPtr)(((byte*)start) + byteLength);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Determine if a type is eligible for storage in unmanaged memory.\n        /// Portable equivalent of RuntimeHelpers.IsReferenceOrContainsReferences{T}()\n        /// </summary>\n        public static bool IsReferenceOrContainsReferences<T>() => PerTypeValues<T>.IsReferenceOrContainsReferences;\n\n        private static bool IsReferenceOrContainsReferencesCore(Type type)\n        {\n            if (type.GetTypeInfo().IsPrimitive) // This is hopefully the common case. All types that return true for this are value types w/out embedded references.\n                return false;\n\n            if (!type.GetTypeInfo().IsValueType)\n                return true;\n\n            // If type is a Nullable<> of something, unwrap it first.\n            Type underlyingNullable = Nullable.GetUnderlyingType(type);\n            if (underlyingNullable != null)\n                type = underlyingNullable;\n\n            if (type.GetTypeInfo().IsEnum)\n                return false;\n\n            foreach (FieldInfo field in type.GetTypeInfo().DeclaredFields)\n            {\n                if (field.IsStatic)\n                    continue;\n                if (IsReferenceOrContainsReferencesCore(field.FieldType))\n                    return true;\n            }\n            return false;\n        }\n\n        public static bool IsReferenceOrContainsReferences(Type type, out FieldInfo referenceField)\n        {\n            referenceField = null;\n            if (type.GetTypeInfo().IsPrimitive) // This is hopefully the common case. All types that return true for this are value types w/out embedded references.\n                return false;\n\n            if (!type.GetTypeInfo().IsValueType)\n                return true;\n\n            // If type is a Nullable<> of something, unwrap it first.\n            Type underlyingNullable = Nullable.GetUnderlyingType(type);\n            if (underlyingNullable != null)\n                type = underlyingNullable;\n\n            if (type.GetTypeInfo().IsEnum)\n                return false;\n\n            foreach (FieldInfo field in type.GetTypeInfo().DeclaredFields)\n            {\n                if (field.IsStatic)\n                    continue;\n                if (IsReferenceOrContainsReferences(field.FieldType, out referenceField))\n                {\n                    referenceField = field;\n                    return true;\n                }\n            }\n            return false;\n        }\n\n\n\n        public static class PerTypeValues<T>\n        {\n            //\n            // Latch to ensure that excruciatingly expensive validation check for constructing a Span around a raw pointer is done\n            // only once per type.\n            //\n            public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T));\n\n            public static readonly T[] EmptyArray = new T[0];\n\n            public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment();\n\n            // Array header sizes are a runtime implementation detail and aren't the same across all runtimes. (The CLR made a tweak after 4.5, and Mono has an extra Bounds pointer.)\n            private static IntPtr MeasureArrayAdjustment()\n            {\n                T[] sampleArray = new T[1];\n                return Unsafe.ByteOffset<T>(ref Unsafe.As<JemPinnable<T>>(sampleArray).Data, ref sampleArray[0]);\n            }\n        }\n\n        public unsafe static void ClearLessThanPointerSized(byte* ptr, UIntPtr byteLength)\n        {\n            if (sizeof(UIntPtr) == sizeof(uint))\n            {\n                Unsafe.InitBlockUnaligned(ptr, 0, (uint)byteLength);\n            }\n            else\n            {\n                // PERF: Optimize for common case of length <= uint.MaxValue\n                ulong bytesRemaining = (ulong)byteLength;\n                uint bytesToClear = (uint)(bytesRemaining & uint.MaxValue);\n                Unsafe.InitBlockUnaligned(ptr, 0, bytesToClear);\n                bytesRemaining -= bytesToClear;\n                ptr += bytesToClear;\n                // Clear any bytes > uint.MaxValue\n                while (bytesRemaining > 0)\n                {\n                    bytesToClear = (bytesRemaining >= uint.MaxValue) ? uint.MaxValue : (uint)bytesRemaining;\n                    Unsafe.InitBlockUnaligned(ptr, 0, bytesToClear);\n                    ptr += bytesToClear;\n                    bytesRemaining -= bytesToClear;\n                }\n            }\n        }\n\n        public static unsafe void ClearLessThanPointerSized(ref byte b, UIntPtr byteLength)\n        {\n            if (sizeof(UIntPtr) == sizeof(uint))\n            {\n                Unsafe.InitBlockUnaligned(ref b, 0, (uint)byteLength);\n            }\n            else\n            {\n                // PERF: Optimize for common case of length <= uint.MaxValue\n                ulong bytesRemaining = (ulong)byteLength;\n                uint bytesToClear = (uint)(bytesRemaining & uint.MaxValue);\n                Unsafe.InitBlockUnaligned(ref b, 0, bytesToClear);\n                bytesRemaining -= bytesToClear;\n                long byteOffset = bytesToClear;\n                // Clear any bytes > uint.MaxValue\n                while (bytesRemaining > 0)\n                {\n                    bytesToClear = (bytesRemaining >= uint.MaxValue) ? uint.MaxValue : (uint)bytesRemaining;\n                    ref byte bOffset = ref Unsafe.Add(ref b, (IntPtr)byteOffset);\n                    Unsafe.InitBlockUnaligned(ref bOffset, 0, bytesToClear);\n                    byteOffset += bytesToClear;\n                    bytesRemaining -= bytesToClear;\n                }\n            }\n        }\n\n        public unsafe static void ClearPointerSizedWithoutReferences(ref byte b, UIntPtr byteLength)\n        {\n            // TODO: Perhaps do switch casing to improve small size perf\n\n            var i = IntPtr.Zero;\n            while (i.LessThanEqual(byteLength - sizeof(Reg64)))\n            {\n                Unsafe.As<byte, Reg64>(ref Unsafe.Add<byte>(ref b, i)) = default(Reg64);\n                i += sizeof(Reg64);\n            }\n            if (i.LessThanEqual(byteLength - sizeof(Reg32)))\n            {\n                Unsafe.As<byte, Reg32>(ref Unsafe.Add<byte>(ref b, i)) = default(Reg32);\n                i += sizeof(Reg32);\n            }\n            if (i.LessThanEqual(byteLength - sizeof(Reg16)))\n            {\n                Unsafe.As<byte, Reg16>(ref Unsafe.Add<byte>(ref b, i)) = default(Reg16);\n                i += sizeof(Reg16);\n            }\n            if (i.LessThanEqual(byteLength - sizeof(long)))\n            {\n                Unsafe.As<byte, long>(ref Unsafe.Add<byte>(ref b, i)) = 0;\n                i += sizeof(long);\n            }\n            // JIT: Should elide this if 64-bit\n            if (sizeof(IntPtr) == sizeof(int))\n            {\n                if (i.LessThanEqual(byteLength - sizeof(int)))\n                {\n                    Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, i)) = 0;\n                    i += sizeof(int);\n                }\n            }\n        }\n\n        public unsafe static void ClearPointerSizedWithReferences(ref IntPtr ip, UIntPtr pointerSizeLength)\n        {\n            // TODO: Perhaps do switch casing to improve small size perf\n\n            var i = IntPtr.Zero;\n            var n = IntPtr.Zero;\n            while ((n = i + 8).LessThanEqual(pointerSizeLength))\n            {\n                Unsafe.Add<IntPtr>(ref ip, i + 0) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 1) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 2) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 3) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 4) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 5) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 6) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 7) = default(IntPtr);\n                i = n;\n            }\n            if ((n = i + 4).LessThanEqual(pointerSizeLength))\n            {\n                Unsafe.Add<IntPtr>(ref ip, i + 0) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 1) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 2) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 3) = default(IntPtr);\n                i = n;\n            }\n            if ((n = i + 2).LessThanEqual(pointerSizeLength))\n            {\n                Unsafe.Add<IntPtr>(ref ip, i + 0) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 1) = default(IntPtr);\n                i = n;\n            }\n            if ((i + 1).LessThanEqual(pointerSizeLength))\n            {\n                Unsafe.Add<IntPtr>(ref ip, i) = default(IntPtr);\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private unsafe static bool LessThanEqual(this IntPtr index, UIntPtr length)\n        {\n            return (sizeof(UIntPtr) == sizeof(uint))\n                ? (int)index <= (int)length\n                : (long)index <= (long)length;\n        }\n\n        [StructLayout(LayoutKind.Sequential, Size = 64)]\n        private struct Reg64 { }\n        [StructLayout(LayoutKind.Sequential, Size = 32)]\n        private struct Reg32 { }\n        [StructLayout(LayoutKind.Sequential, Size = 16)]\n        private struct Reg16 { }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/Extensions/TypeExtensions.cs",
    "content": "/*Based on the CodeProject article by Yuri Astrakhan and Sasha Goldshtein:\n * https://www.codeproject.com/Articles/33382/Fast-Native-Structure-Reading-in-C-using-Dynamic-A\n**/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection;\n\nnamespace jemalloc.Extensions\n{\n    public static class TypeExtensions\n    {\n        /// <summary>\n        /// Gets a value indicating whether a type (or type's element type)\n        /// instance can be null in the underlying data store.\n        /// </summary>\n        /// <param name=\"type\">A <see cref=\"System.Type\"/> instance. </param>\n        /// <returns> True, if the type parameter is a closed generic nullable type; otherwise, False.</returns>\n        /// <remarks>Arrays of Nullable types are treated as Nullable types.</remarks>\n        public static bool IsNullable(this Type type)\n        {\n            while (type.IsArray)\n                type = type.GetElementType();\n\n            return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof (Nullable<>));\n        }\n\n        /// <summary>\n        /// Returns the underlying type argument of the specified type.\n        /// </summary>\n        /// <param name=\"type\">A <see cref=\"System.Type\"/> instance. </param>\n        /// <returns><list>\n        /// <item>The type argument of the type parameter,\n        /// if the type parameter is a closed generic nullable type.</item>\n        /// <item>The underlying Type if the type parameter is an enum type.</item>\n        /// <item>Otherwise, the type itself.</item>\n        /// </list>\n        /// </returns>\n        public static Type GetUnderlyingType(this Type type)\n        {\n            if (type == null) throw new ArgumentNullException(\"type\");\n\n            if (type.IsNullable())\n                type = type.GetGenericArguments()[0];\n\n            if (type.IsEnum)\n                type = Enum.GetUnderlyingType(type);\n\n            return type;\n        }\n\n        /// <summary>\n        /// Determines whether the specified types are considered equal.\n        /// </summary>\n        /// <param name=\"parent\">A <see cref=\"System.Type\"/> instance. </param>\n        /// <param name=\"child\">A type possible derived from the <c>parent</c> type</param>\n        /// <returns>True, when an object instance of the type <c>child</c>\n        /// can be used as an object of the type <c>parent</c>; otherwise, false.</returns>\n        /// <remarks>Note that nullable types does not have a parent-child relation to it's underlying type.\n        /// For example, the 'int?' type (nullable int) and the 'int' type\n        /// aren't a parent and it's child.</remarks>\n        public static bool IsSameOrParent(Type parent, Type child)\n        {\n            if (parent == null) throw new ArgumentNullException(\"parent\");\n            if (child == null) throw new ArgumentNullException(\"child\");\n\n            if (parent == child ||\n                child.IsEnum && Enum.GetUnderlyingType(child) == parent ||\n                child.IsSubclassOf(parent))\n            {\n                return true;\n            }\n\n            if (parent.IsInterface)\n            {\n                var interfaces = child.GetInterfaces();\n\n                foreach (var t in interfaces)\n                    if (t == parent)\n                        return true;\n            }\n\n            return false;\n        }\n\n        /// <summary>\n        /// Recursively checks if the type with all of its members are expressable as a value type that may be cast to a pointer.\n        /// Equivalent to what compiler does to check for CS0208 error of this statement:\n        ///        fixed (int* p = new int[5]) {}\n        /// \n        /// An unmanaged-type is any type that isnt a reference-type and doesnt contain reference-type fields \n        /// at any level of nesting. In other words, an unmanaged-type is one of the following:\n        ///  * sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.\n        ///  * Any enum-type.\n        ///  * Any pointer-type.\n        ///  * Any user-defined struct-type that contains fields of unmanaged-types only.\n        /// \n        /// Strings are not in that list, even though you can use them in structs. \n        /// Fixed-size arrays of unmanaged-types are allowed.\n        /// </summary>\n        public static void ThrowIfNotUnmanagedType(this Type type)\n        {\n            ThrowIfNotUnmanagedType(type, new Stack<Type>(4));\n        }\n\n        private static void ThrowIfNotUnmanagedType(Type type, Stack<Type> typesStack)\n        {\n            if ((!type.IsValueType && !type.IsPointer) || type.IsGenericType || type.IsGenericParameter || type.IsArray)\n                throw new ArgumentException(String.Format(\"Type {0} is not an unmanaged type\", type.FullName));\n\n            if (!type.IsPrimitive && !type.IsEnum && !type.IsPointer)\n                for (var p = type.DeclaringType; p != null; p = p.DeclaringType)\n                    if (p.IsGenericTypeDefinition)\n                        throw new ArgumentException(\n                            String.Format(\"Type {0} contains a generic type definition declaring type {1}\",\n                                          type.FullName, p.FullName));\n\n            try\n            {\n                typesStack.Push(type);\n\n                var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);\n\n                foreach (var f in fields)\n                    if (!typesStack.Contains(f.FieldType))\n                        ThrowIfNotUnmanagedType(f.FieldType);\n            }\n            catch (Exception ex)\n            {\n                throw new ArgumentException(\n                    String.Format(\"Error in subtype of type {0}. See InnerException.\", type.FullName), ex);\n            }\n            finally\n            {\n                typesStack.Pop();\n            }\n        }\n\n        /// <summary>\n        /// Substitutes the elements of an array of types for the type parameters\n        /// of the current generic type definition and returns a Type object\n        /// representing the resulting constructed type.\n        /// </summary>\n        /// <param name=\"type\">A <see cref=\"System.Type\"/> instance.</param>\n        /// <param name=\"typeArguments\">An array of types to be substituted for\n        /// the type parameters of the current generic type.</param>\n        /// <returns>A Type representing the constructed type formed by substituting\n        /// the elements of <paramref name=\"typeArguments\"/> for the type parameters\n        /// of the current generic type.</returns>\n        /// <seealso cref=\"System.Type.MakeGenericType\"/>\n        public static Type TranslateGenericParameters(this Type type, Type[] typeArguments)\n        {\n            // 'T paramName' case\n            //\n            if (type.IsGenericParameter)\n                return typeArguments[type.GenericParameterPosition];\n\n            // 'List<T> paramName' or something like that.\n            //\n            if (type.IsGenericType && type.ContainsGenericParameters)\n            {\n                Type[] genArgs = type.GetGenericArguments();\n\n                for (int i = 0; i < genArgs.Length; ++i)\n                    genArgs[i] = TranslateGenericParameters(genArgs[i], typeArguments);\n\n                return type.GetGenericTypeDefinition().MakeGenericType(genArgs);\n            }\n\n            // Non-generic type.\n            //\n            return type;\n        }\n    }\n}"
  },
  {
    "path": "jemalloc.Api/ExtentHooks.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\nusing System.Security;\n\nnamespace jemalloc\n{\n    public unsafe partial class ExtentHooks : IDisposable\n    {\n        [StructLayout(LayoutKind.Explicit, Size = 72)]\n        public partial struct __Internal\n        {\n            [FieldOffset(0)]\n            internal global::System.IntPtr alloc;\n\n            [FieldOffset(8)]\n            internal global::System.IntPtr dalloc;\n\n            [FieldOffset(16)]\n            internal global::System.IntPtr destroy;\n\n            [FieldOffset(24)]\n            internal global::System.IntPtr commit;\n\n            [FieldOffset(32)]\n            internal global::System.IntPtr decommit;\n\n            [FieldOffset(40)]\n            internal global::System.IntPtr purge_lazy;\n\n            [FieldOffset(48)]\n            internal global::System.IntPtr purge_forced;\n\n            [FieldOffset(56)]\n            internal global::System.IntPtr split;\n\n            [FieldOffset(64)]\n            internal global::System.IntPtr merge;\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemalloc\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint = \"??0extent_hooks_s@@QEAA@AEBU0@@Z\")]\n            internal static extern global::System.IntPtr cctor(global::System.IntPtr instance, global::System.IntPtr _0);\n        }\n\n        public global::System.IntPtr __Instance { get; protected set; }\n\n        protected int __PointerAdjustment;\n        internal static readonly global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, global::jemalloc.ExtentHooks> NativeToManagedMap = new global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, global::jemalloc.ExtentHooks>();\n        protected void*[] __OriginalVTables;\n\n        protected bool __ownsNativeInstance;\n\n        internal static global::jemalloc.ExtentHooks __CreateInstance(global::System.IntPtr native, bool skipVTables = false)\n        {\n            return new global::jemalloc.ExtentHooks(native.ToPointer(), skipVTables);\n        }\n\n        internal static global::jemalloc.ExtentHooks __CreateInstance(global::jemalloc.ExtentHooks.__Internal native, bool skipVTables = false)\n        {\n            return new global::jemalloc.ExtentHooks(native, skipVTables);\n        }\n\n        private static void* __CopyValue(global::jemalloc.ExtentHooks.__Internal native)\n        {\n            var ret = Marshal.AllocHGlobal(sizeof(global::jemalloc.ExtentHooks.__Internal));\n            *(global::jemalloc.ExtentHooks.__Internal*)ret = native;\n            return ret.ToPointer();\n        }\n\n        private ExtentHooks(global::jemalloc.ExtentHooks.__Internal native, bool skipVTables = false)\n            : this(__CopyValue(native), skipVTables)\n        {\n            __ownsNativeInstance = true;\n            NativeToManagedMap[__Instance] = this;\n        }\n\n        protected ExtentHooks(void* native, bool skipVTables = false)\n        {\n            if (native == null)\n                return;\n            __Instance = new global::System.IntPtr(native);\n        }\n\n        public ExtentHooks()\n        {\n            __Instance = Marshal.AllocHGlobal(sizeof(global::jemalloc.ExtentHooks.__Internal));\n            __ownsNativeInstance = true;\n            NativeToManagedMap[__Instance] = this;\n        }\n\n        public ExtentHooks(global::jemalloc.ExtentHooks _0)\n        {\n            __Instance = Marshal.AllocHGlobal(sizeof(global::jemalloc.ExtentHooks.__Internal));\n            __ownsNativeInstance = true;\n            NativeToManagedMap[__Instance] = this;\n            *((global::jemalloc.ExtentHooks.__Internal*)__Instance) = *((global::jemalloc.ExtentHooks.__Internal*)_0.__Instance);\n        }\n\n        public void Dispose()\n        {\n            Dispose(disposing: true);\n        }\n\n        public virtual void Dispose(bool disposing)\n        {\n            if (__Instance == IntPtr.Zero)\n                return;\n            global::jemalloc.ExtentHooks __dummy;\n            NativeToManagedMap.TryRemove(__Instance, out __dummy);\n            if (__ownsNativeInstance)\n                Marshal.FreeHGlobal(__Instance);\n            __Instance = IntPtr.Zero;\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/FixedBuffer.cs",
    "content": "﻿using System;\nusing System.Buffers;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Threading;\n\nnamespace jemalloc\n{\n    [StructLayout(LayoutKind.Sequential)]\n    [DebuggerDisplay(\"{DebuggerDisplay(),nq}\")]\n    public readonly struct FixedBuffer<T> : IDisposable, IRetainable, IEquatable<FixedBuffer<T>>, IEnumerable<T> where T : struct, IEquatable<T>, IComparable<T>, IConvertible\n    {\n        #region Constructors\n        public FixedBuffer(int length)\n        {\n            _Ptr = IntPtr.Zero;\n            _Length = 0;\n            _SizeInBytes = 0;\n            _Timestamp = 0;\n            IsReadOnly = false;\n            AllocateThreadId = 0;\n            Rid = JemUtil.Rng.Next(0, 4096);\n            if (length == 0)\n            {\n                throw new ArgumentException(\"FixedBuffer Length cannot be zero.\");\n            }\n            ThrowIfTypeNotPrimitive();\n            long t = DateTime.UtcNow.Ticks;\n            int th = Thread.CurrentThread.ManagedThreadId;\n            _Ptr = Jem.AllocateFixedBuffer<T>((ulong)length, ElementSizeInBytes, t, th, Rid);\n            if (_Ptr != IntPtr.Zero)\n            {\n                _Length = length;\n                _SizeInBytes = (ulong)_Length * ElementSizeInBytes;\n                _Timestamp = t;\n                AllocateThreadId = th;\n                \n            }\n            else throw new OutOfMemoryException($\"Could not allocate {(ulong)_Length * ElementSizeInBytes} bytes for {Name}\");\n        }\n\n        public FixedBuffer(int length, bool isReadOnly) : this(length)\n        {\n            IsReadOnly = true;\n\n        }\n        public FixedBuffer(T[] array) : this(array.Length)\n        {\n            ReadOnlySpan<T> arraySpan = new ReadOnlySpan<T>(array);\n            arraySpan.CopyTo(this.WriteSpan);\n        }\n\n        public FixedBuffer(Span<T> span) : this(span.Length)\n        {\n            span.CopyTo(this.WriteSpan);\n        }\n        public FixedBuffer(ReadOnlySpan<T> span) : this(span.Length)\n        {\n            IsReadOnly = true;\n            span.CopyTo(this.WriteSpan);\n        }\n        #endregion\n\n        #region Implemented members\n        public void Retain()\n        {\n            ThrowIfInvalid();\n            Jem.IncrementRefCount(_Ptr);\n        }\n        public bool Release()\n        {\n            ThrowIfInvalid();\n            if (RefCount == 0)\n            {\n                return false;\n            }\n            else\n            {\n                Jem.DecrementRefCount(_Ptr);\n                return true;\n            }\n         }\n\n        bool IEquatable<FixedBuffer<T>>.Equals(FixedBuffer<T> buffer)\n        {\n            ThrowIfInvalid();\n            return this._Ptr == buffer.Ptr && this.Length == buffer.Length && this._Timestamp == buffer.Timestamp \n                && this.AllocateThreadId == buffer.AllocateThreadId && this.Rid == buffer.Rid;\n        }\n\n        public IEnumerator<T> GetEnumerator() => new FixedBufferEnumerator<T>(this);\n\n        IEnumerator IEnumerable.GetEnumerator() => new FixedBufferEnumerator<T>(this);\n\n        #region Disposer\n        void IDisposable.Dispose()\n        {\n            if (IsRetained)\n            {\n                throw new InvalidOperationException($\"FixedBuffer<{typeof(T)}[{_Length}] has outstanding references.\");\n            }\n            Dispose(true);\n            GC.SuppressFinalize(this);\n        }\n\n        private void Dispose(bool disposing)\n        {\n            Free();\n        }\n\n        #endregion\n\n        #endregion\n\n        #region Properties\n\n        #region Public\n        public bool IsInvalid => _Ptr == IntPtr.Zero || !Jem.FixedBufferIsAllocatedWith(_Ptr, _SizeInBytes, _Timestamp, AllocateThreadId, Rid);\n\n        public bool IsValid => !IsInvalid;\n\n        public int RefCount\n        {\n            get\n            {\n                ThrowIfInvalid();\n                return Jem.GetRefCount(_Ptr);\n            }\n        }\n\n        public bool IsRetained => RefCount > 0;\n\n        public bool IsReadOnly { get; }\n\n        public int Length\n        {\n            get\n            {\n                ThrowIfInvalid();\n                return _Length;\n            }\n\n        }\n\n        public ulong Size\n        {\n            get\n            {\n                ThrowIfInvalid();\n                return _SizeInBytes;\n            }\n\n        }\n\n        public unsafe ReadOnlySpan<T> Span\n        {\n            get\n            {\n                ThrowIfInvalid();\n                return new ReadOnlySpan<T>(_Ptr.ToPointer(), _Length);\n            }\n        }\n\n\n        internal IntPtr Ptr\n        {\n            get\n            {\n                ThrowIfInvalid();\n                return _Ptr;\n            }\n        }\n        #endregion\n\n        internal long Timestamp\n        {\n            get\n            {\n                return _Timestamp;\n            }\n        }\n        internal unsafe Span<T> WriteSpan\n        {\n            get\n            {\n                ThrowIfInvalid();\n                return new Span<T>(_Ptr.ToPointer(), _Length);\n            }\n        }\n\n\n        #endregion\n\n        #region Methods\n        public void Acquire() => Retain();\n\n        public bool Free()\n        {\n            if (IsInvalid)\n            {\n                return false;\n            }\n            if(IsRetained)\n            {\n                return false;\n            }\n            return Jem.FreeFixedBuffer(_Ptr);\n        }\n\n        public void Fill(T value)\n        {\n            WriteSpan.Fill(value);\n        }\n\n        public void CopyTo(T[] array)\n        {\n            WriteSpan.CopyTo(new Span<T>(array));\n        }\n\n        public T[] CopyToArray()\n        {\n            T[] array = new T[Length];\n            WriteSpan.CopyTo(new Span<T>(array));\n            return array;\n        }\n\n        public T[] CopyToArray(T[] array)\n        {\n            if (_Length != array.Length)\n            {\n                throw new ArgumentException($\"Array length {array.Length} is not the same as length {_Length} of {Name}.\");\n            }\n            else\n            {\n                Span.CopyTo(new Span<T>(array));\n                return array;\n            }\n        }\n\n        public T[] CopyToArrayAndFree()\n        {\n            T[] array = CopyToArray();\n            Free();\n            return array;\n        }\n\n        public bool EqualTo(T[] array)\n        {\n            ThrowIfInvalid();\n            if (_Length != array.Length)\n            {\n                return false;\n            }\n            else\n            {\n                ReadOnlySpan<T> span = new ReadOnlySpan<T>(array);\n                bool ret = this.Span.SequenceEqual(span);\n                return ret;\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe ReadOnlySpan<T> AcquireSpan()\n        {\n            Acquire();\n            return new ReadOnlySpan<T>((void*) _Ptr, (int)Length);\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe ReadOnlySpan<C> AcquireSpan<C>() where C : struct, IEquatable<T>, IComparable<T>, IConvertible\n        {\n            int size = checked((int)(Size / (ulong)JemUtil.SizeOfStruct<C>()));\n            if (size == 0)\n            {\n                throw new ArgumentException($\"Type {typeof(T).Name} is too small to be reinterpreted as {typeof(C).Name}.\");\n            }\n            else\n            {\n                Acquire();\n                return new ReadOnlySpan<C>((void*)_Ptr, size);\n            }\n        }\n\n\n        public ReadOnlySpan<T> Slice(int start, int length)\n        {\n            return Span.Slice(start, length);\n        }\n\n        public unsafe void * PtrTo(int index)\n        {\n            return BufferHelpers.Add<T>(_Ptr, index).ToPointer();\n        }\n\n        public Vector<T> AcquireAsSingleVector()\n        {\n            if (this._Length != Vector<T>.Count)\n            {\n                throw new InvalidOperationException($\"The length of the array must be {Vector<T>.Count} elements to create a vector of type {JemUtil.CLRType<T>().Name}.\");\n            }\n            ReadOnlySpan<T> span = AcquireSpan();\n            ReadOnlySpan<Vector<T>> vector = span.NonPortableCast<T, Vector<T>>();\n            return vector[0];\n        }\n        \n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe ReadOnlySpan<Vector<T>> AcquireVectorSpan()\n        {\n            ThrowIfNotVectorizable();\n            ThrowIfInvalid();\n            return new ReadOnlySpan<Vector<T>>(_Ptr.ToPointer(), _Length / JemUtil.VectorLength<T>());\n        }\n        \n        public unsafe Span<T> AcquireWriteSpan()\n        {\n            Acquire();\n            return new Span<T>((void*)_Ptr, _Length);\n        }\n        \n        public unsafe Span<Vector<T>> AcquireVectorWriteSpan()\n        {\n            ThrowIfNotVectorizable();\n            Acquire();\n            return new Span<Vector<T>>(_Ptr.ToPointer(), _Length / JemUtil.VectorLength<T>());\n        }\n        \n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        internal unsafe ref T Read(int index)\n        {\n            ref T ret = ref Unsafe.Add(ref Unsafe.AsRef<T>(_Ptr.ToPointer()), index);\n            return ref ret;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe ref C Read<C>(int index) where C : struct\n        {\n            //ref C ret = ref Unsafe.aAdd(ref Unsafe.AsRef<C>(_Ptr.ToPointer()), index);\n            //return re\n            return ref Unsafe.AsRef<C>(PtrTo(index));\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe void Write<C>(int index, ref C value) where C : struct\n        {\n            Unsafe.Write(PtrTo(index), value);\n        }\n\n        internal unsafe Span<Vector<T>> WriteVectorSpan\n        {\n            get\n            {\n                ThrowIfInvalid();\n                return new Span<Vector<T>>(_Ptr.ToPointer(), _Length / JemUtil.VectorLength<T>());\n            }\n        }\n\n        internal void ThrowIfInvalid()\n        {\n            if (IsInvalid)\n            {\n                throw new InvalidOperationException($\"{nameof(FixedBuffer<T>)}({this._Length}) is invalid.\");\n            }\n        }\n\n        internal void ThrowIfIndexOutOfRange(int index)\n        { \n            if (index >= _Length)\n            {\n                throw new IndexOutOfRangeException($\"Index {index} is greater than the maximum index of the buffer {_Length - 1}.\");\n            }\n            else if (index < 0)\n            {\n                throw new IndexOutOfRangeException($\"Index {index} is less than zero.\");\n            }\n        }\n\n        internal void ThrowIfRefCountNonZero()\n        {\n            if (0 > 0)\n            {\n                throw new InvalidOperationException($\"{nameof(FixedBuffer<T>)}({this._Length}) has RefCount .\");\n            }\n        }\n\n        internal void ThrowIfReadOnly()\n        {\n            if (IsReadOnly)\n            {\n                throw new InvalidOperationException($\"{nameof(FixedBuffer<T>)}({this._Length}) is read-only.\");\n            }\n        }\n\n        internal void ThrowIfTypeNotPrimitive()\n        {\n            if (!typeof(T).IsPrimitive)\n            {\n                throw new ArgumentException($\"The type {typeof(T).Name} is not a primitive type.\");\n            }\n        }\n\n        internal void ThrowIfNotVectorizable()\n        {\n            if (!JemUtil.IsNumericType<T>() || _Length == 0 || (_Length % JemUtil.VectorLength<T>() != 0))\n            {\n                throw new InvalidOperationException(\"Buffer is not vectorizable.\");\n            }\n        }\n\n        \n\n        internal string Name => $\"{nameof(FixedBuffer<T>)}({this._Length})\";\n\n        private string DebuggerDisplay() => string.Format(\"{{{0}[{1}]}}\", typeof(T).Name, Length);\n\n        #region Arithmetic\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public void VectorFill(T value)\n        {\n            ThrowIfInvalid();\n            int c = JemUtil.VectorLength<T>();\n            int i;\n            Vector<T> fill = new Vector<T>(value);\n            Span<Vector<T>> s = WriteVectorSpan;\n            for (i = 0; i < s.Length; i ++)\n            {\n                s[i] = fill;\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public void VectorMultiply(T value)\n        {\n            ThrowIfInvalid();\n            int c = JemUtil.VectorLength<T>();\n            int i;\n            T r;\n            Vector<T> mul = new Vector<T>(value);\n            for (i = 0; i < _Length - c; i += c)\n            {\n                Vector<T> f = Read<Vector<T>>(i);\n                Vector<T> result = f * mul;\n                Write(i, ref result);\n            }\n            \n            for (; i < _Length; ++i)\n            {\n                r = GM<T>.Multiply(this[i], value);\n                Write(i, ref r);\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public void VectorSqrt()\n        {\n            ThrowIfInvalid();\n            int c = JemUtil.VectorLength<T>();\n            int i;\n            T r;\n            for (i = 0; i < _Length - c; i += c)\n            {\n                Vector<T> f = Read<Vector<T>>(i);\n                Vector<T> result = Vector.SquareRoot(f);\n                Write(i, ref result);\n            }\n\n            for (; i < _Length; ++i)\n            {\n                r = JemUtil.ValToGenericStruct<double, T>(GM<T>.Sqrt(this[i]));\n                Write(i, ref r);\n            }\n        }\n\n        public unsafe bool VectorLessThanAll(T value, out int index)\n        {\n            ThrowIfInvalid();\n            index = -1;\n            bool r = true;\n            int c = Vector<T>.Count;\n            int i;\n            Vector<T> v = new Vector<T>(value);\n            Vector<T> O = Vector<T>.One;\n            for (i = 0; i <= _Length - c; i+= c)\n            {\n                Vector<T> s = Unsafe.Read<Vector<T>>(BufferHelpers.Add<T>(_Ptr, i).ToPointer());\n                Vector<T> vcmp = Vector.LessThan(s, v);\n                if (vcmp == O)\n                {\n                    continue;\n                }\n                else\n                {\n                    r = false;\n                    for (int j = 0; j < c; j++)\n                    {\n                        if (vcmp[j].Equals(default))                      \n                        {\n                            index = i + j;\n                            return r;\n                        }\n                    }\n                    return r;\n                }\n            }\n\n            for (; i < _Length; ++i)\n            {\n                if (Read(i).CompareTo(value) >= 0)\n                {\n                    r = false;\n                    index = i;\n                    return r;\n                }\n            }\n            return r;\n        }\n            \n        #endregion\n\n        #endregion\n\n        #region Operators\n        public ref T this[int index]\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => ref this.Read(index);\n        }\n\n        public static implicit operator IntPtr (FixedBuffer<T> buffer)\n        {\n            return buffer._Ptr;\n        }\n\n       \n        #endregion\n\n        #region Fields\n        private static readonly Type ElementType = typeof(T);\n        private static readonly ulong ElementSizeInBytes = (ulong) JemUtil.SizeOfStruct<T>();\n        private static readonly int VectorWidth = Vector<T>.Count;\n        private readonly IntPtr _Ptr;\n        private readonly ulong _SizeInBytes;\n        private readonly int _Length;\n        private readonly long _Timestamp;\n        internal readonly int AllocateThreadId;\n        internal readonly int Rid;\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/FixedBufferAllocation.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace jemalloc\n{\n    public readonly struct FixedBufferAllocation : IEquatable<FixedBufferAllocation>\n    {\n        #region Constructor\n        public FixedBufferAllocation(IntPtr ptr, ulong size, long timestamp, int tid, int rid)\n        {\n            this.Ptr = ptr;\n            this.Size = size;\n            this.TimeStamp = timestamp;\n            this.ThreadId = tid;\n            this.Rid = rid;\n            HashCode = JemUtil.CombineHashCodes(this.Ptr.GetHashCode(), this.Size.GetHashCode(), this.TimeStamp.GetHashCode(), this.ThreadId.GetHashCode(), this.Rid.GetHashCode());\n        }\n        #endregion\n\n        public override int GetHashCode()\n        {\n            return this.HashCode;\n        }\n\n        public override bool Equals(object obj)\n        {\n            if (obj is FixedBufferAllocation)\n            {\n                FixedBufferAllocation o = (FixedBufferAllocation)obj;\n                return this.HashCode == o.HashCode;\n            }\n            else\n            {\n                return false;\n            }\n        }\n\n        bool IEquatable<FixedBufferAllocation>.Equals(FixedBufferAllocation other)\n        {\n            return this.HashCode == other.HashCode;\n        }\n\n        public readonly IntPtr Ptr;\n        public readonly ulong Size;\n        public readonly long TimeStamp;\n        public readonly int ThreadId;\n        public readonly int Rid;\n        public readonly int HashCode;\n\n    }\n    public class FixedBufferComparator : IEqualityComparer<FixedBufferAllocation>\n    {\n        public bool Equals(FixedBufferAllocation l, FixedBufferAllocation r)\n        {\n            return l.HashCode == r.HashCode;\n        }\n\n        public int GetHashCode(FixedBufferAllocation a)\n        {\n            return a.HashCode;\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/FixedBufferEnumerator.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Text;\n\nnamespace jemalloc\n{\n    public class FixedBufferEnumerator<T> : IEnumerator, IEnumerator<T> where T : struct, IEquatable<T>, IComparable<T>, IConvertible\n    {\n        /// <summary>The SafeBuffer being enumerated.</summary>\n        private readonly FixedBuffer<T> _buffer;\n        /// <summary>The next index to yield.</summary>\n        private int _index;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        internal FixedBufferEnumerator(FixedBuffer<T> buffer)\n        {\n            _buffer = buffer;\n            _buffer.Acquire();\n            _index = -1;\n        }\n\n        /// <summary>Advances the enumerator to the next element of the buffer.</summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool MoveNext()\n        {\n            int index = _index + 1;\n            if (index < _buffer.Length)\n            {\n                _index = index;\n                return true;\n            }\n            else\n            {\n                return false;\n            }\n\n        }\n\n        public void Reset()\n        {\n            _index = -1;\n        }\n\n        /// <summary>Gets the element at the current position of the enumerator.</summary>\n        object IEnumerator.Current\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => _buffer[_index];\n        }\n\n        public T Current\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => _buffer[_index];\n        }\n\n        void IDisposable.Dispose()\n        {\n            _buffer.Release();\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/GDI.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace jemalloc\n{\n    public unsafe static partial class Win32\n    {\n        public enum BitmapCompressionMode\n        {\n            BI_RGB = 0x0000,\n            BI_RLE8 = 0x0001,\n            BI_RLE4 = 0x0002,\n            BI_BITFIELDS = 0x0003,\n            BI_JPEG = 0x0004,\n            BI_PNG = 0x0005,\n            BI_CMYK = 0x000B,\n            BI_CMYKRLE8 = 0x000C,\n            BI_CMYKRLE4 = 0x000D\n        }\n        \n        [StructLayout(LayoutKind.Sequential)]\n        public struct BITMAPINFOHEADER\n        {\n            public uint biSize;\n            public int biWidth;\n            public int biHeight;\n            public ushort biPlanes;\n            public ushort biBitCount;\n            public BitmapCompressionMode biCompression;\n            public uint biSizeImage;\n            public int biXPelsPerMeter;\n            public int biYPelsPerMeter;\n            public uint biClrUsed;\n            public uint biClrImportant;\n\n            public void Init()\n            {\n                biSize = (uint)Marshal.SizeOf(this);\n            }\n        }\n\n        [StructLayout(LayoutKind.Sequential)]\n        public struct RGBQUAD\n        {\n            public byte rgbBlue;\n            public byte rgbGreen;\n            public byte rgbRed;\n            public byte rgbReserved;\n        }\n\n        public struct BITMAPINFO\n        {\n            BITMAPINFOHEADER bmiHeader;\n            RGBQUAD[] bmiColors;\n        }\n        \n\n\n\n\n        [DllImport(\"gdi32.dll\")]\n        static extern IntPtr CreateDIBitmap(IntPtr hdc, [In] ref BITMAPINFOHEADER lpbmih, uint fdwInit, byte[] lpbInit, [In] ref BITMAPINFO lpbmi, uint fuUsage);\n\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/GenericMath.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace jemalloc\n{\n    public static class GM<TData> where TData : struct, IEquatable<TData>, IComparable<TData>, IConvertible\n    {\n        #region Constructor\n        static GM()\n        {\n            if (!JemUtil.IsNumericType<TData>())\n            {\n                throw new InvalidOperationException($\"Type {typeof(TData).Name} is not a numeric type.\");\n            }\n\n        }\n        #endregion\n\n        #region Properties\n        public static Random Rng { get; } = new Random();\n        #endregion\n\n        #region Methods\n        public static TData Const<TValue>(TValue v) where TValue : struct, IEquatable<TValue>, IComparable<TValue>, IConvertible\n        {\n            return (TData) Convert.ChangeType(v, typeof(TData));\n        }\n\n        public static TData Multiply(TData l, TData r) \n        {\n            Tuple<TData, TData> value = new Tuple<TData, TData>(l, r);\n            switch (value)\n            {\n                case Tuple<Byte, Byte> v:\n                    return (TData)Convert.ChangeType(checked((byte)(v.Item1 * v.Item2)), typeof(TData));\n\n                case Tuple<SByte, SByte> v:\n                    return (TData)Convert.ChangeType(checked((SByte)(v.Item1 * v.Item2)), typeof(TData));\n\n                case Tuple<UInt16, UInt16> v:\n                    return (TData)Convert.ChangeType((checked((UInt16)(v.Item1 * v.Item2))), typeof(TData));\n\n                case Tuple<Int16, Int16> v:\n                    return (TData)Convert.ChangeType(checked((Int16)(v.Item1 * v.Item2)), typeof(TData));\n\n                case Tuple<UInt32, UInt32> v:\n                    return (TData)Convert.ChangeType(checked(v.Item1 * v.Item2), typeof(TData));\n\n                case Tuple<Int32, Int32> v:\n                    return (TData)Convert.ChangeType(checked(v.Item1 * v.Item2), typeof(TData));\n\n                case Tuple<UInt64, UInt64> v:\n                    return (TData)Convert.ChangeType(checked(v.Item1 * v.Item2), typeof(TData));\n\n                case Tuple<Int64, Int64> v:\n                    return (TData)Convert.ChangeType(checked(v.Item1 * v.Item2), typeof(TData));\n\n                case Tuple<Single, Single> v:\n                    return (TData)Convert.ChangeType(checked(v.Item1 * v.Item2), typeof(TData));\n\n                case Tuple<Double, Double> v:\n                    return (TData)Convert.ChangeType(checked(v.Item1 * v.Item2), typeof(TData));\n\n                case Tuple<bool, bool> v:\n                    throw new ArgumentException($\"Cannot multiply 2 bools.\");\n\n                default:\n                    throw new Exception($\"Unsupported math type: {typeof(TData).Name}\");\n            }\n        }\n        \n        public static double Sqrt(TData n)\n        {\n            switch (n)\n            {\n                case SByte v:\n                    return checked(Math.Sqrt(v));\n                case Byte v:\n                    return checked(Math.Sqrt(v));\n                case Int32 v:\n                    return checked(Math.Sqrt(v));\n                case UInt32 v:\n                    return checked(Math.Sqrt(v));\n                case Int16 v:\n                    return checked(Math.Sqrt(v));\n                case UInt16 v:\n                    return checked(Math.Sqrt(v));\n                case Int64 v:\n                    return checked(Math.Sqrt(v));\n                case UInt64 v:\n                    return checked(Math.Sqrt(v));\n                case Single v:\n                    return checked(Math.Sqrt(v));\n                case Double v:\n                    return checked(Math.Sqrt(v));\n                case bool v:\n                    throw new ArgumentException($\"Cannot get the square root of a bool.\");\n                default:\n                    throw new ArithmeticException();\n            }\n        }\n\n       \n        public static double F(Func<double, double> f, TData n)\n        {\n            switch (n)\n            {\n                case SByte v:\n                    return checked(f(v));\n                case Byte v:\n                    return checked(f(v));\n                case Int32 v:\n                    return checked(f(v));\n                case UInt32 v:\n                    return checked(f(v));\n                case Int16 v:\n                    return checked(f(v));\n                case UInt16 v:\n                    return checked(f(v));\n                case Int64 v:\n                    return checked(f(v));\n                case UInt64 v:\n                    return checked(f(v));\n                case Single v:\n                    return checked(f(v));\n                case Double v:\n                    return checked(f(v));\n                case Boolean v:\n                    throw new ArgumentException($\"Cannot apply math functions to a bool.\");\n                default:\n                    throw new ArithmeticException();\n            }\n        }\n\n        public static TData Random()\n        {\n            TData e = default;\n            switch (e)\n            {\n                case SByte v:\n                    return Const(checked((sbyte)Rng.Next(0, SByte.MaxValue)));\n                case Byte v:\n                    return Const(checked((byte)Rng.Next(0, Byte.MaxValue)));\n                case Int32 v:\n                    return Const(checked((int)Rng.Next(0, Int32.MaxValue)));\n                case UInt32 v:\n                    return Const(checked((uint)Rng.Next(0, Int32.MaxValue)));\n                case Int16 v:\n                    return Const(checked((short)Rng.Next(0, Int16.MaxValue)));\n                case UInt16 v:\n                    return Const(checked((ushort)Rng.Next(0, UInt16.MaxValue)));\n                case Int64 v:\n                    return Const(checked((long)(Rng.NextDouble() * Int64.MaxValue)));\n                case UInt64 v:\n                    return Const(checked((ulong)(Rng.NextDouble() * UInt64.MaxValue)));\n                case Single v:\n                    return Const(checked(((Single)(Rng.NextDouble() * Int64.MaxValue))));\n                case Double v:\n                    return Const(checked((((double)Rng.NextDouble() * Int64.MaxValue))));\n                case Boolean v:\n                    return Const(Convert.ToBoolean(Rng.Next(0, 1)));\n\n                default:\n                    throw new ArithmeticException();\n            }\n        }\n\n        public static TData Random(double max)\n        {\n            return Const(checked((double)Rng.NextDouble() * max));\n        }\n\n        public static (TData, TData) RandomMultiplyFactorAndValue()\n        {\n            TData e = default;\n            TData max;\n            int factor = Rng.Next(0, 4);\n            switch (e)\n            {\n                case SByte v:\n                    max = Random((sbyte)(sbyte.MaxValue / 4));\n                    break;\n                case Byte v:\n                    max = Random((byte)(byte.MaxValue / (byte) 4));\n                    break;\n                case Int16 v:\n                    max = Random((short)(short.MaxValue / (short)4));\n                    break;\n                case UInt16 v:\n                    max = Random((ushort)(ushort.MaxValue / (ushort)4));\n                    break;\n                case Int32 v:\n                    max = Random((int)(int.MaxValue / 4));\n                    break;\n                case UInt32 v:\n                    max = Random(uint.MaxValue / 4u);\n                    break;\n                 case Int64 v:\n                    max = Random((long)(long.MaxValue / 4));\n                    break;\n                case UInt64 v:\n                    max = Random(ulong.MaxValue / 4u);\n                    break;\n                case Double v:\n                    max = Random((double)(long.MaxValue / 4));\n                    break;\n                case Single v:\n                    max = Random((Single)(long.MaxValue / 4));\n                    break;\n                default:\n                    throw new ArgumentException($\"Cannot multiply type {nameof(TData)}.\");\n            }\n            return (Const(factor), Const(max));\n\n        }\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/HugeArray.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace jemalloc\n{\n    public class HugeArray<T> : HugeBuffer<T> where T : struct, IEquatable<T>\n    {\n        public HugeArray(ulong length, params T[] values) : base(length, values) { }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/HugeBuffer.cs",
    "content": "﻿using System;\nusing System.Buffers;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.ConstrainedExecution;\nusing System.Threading;\n\nnamespace jemalloc\n{\n    public abstract class HugeBuffer<T> : SafeHandle, IRetainable, IDisposable, IEquatable<HugeBuffer<T>>, IEnumerable<T> where T : struct, IEquatable<T>\n    {\n        #region Constructors\n        protected HugeBuffer(ulong length, params T[] values) : base(IntPtr.Zero, true)\n        {\n            ulong l = (ulong)values.Length;\n            if (BufferHelpers.IsReferenceOrContainsReferences<T>())\n            {\n                throw new ArgumentException(\"Only structures without reference fields can be used with this class.\");\n            }\n            if (l > length)\n            {\n                throw new ArgumentException(\"The length of the list of values must be smaller or equal to the length of the buffer\");\n            }\n            SizeInBytes = NotAllocated;\n            base.SetHandle(Allocate(length));\n            if (IsAllocated)\n            {\n                CopyFrom(values);\n            }\n        }\n        #endregion\n\n        #region Overriden members\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        protected override bool ReleaseHandle()\n        {\n            bool r = Jem.Free(handle);\n            if (!r)\n            {\n                return false;\n            }\n            else\n            {\n                handle = IntPtr.Zero;\n                unsafe\n                {\n                    voidPtr = (void*)0;\n                }\n                Length = 0;\n                SizeInBytes = 0;\n                return true;\n            }\n        }\n\n        public override bool IsInvalid => handle == IntPtr.Zero;\n\n        #region Disposer\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing)\n            {\n                ThrowIfNotAllocatedOrInvalid();\n                ThrowIfRetained();\n                ReleaseHandle();\n            }\n            base.Dispose(disposing);\n        }\n\n        #endregion\n  \n        #endregion\n\n        #region Implemented members\n\n        public void Retain() => Acquire();\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        public bool Release()\n        {\n\n            if (IsNotAllocated || IsInvalid)\n            {\n                return false;\n            }\n            else\n            {\n                Jem.DecrementRefCount(handle);\n                DangerousRelease();\n                return true;\n            }\n        }\n\n        public bool Equals(HugeBuffer<T> other)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            return this.handle == other.handle && this.Length == other.Length;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public IEnumerator<T> GetEnumerator() => new HugeBufferEnumerator<T>(this);\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        IEnumerator IEnumerable.GetEnumerator() => new HugeBufferEnumerator<T>(this);\n\n        #endregion\n\n        #region Properties\n        public ulong Length { get; protected set; }\n\n        public ulong SizeInBytes { get; protected set; }\n\n        public bool IsNotAllocated => SizeInBytes == NotAllocated;\n\n        public bool IsAllocated => !IsNotAllocated;\n\n        public bool IsValid => !IsInvalid;\n\n        public bool IsRetained => _RefCount > 0;\n\n        public bool IsVectorizable { get; protected set; }\n\n        protected int _RefCount => Jem.GetRefCount(handle);\n        #endregion\n\n        #region Methods\n\n        #region Memory management\n        protected unsafe virtual IntPtr Allocate(ulong length)\n        {\n            if (length < 0)\n                throw new ArgumentOutOfRangeException(\"length\");\n            Contract.EndContractBlock();\n            ulong s = checked(length * ElementSizeInBytes);\n            handle = Jem.Calloc(length, ElementSizeInBytes);\n            if (handle != IntPtr.Zero)\n            {\n                voidPtr = handle.ToPointer();\n                Length = length;\n                SizeInBytes = s;\n                InitSegments();\n                InitVectors();\n            }\n            return handle;\n        }\n\n        protected unsafe void InitSegments()\n        {\n            int n = (int)((Length - 1) / Int32.MaxValue) + 1;\n            segments = new IntPtr[n];\n            segments2 = new Tuple<IntPtr, int>[segments.Length];\n            segments[0] = handle;\n            segments2[0] = new Tuple<IntPtr, int>(handle, n == 1 ? (int)Length : Int32.MaxValue);\n            for (int i = 1; i < n; i++)\n            {\n                segments[i] = BufferHelpers.Add<T>(segments[i - 1], Int32.MaxValue);\n                if (i < n - 1)\n                {\n                    segments2[i] = new Tuple<IntPtr, int>(segments[i], Int32.MaxValue);\n                }\n            }\n            segments2[n - 1] = new Tuple<IntPtr, int>(segments[n - 1], (int)(Length - (ulong)((n - 1) * Int32.MaxValue)));\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        protected unsafe void InitVectors()\n        {\n            if (IsNumeric && Length % (ulong)VectorLength == 0 && SIMD)\n            {\n\n                IsVectorizable = true;\n            }\n            else\n            {\n                IsVectorizable = false;\n            }\n        }\n\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        protected int _GetSegmentIndex(ulong index)\n        {\n            return (int)(index / Int32.MaxValue);\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        protected unsafe void _GetSegment(ulong index, out void* ptr, out int offset)\n        {\n            int s = _GetSegmentIndex(index);\n            int l = segments.Length;\n            ptr = segments[s].ToPointer();\n            offset = (int)(index - ((ulong)(s) * Int32.MaxValue));\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        protected unsafe Span<T> _GetSegmentSpan(ulong index)\n        {\n            int i = _GetSegmentIndex(index);\n            return new Span<T>(segments2[i].Item1.ToPointer(), segments2[i].Item2);\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        protected unsafe Span<Vector<T>> _GetSegmentVectorSpan(ulong index)\n        {\n            int i = _GetSegmentIndex(index);\n            return new Span<Vector<T>>(segments2[i].Item1.ToPointer(), segments2[i].Item2 / VectorLength + 1);\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        protected unsafe ref T _Read(ulong index)\n        {\n\n            // return (T*) (seg_ptr + byteOffset);\n\n            _GetSegment(index, out void* ptr, out int offset);\n            ref T ret = ref Unsafe.Add(ref Unsafe.AsRef<T>(ptr), offset);\n\n            return ref ret;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        protected unsafe T _Write(ulong index, T value)\n        {\n\n            // return (T*) (seg_ptr + byteOffset);\n            _GetSegment(index, out void* ptr, out int offset);\n            ref T v = ref Unsafe.AsRef<T>(BufferHelpers.Add<T>(new IntPtr(ptr), offset).ToPointer());\n            v = value;\n            return value;\n        }\n\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]\n        public bool Acquire()\n        {\n            if (IsNotAllocated || IsInvalid)\n                return false;\n            bool success = false;\n            DangerousAddRef(ref success);\n            if (success)\n            {\n                Jem.IncrementRefCount(handle);\n            }\n            return success;\n        }\n\n        public bool Release(int n)\n        {\n            bool r = false;\n            for (int i = 0; i < n; i++)\n            {\n                r = Release();\n                if (r)\n                {\n                    continue;\n                }\n                else\n                {\n                    return r;\n                }\n            }\n            return r;\n        }\n        #endregion\n\n        #region Values\n\n        public bool EqualTo(T[] array)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            if (this.Length != (ulong)array.Length)\n            {\n                return false;\n            }\n            return _GetSegmentSpan(0).SequenceEqual(new ReadOnlySpan<T>(array));\n        }\n\n        public unsafe void Fill(T value)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            for (int i = 0; i < segments.Length; i++)\n            {\n                Span<T> s = new Span<T>(segments2[i].Item1.ToPointer(), segments2[i].Item2);\n                s.Fill(value);\n            }\n        }\n\n        public void CopyFrom(T[] array)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            new Span<T>(array).CopyTo(_GetSegmentSpan(0));\n        }\n\n        public T[] CopyToArray()\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            if (this.Length > Int32.MaxValue)\n            {\n                throw new ArgumentOutOfRangeException(\"This length of this array exceeds the max length of a managed array.\");\n            }\n            T[] a = new T[this.Length];\n            _GetSegmentSpan(0).CopyTo(new Span<T>(a));\n            return a;\n        }\n\n        public unsafe Span<C> GetSpan<C>(ulong index = 0, int length = 1) where C : struct, IEquatable<C>\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            ThrowIfIndexOutOfRange(index);\n            ulong s = (index * (ulong) ElementSizeInBytes + (ulong) length * (ulong) Unsafe.SizeOf<C>());\n            if (s > SizeInBytes)\n            {\n                BufferSizeIsOutOfRange(s);\n            }\n            _GetSegment(index, out void* ptr, out int offset);\n            void* p = BufferHelpers.Add<T>(new IntPtr(ptr), offset).ToPointer();\n            return new Span<C>(p, length);\n        }\n\n        public unsafe Span<T> Slice(ulong start, ulong end)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            ThrowIfIndexOutOfRange(start);\n            ThrowIfIndexOutOfRange(end);\n            if (start >= end)\n            {\n                throw new ArgumentOutOfRangeException($\"The end {end} of the slice must be greater than the start {start}.\");\n            }\n            else if (end - start > Int32.MaxValue)\n            {\n                throw new ArgumentOutOfRangeException($\"The size of the slice must be less than or equal to {Int32.MaxValue}.\");\n            }\n            _GetSegment(end, out void* ptr, out int offset);\n            void* p = BufferHelpers.Add<T>(new IntPtr(ptr), offset).ToPointer();\n            return new Span<T>(p, (int) (end - start));\n        }\n\n\n        public unsafe Vector<T> GetAsSingleVector()\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            if (this.Length != (ulong) VectorLength)\n            {\n                throw new InvalidOperationException($\"The length of the array must be {Vector<T>.Count} elements to create a vector of type {CLRType.Name}.\");\n            }\n            return Unsafe.Read<Vector<T>>(handle.ToPointer());\n        }\n\n        public unsafe Span<Vector<T>> GetSliceSegmentAsVectorSpan(ulong index)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            if ((Length - index) < (ulong) VectorLength)\n            {\n                ThrowIfIndexOutOfRange(index);\n            }\n            T v = this[index];\n            int i = _GetSegmentIndex(index);\n            if (segments2[i].Item2 % VectorLength != 0)\n            {\n                BufferIsNotVectorisable();\n            }\n            return new Span<Vector<T>>(segments2[i].Item1.ToPointer(), segments2[i].Item2 / VectorLength + 1);\n        }\n\n        public unsafe Vector<T> GetSliceAsSingleVector(ulong index)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            ThrowIfIndexOutOfRange(index);\n            if ((Length - index) < (ulong) VectorLength)\n            {\n                BufferIsNotVectorisable();\n            }\n            int i = _GetSegmentIndex(index);\n            _GetSegment(index, out void* ptr, out int offset);\n            IntPtr start = BufferHelpers.Add<T>(segments2[i].Item1, offset);\n            return Unsafe.Read<Vector<T>>(start.ToPointer());\n        }\n        #endregion\n\n        #region Vector\n        /*\n        public unsafe void VectorMultiply(T value)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            ThrowIfNotNumeric();\n            Vector<T> mul = new Vector<T>(value);\n            for (int h = 0; h < segments2.Length; h++)\n            {\n                int i = 0;\n                for (; i < segments2[h].Item2 - VectorLength; i++ )\n                {\n                    Vector<T> v = Unsafe.Read<Vector<T>>(BufferHelpers.Add<T>(segments2[h].Item1, i).ToPointer());\n                    v = v * mul;\n                }\n                f\n            }\n        }*/\n        #endregion\n\n        #region Helpers\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfCannotAcquire()\n        {\n            if (!Acquire())\n            {\n                throw new InvalidOperationException(\"Could not acquire handle.\");\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfIndexOutOfRange(ulong index)\n        {\n            if (index >= Length)\n            {\n                BufferIndexIsOutOfRange(index);\n            }\n         }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfNotAllocatedOrInvalid()\n        {\n            if (IsNotAllocated)\n            {\n                BufferIsNotAllocated();\n            }\n            else if (IsInvalid)\n            {\n                HandleIsInvalid();\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfRetained()\n        {\n            if (IsRetained)\n            {\n                throw new InvalidOperationException($\"SafeBuffer<{typeof(T)}[{Length}] has outstanding references.\");\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfNotAllocated()\n        {\n            if (IsNotAllocated)\n            {\n                BufferIsNotAllocated();\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfNotVectorisable()\n        {\n            if (!IsVectorizable)\n            {\n                BufferIsNotVectorisable();\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfNotNumeric()\n        {\n            if (!IsNumeric)\n            {\n                BufferIsNotNumeric();\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static InvalidOperationException HandleIsInvalid()\n        {\n            Contract.Assert(false, \"The handle is invalid.\");\n            return new InvalidOperationException(\"The handle is invalid.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static InvalidOperationException BufferIsNotAllocated()\n        {\n            Contract.Assert(false, \"Unallocated safe buffer used.\");\n            return new InvalidOperationException(\"Unallocated safe buffer used.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static InvalidOperationException BufferIsNotVectorisable()\n        {\n            Contract.Assert(false, \"Buffer is not vectorisable.\");\n            return new InvalidOperationException(\"Buffer is not vectorisable.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static InvalidOperationException BufferIsNotNumeric()\n        {\n            Contract.Assert(false, \"Buffer is not numeric.\");\n            return new InvalidOperationException(\"Buffer is not numeric.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void BufferIndexIsOutOfRange(ulong index)\n        {\n            Contract.Assert(false, $\"Index {index} into buffer is out of range.\");\n            throw new IndexOutOfRangeException($\"Index {index} into buffer is out of range.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void BufferSizeIsOutOfRange(ulong index)\n        {\n            Contract.Assert(false, $\"Size {index} exceeds the size of the buffer.\");\n            throw new IndexOutOfRangeException($\"Size {index} exceeds the size of the buffer.\");\n        }\n        #endregion\n\n        #endregion\n\n        #region Operators\n        public ref T this[ulong index]\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => ref _Read(index);\n            \n        }\n        #endregion\n\n        #region Fields\n        protected static readonly Type CLRType = typeof(T);\n        protected static readonly T Element = default;\n        protected static readonly uint ElementSizeInBytes = (uint) JemUtil.SizeOfStruct<T>();\n        protected static readonly UInt64 NotAllocated = UInt64.MaxValue;\n        protected static readonly bool IsNumeric = JemUtil.IsNumericType<T>();\n        protected static readonly int VectorLength = Vector<T>.Count;\n        protected static bool SIMD = Vector.IsHardwareAccelerated;\n        protected internal unsafe void* voidPtr;\n        protected unsafe IntPtr[] segments;\n        protected unsafe Tuple<IntPtr, int>[] segments2;\n        //Debugger Display = {T[length]}\n        private string DebuggerDisplay => string.Format(\"{{{0}[{1}]}}\", typeof(T).Name, Length);\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/HugeBufferEnumerator.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Text;\n\nnamespace jemalloc\n{\n    /// <summary>Enumerates the elements of a <see cref=\"HugeBuffer{T}\"/>.</summary>\n    public class HugeBufferEnumerator<T> : IEnumerator, IEnumerator<T> where T : struct, IEquatable<T>\n    {\n        /// <summary>The span being enumerated.</summary>\n        private readonly HugeBuffer<T> _buffer;\n        /// <summary>The next index to yield.</summary>\n        private ulong _index;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        internal HugeBufferEnumerator(HugeBuffer<T> buffer)\n        {\n            _buffer = buffer;\n            _buffer.Acquire();\n            _index = UInt64.MaxValue;\n        }\n\n        /// <summary>Advances the enumerator to the next element of the buffer.</summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool MoveNext()\n        {\n            if (_index == UInt64.MaxValue)\n            {\n                _index = 0;\n                return true;\n            }\n            else\n            {\n                ulong index = _index + 1;\n                if (index < _buffer.Length)\n                {\n                    _index = index;\n                    return true;\n                }\n                else\n                {\n                    return false;\n                }\n            }\n        }\n\n        public void Reset()\n        {\n            _index = UInt64.MaxValue;\n        }\n\n        /// <summary>Gets the element at the current position of the enumerator.</summary>\n        object IEnumerator.Current\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => _buffer[_index];\n        }\n\n        public T Current\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => _buffer[_index];\n        }\n\n        void IDisposable.Dispose()\n        {\n            _buffer.Release();\n        }\n    }\n\n}\n"
  },
  {
    "path": "jemalloc.Api/IBufferAllocation.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace jemalloc\n{\n    public interface IBufferAllocation\n    {\n        IntPtr Ptr { get; }\n        ulong Size { get; }\n        long TimeStamp { get; }\n        int ThreadId { get; }\n        int HashCode { get; }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/JemApi.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Concurrent;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.ConstrainedExecution;\nusing System.Security;\nusing System.Text;\nusing System.Threading;\n\nnamespace jemalloc\n{\n    #region Types and Enums\n    public class CallerInformation\n    {\n        public string Name;\n        public string File;\n        public int LineNumber;\n\n        public CallerInformation(string name, string file, int line_number)\n        {\n            this.Name = name;\n            this.File = file;\n            this.LineNumber = line_number;\n        }\n\n        public override string ToString() => Jem.GetCallerDetails(this);\n        \n    }\n\n    internal enum ERRNO\n    {\n        ENONE = 0,\n        EPERM = 1,\n        ENOENT = 2,\n        ESRCH = 3,\n        EINTR = 4,\n        EIO = 5,\n        ENXIO = 6,\n        E2BIG = 7,\n        ENOEXEC = 8,\n        EBADF = 9,\n        ECHILD = 10,\n        EAGAIN = 11,\n        ENOMEM = 12,\n        EACCES = 13,\n        EFAULT = 14,\n        EBUSY = 16,\n        EEXIST = 17,\n        EXDEV = 18,\n        ENODEV = 19,\n        ENOTDIR = 20,\n        EISDIR = 21,\n        ENFILE = 23,\n        EMFILE = 24,\n        ENOTTY = 25,\n        EFBIG = 27,\n        ENOSPC = 28,\n        ESPIPE = 29,\n        EROFS = 30,\n        EMLINK = 31,\n        EPIPE = 32,\n        EDOM = 33,\n        EDEADLK = 36,\n        ENAMETOOLONG = 38,\n        ENOLCK = 39,\n        ENOSYS = 40,\n        ENOTEMPTY = 41\n    }\n\n    [Flags]\n    public enum ALLOC_FLAGS\n    {\n        ZERO,\n        DETAILS\n    }\n    #endregion\n\n    public unsafe static partial class Jem\n    {\n        #region Constructor\n        static Jem()\n        {\n            __Internal.JeMallocMessage += messagesCallback;\n        }\n        #endregion\n\n        #region Methods\n\n        #region Low-level jemalloc API\n        public static global::System.IntPtr Malloc(ulong size, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            CallerInformation caller = new CallerInformation(memberName, fileName, lineNumber);\n            Initialized = true;\n            IntPtr __ret = __Internal.JeMalloc(size);\n            if (__ret != IntPtr.Zero)\n            {\n                allocLock.EnterWriteLock();\n                _Allocations.Add(__ret, 0);\n                allocLock.ExitWriteLock();\n                return __ret;\n            }\n            else\n            {\n                throw new OutOfMemoryException($\"Could not allocate {size} bytes for {GetCallerDetails(caller)}.\");\n            }\n        }\n\n        public static global::System.IntPtr Calloc(ulong num, ulong size, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            CallerInformation caller = new CallerInformation(memberName, fileName, lineNumber);\n            Initialized = true;\n            IntPtr __ret = __Internal.JeCalloc(num, size);\n            if (__ret != IntPtr.Zero)\n            {\n                allocLock.EnterWriteLock();\n                _Allocations.Add(__ret, 0);\n                allocLock.ExitWriteLock();\n                return __ret;\n            }\n            else\n            {\n                throw new OutOfMemoryException($\"Could not allocate {num * size} bytes for {GetCallerDetails(caller)}.\");\n            }\n        }\n\n        public static int PosixMemalign(void** memptr, ulong alignment, ulong size)\n        {\n            Initialized = true;\n            var __ret = __Internal.JePosixMemalign(memptr, alignment, size);\n            return __ret;\n        }\n\n        public static global::System.IntPtr AlignedAlloc(ulong alignment, ulong size)\n        {\n            Initialized = true;\n            var __ret = __Internal.JeAlignedAlloc(alignment, size);\n            return __ret;\n        }\n\n        public static global::System.IntPtr Realloc(global::System.IntPtr ptr, ulong size)\n        {\n            Initialized = true;\n            var __ret = __Internal.JeRealloc(ptr, size);\n            return __ret;\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        public static bool Free(global::System.IntPtr ptr, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            bool ret = false;\n            RuntimeHelpers.PrepareConstrainedRegions();\n            try\n            {\n\n            }\n            finally\n            {\n                allocLock.EnterUpgradeableReadLock();\n                ret = _Allocations.ContainsKey(ptr);\n                if (ret)\n                {\n                    allocLock.EnterWriteLock();\n                    _Allocations.Remove(ptr);\n                    __Internal.JeFree(ptr);\n                    allocLock.ExitWriteLock();\n                }\n                allocLock.ExitUpgradeableReadLock();\n            }\n            return ret;\n            \n        }\n\n        public static global::System.IntPtr Mallocx(ulong size, int flags)\n        {\n            Initialized = true;\n            var __ret = __Internal.JeMallocx(size, flags);\n            return __ret;\n        }\n\n        public static global::System.IntPtr Rallocx(global::System.IntPtr ptr, ulong size, int flags)\n        {\n            Initialized = true;\n            var __ret = __Internal.JeRallocx(ptr, size, flags);\n            return __ret;\n        }\n\n        public static ulong Xallocx(global::System.IntPtr ptr, ulong size, ulong extra, int flags)\n        {\n            Initialized = true;\n            var __ret = __Internal.JeXallocx(ptr, size, extra, flags);\n            return __ret;\n        }\n\n        public static ulong Sallocx(global::System.IntPtr ptr, int flags)\n        {\n            Initialized = true;\n            var __ret = __Internal.JeSallocx(ptr, flags);\n            return __ret;\n        }\n\n        public static void Dallocx(global::System.IntPtr ptr, int flags)\n        {\n            Initialized = true;\n            __Internal.JeDallocx(ptr, flags);\n        }\n\n        public static void Sdallocx(global::System.IntPtr ptr, ulong size, int flags)\n        {\n            Initialized = true;\n            __Internal.JeSdallocx(ptr, size, flags);\n        }\n\n        public static ulong Nallocx(ulong size, int flags)\n        {\n            Initialized = true;\n            var __ret = __Internal.JeNallocx(size, flags);\n            return __ret;\n        }\n\n        public static int Mallctl(string name, global::System.IntPtr oldp, ref ulong oldlenp, global::System.IntPtr newp, ulong newlen)\n        {\n            fixed (ulong* __refParamPtr2 = &oldlenp)\n            {\n                var __arg2 = __refParamPtr2;\n                var __ret = __Internal.JeMallctl(name, oldp, __arg2, newp, newlen);\n                return __ret;\n            }\n        }\n\n        public static int Mallctlnametomib(string name, ref ulong mibp, ref ulong miblenp)\n        {\n            fixed (ulong* __refParamPtr1 = &mibp)\n            {\n                var __arg1 = __refParamPtr1;\n                fixed (ulong* __refParamPtr2 = &miblenp)\n                {\n                    var __arg2 = __refParamPtr2;\n                    var __ret = __Internal.JeMallctlnametomib(name, __arg1, __arg2);\n                    return __ret;\n                }\n            }\n        }\n\n        public static int Mallctlbymib(ref ulong mib, ulong miblen, global::System.IntPtr oldp, ref ulong oldlenp, global::System.IntPtr newp, ulong newlen)\n        {\n            fixed (ulong* __refParamPtr0 = &mib)\n            {\n                var __arg0 = __refParamPtr0;\n                fixed (ulong* __refParamPtr3 = &oldlenp)\n                {\n                    var __arg3 = __refParamPtr3;\n                    var __ret = __Internal.JeMallctlbymib(__arg0, miblen, oldp, __arg3, newp, newlen);\n                    return __ret;\n                }\n            }\n        }\n        #endregion\n\n        #region High-level API\n        public static bool Init(string conf)\n        {\n            if (!Initialized)\n            {\n                if (mallocMessagesBuilder == null)\n                {\n                    mallocMessagesBuilder = new StringBuilder();\n                }\n                try\n                {\n                    MallocConf = conf;\n                }\n                catch (Exception)\n                {\n                    throw new ArgumentException($\"The configuration string \\'{conf}\\' is invalid\");\n                }\n                Initialized = true;\n                return true;\n            }\n            else return false;\n        }\n\n        #region Memory life-time management\n        public static int GetRefCount(IntPtr ptr)\n        {\n            allocLock.EnterReadLock();\n            int c = _Allocations[ptr];\n            allocLock.ExitReadLock();\n            return c;\n        }\n        \n        public static void IncrementRefCount(IntPtr ptr)\n        {\n            allocLock.EnterWriteLock();\n            _Allocations[ptr] = _Allocations[ptr] + 1;\n            allocLock.ExitWriteLock();\n        }\n\n        public static void DecrementRefCount(IntPtr ptr)\n        {\n            allocLock.EnterWriteLock();\n            _Allocations[ptr] = _Allocations[ptr] - 1;\n            allocLock.ExitWriteLock();\n        }\n\n        public static bool PtrIsAllocated(IntPtr ptr)\n        {\n            allocLock.EnterReadLock();\n            bool r = _Allocations.ContainsKey(ptr);\n            allocLock.ExitReadLock();\n            return r;\n        }\n        #endregion\n\n        public static string MallocStats => GetMallocStats(string.Empty);\n\n        public static string GetMallocStats(string opt)\n        {\n            StringBuilder statsBuilder = new StringBuilder(1000);\n            __Internal.JeMallocMessageCallback stats = (o, m) => { statsBuilder.Append(m); };\n            __Internal.JeMallocStatsPrint(Marshal.GetFunctionPointerForDelegate(stats), IntPtr.Zero, opt);\n            if (Environment.OSVersion.Platform == PlatformID.Win32NT)\n            {\n                statsBuilder = statsBuilder.Replace(\"\\\\n\", \"\\\\r\\\\n\");\n            }\n            return statsBuilder.ToString();\n        }\n\n        public static ulong MallocUsableSize(global::System.IntPtr ptr)\n        {\n            var __ret = __Internal.JeMallocUsableSize(ptr);\n            return __ret;\n        }\n\n        public static string MallocConf\n        {\n            get\n            {\n                return Marshal.PtrToStringAnsi(__Internal.JeGetMallocConf());\n            }\n            set\n            {\n                __Internal.JeSetMallocConf(Marshal.StringToHGlobalAnsi(value));\n            }\n        }\n\n        #region MallCtl\n        public static int GetMallCtlInt32(string name)\n        {\n            void* i = stackalloc int[1];\n            ulong size = sizeof(Int32);\n            ERRNO r = (ERRNO) Mallctl(name, (IntPtr) i, ref size, IntPtr.Zero, 0);\n            return r == ERRNO.ENONE ? *(Int32*)(i) : throw GetExceptionForErrNo($\"Could not get mallctl value {name}.\", r);\n        }\n\n        public static bool SetMallCtlInt32(string name, int value)\n        {\n            void* i = &value;\n            ulong size = sizeof(Int32);\n            ERRNO r = (ERRNO) Mallctl(name, IntPtr.Zero, ref size, (IntPtr) i, size);\n            return r == ERRNO.ENONE ? true : throw GetExceptionForErrNo($\"Could not set mallctl value {name} to {value}.\", r);\n        }\n\n        public static bool GetMallCtlBool(string name)\n        {\n            void* i = stackalloc byte[1];\n            ulong size = sizeof(byte);\n            ERRNO r = (ERRNO)Mallctl(name, (IntPtr)i, ref size, IntPtr.Zero, 0);\n            return r == ERRNO.ENONE ? *(byte*)(i) == 1 ? true : false: \n                r == ERRNO.ENOENT ? false : throw GetExceptionForErrNo($\"Could not get mallctl value {name}.\", r);\n         \n        }\n\n        public static bool SetMallCtlBool(string name, bool value)\n        {\n            byte v = value ? (byte) 1 : (byte) 0;\n            void* n = &v;\n            ulong size = sizeof(byte);\n            ERRNO r = (ERRNO)Mallctl(name, IntPtr.Zero, ref size, (IntPtr)n, size);\n            return r == ERRNO.ENONE ? true : throw GetExceptionForErrNo($\"Could not set mallctl value {name} to {value}.\", r);\n        }\n\n        public static UInt64 GetMallCtlUInt64(string name)\n        {\n            void* i = stackalloc UInt64[1];\n            ulong size = sizeof(UInt64);\n            ERRNO r = (ERRNO) Mallctl(name, (IntPtr) i, ref size, IntPtr.Zero, 0);\n            return r == ERRNO.ENONE ? *(UInt64*)(i) : throw GetExceptionForErrNo($\"Could not get mallctl value {name}.\", r);\n        }\n\n        public static bool SetMallCtlUInt64(string name, ulong value)\n        {\n            void* n = &value;\n            ulong size = sizeof(UInt64);\n            ERRNO r = (ERRNO) Mallctl(name, IntPtr.Zero, ref size, (IntPtr) n, size);\n            return r == ERRNO.ENONE ? true : throw GetExceptionForErrNo($\"Could not set mallctl value {name} to {value}.\", r);\n        }\n\n        public static Int64 GetMallCtlSInt64(string name)\n        {\n            void* i = stackalloc Int64[1];\n            ulong size = sizeof(Int64);\n            ERRNO r = (ERRNO) Mallctl(name, (IntPtr) i, ref size, IntPtr.Zero, 0);\n            return r == ERRNO.ENONE ? *(Int64*)(i) : throw GetExceptionForErrNo($\"Could not get mallctl value {name}.\", r);\n        }\n\n        public static bool SetMallCtlSInt64(string name, long value)\n        {\n            void* n = &value;\n            ulong size = sizeof(Int64);\n            ERRNO r = (ERRNO) Mallctl(name, IntPtr.Zero, ref size, (IntPtr)n, size);\n            return r == ERRNO.ENONE ? true : throw GetExceptionForErrNo($\"Could not set mallctl value {name} to {value}.\", r);\n        }\n\n        public static string GetMallCtlStr(string name)\n        {\n            void* p = stackalloc IntPtr[1];\n            IntPtr retp = new IntPtr(p);\n            ulong size = (ulong)sizeof(IntPtr);\n            int ret = Mallctl(name, (IntPtr) p, ref size, IntPtr.Zero, 0);\n            if ((ERRNO)ret == ERRNO.ENONE)\n            {\n                return Marshal.PtrToStringAnsi(*(IntPtr*)p);\n            }\n            else\n            {\n               throw GetExceptionForErrNo($\"Could not get mallctl value {name}.\", (ERRNO)ret);\n            }\n        }\n        #endregion\n\n        public static int TryFreeAll()\n        {\n            allocLock.EnterWriteLock();\n            int c = _Allocations.Count;\n            foreach (IntPtr p in _Allocations.Keys)\n            {\n                Jem.Free(p);\n                _Allocations.Remove(p);\n            }\n            allocLock.ExitWriteLock();\n            return c;\n        }\n\n        public static Span<T> Malloc<T>(ulong size, int length, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0) where T : struct\n        {\n            IntPtr ptr = Malloc(size, memberName, fileName, lineNumber);\n            return new Span<T>((void*)ptr, length);\n        }\n\n        #region FixedBuffer\n        public static IntPtr AllocateFixedBuffer<T>(ulong length, ulong size, long timestamp, int tid, int rid, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            IntPtr ptr = Jem.Calloc(length, size, memberName, fileName, lineNumber);\n            if (ptr != IntPtr.Zero)\n            {\n                fixedBufferLock.EnterWriteLock();\n                _FixedBufferAllocations.Add(ptr, new FixedBufferAllocation(ptr, length * size, timestamp, tid, rid));\n                fixedBufferLock.ExitWriteLock();\n\n            }\n            return ptr;\n        }\n\n        public static bool FreeFixedBuffer(IntPtr ptr)\n        {\n            fixedBufferLock.EnterWriteLock();\n            bool r = _FixedBufferAllocations.Remove(ptr);\n            fixedBufferLock.ExitWriteLock();\n            if (!r)\n            {\n                return false;\n            }\n            else\n            {\n                Jem.Free(ptr);\n                return true;\n            }\n            \n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public static bool FixedBufferIsAllocatedWith(IntPtr ptr, ulong size, long timestamp, int tid, int rid)\n        {\n            fixedBufferLock.EnterReadLock();\n            bool r1 = _FixedBufferAllocations.ContainsKey(ptr);\n            if (!r1)\n            {\n                fixedBufferLock.ExitReadLock();\n                return false;\n            }\n            else\n            {\n                bool r2 = _FixedBufferAllocations[ptr].Equals(new FixedBufferAllocation(ptr, size, timestamp, tid, rid));\n                fixedBufferLock.ExitReadLock();\n                return r2;\n            }\n        }\n        #endregion\n\n        #endregion\n\n        #region Utility methods\n        internal static bool AllocFlagSet(ALLOC_FLAGS flag)\n        {\n            return (flag & Flags) == flag;\n        }\n\n        internal static Exception GetExceptionForErrNo(string message, ERRNO no)\n        {\n            switch (no)\n            {\n                case ERRNO.ENOMEM:\n                    return new OutOfMemoryException(message);\n                default:\n                    return new Exception(message + $\" {no}.\");\n            }\n        }\n\n        internal static string GetCallerDetails(string memberName, string fileName, int lineNumber)\n        {\n            return $\"Member {memberName} at line {lineNumber} in file {fileName}\";\n        }\n\n        internal static string GetCallerDetails(CallerInformation c)\n        {\n            return $\"Member {c.Name} at line {c.LineNumber} in file {c.File}\";\n        }\n        #endregion\n\n        #endregion\n\n        #region Properties\n        public static bool Initialized { get; private set; } = false;\n\n        public static ALLOC_FLAGS Flags;\n\n        #region Malloc Messages\n        public static event JeMallocMessageAction MallocMessage;\n\n        public static string MallocMessages => mallocMessagesBuilder.ToString();\n\n        private static __Internal.JeMallocMessageCallback messagesCallback = (o, m) =>\n        {\n            mallocMessagesBuilder.Append(m);\n            MallocMessage.Invoke(m);\n        };\n        #endregion\n\n        #region jemalloc Statistics\n        public static UInt64 AllocatedBytes => GetMallCtlUInt64(\"stats.allocated\");\n        public static UInt64 ActiveBytes => GetMallCtlUInt64(\"stats.active\");\n        public static UInt64 MappedBytes => GetMallCtlUInt64(\"stats.mapped\");\n        public static UInt64 ResidentBytes => GetMallCtlUInt64(\"stats.resident\");\n\n        #endregion\n\n        #region Allocations ledgers\n\n        public static List<Tuple<IntPtr, ulong, CallerInformation>> AllocationsDetails { get; private set; } = new List<Tuple<IntPtr, ulong, CallerInformation>>();\n        #endregion\n        #endregion\n\n        #region Fields\n        private static StringBuilder mallocMessagesBuilder = new StringBuilder();\n        private static Dictionary<IntPtr, int> _Allocations = new Dictionary<IntPtr, int>(1024);\n        private static Dictionary<IntPtr, FixedBufferAllocation> _FixedBufferAllocations = new Dictionary<IntPtr, FixedBufferAllocation>(1024);\n        private static FixedBufferComparator fixedBufferComparator = new FixedBufferComparator();\n        private static ReaderWriterLockSlim allocLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);\n        private static ReaderWriterLockSlim fixedBufferLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/JemPinnable.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace jemalloc\n{\n    [StructLayout(LayoutKind.Sequential)]\n    internal sealed class JemPinnable<T>\n    {\n        public T Data;\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/JemUtil.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Collections.Generic;\nusing System.Collections.Concurrent;\nusing System.Collections.Immutable;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Runtime.ConstrainedExecution;\nusing System.Security;\n\n\nnamespace jemalloc\n{\n    public static class JemUtil\n    {\n        #region Constructor\n        static JemUtil()\n        {\n            \n        }\n        #endregion\n\n        #region Properties\n        public static ConcurrentDictionary<string, object> BenchmarkValues { get; } = new ConcurrentDictionary<string, object>();\n\n        public static ConcurrentDictionary<string, string> BenchmarkStatistics { get; } = new ConcurrentDictionary<string, string>();\n\n        public static Process CurrentProcess { get; } =  Process.GetCurrentProcess();\n\n        public static Random Rng { get; } = new Random();\n\n        public static long ProcessPrivateMemory\n        {\n            get\n            {\n                CurrentProcess.Refresh();\n                return CurrentProcess.PrivateMemorySize64;\n            }\n        }\n        public static long ProcessPeakVirtualMem\n        {\n            get\n            {\n                CurrentProcess.Refresh();\n                return CurrentProcess.PeakVirtualMemorySize64;\n            }\n        }\n\n        public static long ProcessPeakWorkingSet\n        {\n            get\n            {\n                CurrentProcess.Refresh();\n                return CurrentProcess.PeakWorkingSet64;\n            }\n        }\n\n        public static long ProcessPeakPagedMem\n        {\n            get\n            {\n                CurrentProcess.Refresh();\n                return CurrentProcess.PeakPagedMemorySize64;\n            }\n        }\n\n        public static long ProcessVirtualMemory\n        {\n            get\n            {\n                CurrentProcess.Refresh();\n                return CurrentProcess.VirtualMemorySize64;\n            }\n        }\n\n        public static long ProcessWorkingSet\n        {\n            get\n            {\n                CurrentProcess.Refresh();\n                return CurrentProcess.WorkingSet64;\n            }\n        }\n\n        public static long ProcessPagedMemory\n        {\n            get\n            {\n                CurrentProcess.Refresh();\n                return CurrentProcess.PagedMemorySize64;\n            }\n        }\n\n        public static Type CLRType<T>() => typeof(T);\n\n        public static uint ElementSizeInBytes<T>() where T: struct => (uint)JemUtil.SizeOfStruct<T>();\n\n        public static int VectorLength<T> () where T : struct => Vector<T>.Count;\n\n        public static bool SIMD => Vector.IsHardwareAccelerated;\n        #endregion\n\n        #region Methods\n        public static bool IsNumericType<T>()\n        {\n            return NumericTypes.Contains(typeof(T));\n        }\n\n        public unsafe static Span<T> PtrToSpan<T>(IntPtr ptr, int length)\n        {\n            return new Span<T>((void*)ptr, length);\n        }\n\n\n        public unsafe static ref readonly T PtrToStruct<T>(void* ptr) where T : struct\n        {\n            return ref Unsafe.AsRef<T>(ptr);\n        }\n\n        public unsafe static TReturn ValToGenericStruct<TValue, TReturn>(TValue v) where TValue : struct where TReturn : struct\n        {\n            void* ptr = Unsafe.AsPointer(ref v);\n            return PtrToStruct<TReturn>(ptr);\n        }\n\n        public static int SizeOfStruct<T>() where T : struct\n        {\n            return Unsafe.SizeOf<T>();\n        }\n\n        // System.String.GetHashCode(): http://referencesource.microsoft.com/#mscorlib/system/string.cs,0a17bbac4851d0d4\n        // System.Web.Util.StringUtil.GetStringHashCode(System.String): http://referencesource.microsoft.com/#System.Web/Util/StringUtil.cs,c97063570b4e791a\n        public static int CombineHashCodes(params int[] hashCodes)\n        {\n            int hash1 = (5381 << 16) + 5381;\n            int hash2 = hash1;\n\n            int i = 0;\n            foreach (var hashCode in hashCodes)\n            {\n                if (i % 2 == 0)\n                    hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ hashCode;\n                else\n                    hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ hashCode;\n\n                ++i;\n            }\n\n            return hash1 + (hash2 * 1566083941);\n        }\n\n        public static string PrintSize(double bytes, string suffix = \"\")\n        {\n            if (bytes >= 0 && bytes <= 1024)\n            {\n                return string.Format(\"{0:N0} {1}\", bytes, suffix);\n            }\n            else if (bytes >= 1024 && bytes < (1024 * 1024))\n            {\n                return string.Format(\"{0:N1} K{1}\", bytes / 1024, suffix);\n            }\n            else if (bytes >= (1024 * 1024) && bytes < (1024 * 1024 * 1024))\n            {\n                return string.Format(\"{0:N1} M{1}\", bytes / (1024 * 1024), suffix);\n            }\n            else if (bytes >= (1024 * 1024 * 1024) && (bytes < (1024f * 1024f * 1024f * 1024f)))\n            {\n                return string.Format(\"{0:N1} G{1}\", bytes / (1024 * 1024 * 1024), suffix);\n            }\n            else if (bytes >= (1024f * 1024f * 1024f * 1024f) && (bytes < (1024f * 1024f * 1024f * 1024f * 1024f)))\n            {\n                return string.Format(\"{0:N1} T{1}\", bytes / (1024f * 1024f * 1024f * 1024f), suffix);\n            }\n            else throw new ArgumentOutOfRangeException();\n\n        }\n\n        public static string PrintBytes(double bytes, string suffix = \"\")\n        {\n            if (bytes >= 0 && bytes <= 1024)\n            {\n                return string.Format(\"{0:N0} B{1}\", bytes, suffix);\n            }\n            else if (bytes >= 1024 && bytes < (1024 * 1024))\n            {\n                return string.Format(\"{0:N1} KB{1}\", bytes / 1024, suffix);\n            }\n            else if (bytes >= (1024 * 1024) && bytes < (1024 * 1024 * 1024))\n            {\n                return string.Format(\"{0:N1} MB{1}\", bytes / (1024 * 1024), suffix);\n            }\n            else if (bytes >= (1024 * 1024 * 1024) && (bytes < (1024f * 1024f * 1024f * 1024f)))\n            {\n                return string.Format(\"{0:N1} GB{1}\", bytes / (1024 * 1024 * 1024), suffix);\n            }\n            else if (bytes >= (1024f * 1024f * 1024f * 1024f) && (bytes < (1024f * 1024f * 1024f * 1024f * 1024f)))\n            {\n                return string.Format(\"{0:N1} TB{1}\", bytes / (1024f * 1024f * 1024f * 1024f), suffix);\n            }\n            else throw new ArgumentOutOfRangeException();\n\n        }\n\n        public static Tuple<double, string> PrintBytesToTuple(double bytes, string suffix = \"\")\n        {\n            string[] s = PrintBytes(bytes, suffix).Split(' ');\n            return new Tuple<double, string>(Double.Parse(s[0]), s[1]);\n        }\n\n        public unsafe static ulong GetCurrentThreadCycles()\n        {\n            if (Environment.OSVersion.Platform != PlatformID.Win32NT)\n            {\n                throw new PlatformNotSupportedException();\n            }\n            \n            if (!__Internal.DuplicateHandle(__Internal.GetCurrentProcess(), __Internal.GetCurrentThread(), __Internal.GetCurrentProcess(), out IntPtr* p,\n                0x0400, true, (uint) __Internal.DuplicateOptions.DUPLICATE_SAME_ACCESS))\n            {\n                throw new System.ComponentModel.Win32Exception();\n            }\n\n            if (__Internal.QueryThreadCycleTime(in *p, out ulong cycles))\n            {\n                //__Internal.CloseHandle(*p);\n                return cycles;\n            }    \n            else\n            {\n                //__Internal.CloseHandle(*p);\n                throw new System.ComponentModel.Win32Exception();\n            }\n            \n\n        }\n\n        public partial struct __Internal\n        {\n            [Flags]\n            public enum DuplicateOptions : uint\n            {\n                DUPLICATE_CLOSE_SOURCE = (0x00000001),// Closes the source handle. This occurs regardless of any error status returned.\n                DUPLICATE_SAME_ACCESS = (0x00000002), //Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle.\n            }\n\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            [SuppressUnmanagedCodeSecurity]\n            internal static extern bool QueryThreadCycleTime(in IntPtr hThread, out ulong cycles);\n\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            [SuppressUnmanagedCodeSecurity]\n            internal static extern IntPtr GetCurrentThread();\n\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            [SuppressUnmanagedCodeSecurity]\n            internal static extern IntPtr GetCurrentProcess();\n\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            [SuppressUnmanagedCodeSecurity]\n            [return: MarshalAs(UnmanagedType.Bool)]\n            internal static unsafe extern bool DuplicateHandle(IntPtr hSourceProcessHandle,IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr* lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);\n\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n            [SuppressUnmanagedCodeSecurity]\n            [return: MarshalAs(UnmanagedType.Bool)]\n            internal static extern bool CloseHandle(IntPtr hObject);\n\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            public static extern bool QueryPerformanceCounter(out long lpPerformanceCount);\n        }\n        #endregion\n\n        #region Fields\n        public static readonly Type Int8CLRType = typeof(SByte);\n        public static readonly Type UInt8CLRType = typeof(Byte);\n        public static readonly Type Int16CLRType = typeof(Int16);\n        public static readonly Type UInt16CLRType = typeof(UInt16);\n        public static readonly Type Int32CLRType = typeof(Int32);\n        public static readonly Type UInt32CLRType = typeof(UInt32);\n        public static readonly Type Int64CLRType = typeof(Int64);\n        public static readonly Type UInt64CLRType = typeof(UInt64);\n        public static readonly Type SingleCLRType = typeof(Single);\n        public static readonly Type DoubleCLRType = typeof(Double);\n        public static readonly Type CharCLRType = typeof(Char);\n        public static readonly Type DecimalCLRType = typeof(Decimal);\n        public static readonly Type IntPtrCLRType = typeof(IntPtr);\n        public static readonly Type BoolCLRType = typeof(Boolean);\n        public static readonly HashSet<Type> NumericTypes = new HashSet<Type>(new Type[]\n        {\n            Int8CLRType, UInt8CLRType, Int16CLRType, UInt16CLRType, Int32CLRType, UInt32CLRType, Int64CLRType, UInt64CLRType,\n            SingleCLRType, DoubleCLRType, CharCLRType, BoolCLRType\n        });\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/MemoryRef.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Buffers;\nusing System.Text;\n\nnamespace jemalloc\n{\n    public readonly ref struct MemoryRef<T> where T : struct\n    {\n        internal MemoryRef(Guid guid, MemoryHandle h)\n        {\n            Id = guid;\n            Handle = h;\n        }\n        private readonly Guid Id;\n        private readonly MemoryHandle Handle;\n        public bool Release()\n        {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/NDArray.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace jemalloc\n{\n    //WIP\n    public class NDArray<T> where T : struct\n    {\n        public NDArray(ulong points, int rank)\n        {\n            //data[3L]\n        }\n\n        //HugeArray<T>[] data;\n        \n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/SafeArray.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Numerics;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Text;\n\nnamespace jemalloc\n{\n    public class SafeArray<T> : SafeBuffer<T> where T : struct, IEquatable<T>\n    {\n        public SafeArray(int length, params T[] values) : base(length, values) {}\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/SafeBuffer.cs",
    "content": "﻿using System;\nusing System.Buffers;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.ConstrainedExecution;\nusing System.Text;\n\nnamespace jemalloc\n{\n    public abstract class SafeBuffer<T> : SafeHandle, IRetainable, IDisposable, IEquatable<SafeBuffer<T>>, IEnumerable<T> where T : struct, IEquatable<T>\n    {\n        #region Constructors\n        protected SafeBuffer(int length, params T[] values) : base(IntPtr.Zero, true)\n        {\n            if (BufferHelpers.IsReferenceOrContainsReferences(typeof(T), out FieldInfo field))\n            {\n                throw new ArgumentException($\"Only structures without reference fields can be used with this class. The field {field.Name} has type {field.FieldType.Name}.\");\n            }\n            if (values.Length > length)\n            {\n                throw new ArgumentException(\"The length of the list of values must be smaller or equal to the length of the buffer\");\n            }\n            SizeInBytes = NotAllocated;\n            base.SetHandle(Allocate(length));\n            if (IsAllocated)\n            {\n                CopyFrom(values);\n            }\n        }\n\n        #endregion\n\n        #region Overriden members\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        protected override bool ReleaseHandle()\n        {\n            bool r = Jem.Free(handle);\n            if (!r)\n            {\n                return false;\n            }\n            else\n            {\n                handle = IntPtr.Zero;\n                unsafe\n                {\n                    voidPtr = (void *) 0;\n                }\n                Length = 0;\n                SizeInBytes = 0;\n                return true;\n            }\n        }\n\n        public override bool IsInvalid => handle == IntPtr.Zero;\n\n        #region Disposer\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing)\n            {\n                ThrowIfNotAllocatedOrInvalid();\n                ThrowIfRetained();\n                ReleaseHandle();\n            }\n            base.Dispose(disposing);\n        }\n\n        #endregion\n\n        #endregion\n\n        #region Implemented members\n        public void Retain() => Acquire();\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        public bool Release()\n        {\n            \n            if (IsNotAllocated || IsInvalid)\n            {\n                return false;\n            }\n            else\n            {\n                Jem.DecrementRefCount(handle);\n                DangerousRelease();\n                return true;\n            }\n        }\n\n        public bool Equals(SafeBuffer<T> other)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            return this.handle == other.handle && this.Length == other.Length;\n        }\n\n        public IEnumerator<T> GetEnumerator() => new SafeBufferEnumerator<T>(this);\n\n        IEnumerator IEnumerable.GetEnumerator() => new SafeBufferEnumerator<T>(this);\n        #endregion\n\n        #region Properties\n        public int Length { get; protected set; }\n\n        public ulong SizeInBytes { get; protected set; }\n\n        public bool IsNotAllocated => SizeInBytes == NotAllocated;\n\n        public bool IsAllocated => !IsNotAllocated;\n\n        public bool IsValid => !IsInvalid;\n\n        public bool IsRetained => IsValid ? _RefCount > 0 : false;\n\n        public bool IsVectorizable { get; protected set; }\n\n        public Span<T> Span\n        {\n            get\n            {\n                ThrowIfNotAllocatedOrInvalid();\n                return _Span;\n            }\n        }\n\n        protected int _RefCount => Jem.GetRefCount(handle);\n\n        protected unsafe Span<T> _Span => new Span<T>(voidPtr, Length);\n\n        #endregion\n\n        #region Methods\n\n        #region Memory management\n        protected unsafe virtual IntPtr Allocate(int length)\n        {\n            if (length <= 0)\n                throw new ArgumentOutOfRangeException(\"length\");\n            Contract.EndContractBlock();\n            ulong s = checked((uint)length * ElementSizeInBytes);\n            handle = Jem.Calloc((uint)length, ElementSizeInBytes);\n            if (handle != IntPtr.Zero)\n            {\n                voidPtr = handle.ToPointer();\n                Length = length;\n                SizeInBytes = s;\n                InitVector();\n            }\n            return handle;\n        }\n\n        protected void InitVector()\n        {\n            if (IsNumeric && Length % VectorLength == 0 && SIMD && IsNumeric)\n            {\n                IsVectorizable = true;\n            }\n            else\n            {\n                IsVectorizable = false;\n            }\n        }\n\n        \n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        protected unsafe ref T Read(int index)\n        {\n            // return (T*) (_ptr + byteOffset);\n            return ref Unsafe.Add(ref Unsafe.AsRef<T>(voidPtr), index);\n\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        protected unsafe void Write(int index, T value)\n        {\n\n            ref T v = ref Unsafe.Add(ref Unsafe.AsRef<T>(voidPtr), index);\n            v = value;\n        }\n\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]\n        public bool Acquire()\n        {\n            if (IsNotAllocated || IsInvalid)\n                return false;\n            bool success = false;\n            DangerousAddRef(ref success);\n            if (success)\n            {\n                Jem.IncrementRefCount(handle);\n            }\n            return success;\n        }\n\n        public bool Release(int n)\n        {\n            bool r = false;\n            for (int i = 0; i < n; i++)\n            {\n                r = Release();\n                if (r)\n                {\n                    continue;\n                }\n                else\n                {\n                    return r;\n                }\n            }\n            return r;\n        }\n        #endregion\n\n        #region Values\n\n        public bool EqualTo(T[] array)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            return _Span.SequenceEqual<T>(new ReadOnlySpan<T>(array));\n\n        }\n\n        public void Fill(T value)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            Span.Fill(value);\n        }\n\n\n        public void CopyFrom(T[] array)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            Span<T> s = _Span;\n            new Span<T>(array).CopyTo(_Span);\n        }\n\n        public T[] CopyToArray()\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            T[] a = new T[this.Length];\n            _Span.CopyTo(new Span<T>(a));\n            return a;\n        }\n\n        public unsafe Span<C> GetSpan<C>(int index = 0, int length = 1) where C : struct, IEquatable<C>\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            ThrowIfIndexOutOfRange(index);\n            ulong s = (ulong) (index * ElementSizeInBytes + length * Unsafe.SizeOf<C>());\n            if (s > SizeInBytes)\n            {\n                SizeIsOutOfRange(s);\n            }\n            void* p = BufferHelpers.Add<T>(handle, index).ToPointer();\n            return new Span<C>(p, length);\n        }\n\n        public unsafe Span<T> Slice(int index) => GetSpan<T>(index, Length - index);\n\n        public unsafe Span<T> Slice(int start, int end)\n        {\n            if (start >= end)\n            {\n                throw new ArgumentOutOfRangeException($\"The end {end} of the slice must be greater than the start {start}.\");\n            }\n            else\n            {\n                return GetSpan<T>(start, end - start);\n            }\n        }\n\n        public unsafe Vector<C> GetVector<C>() where C : struct, IEquatable<C>, IConvertible, IComparable, IFormattable\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            ThrowIfNotNumeric();\n            if (this.Length != Vector<C>.Count)\n            {\n                throw new InvalidOperationException($\"The length of the array must be {Vector<C>.Count} elements to create a vector of type {CLRType.Name}.\");\n            }\n            else\n            {\n                return Unsafe.Read<Vector<C>>(voidPtr);\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe Vector<T> GetSliceAsVector(int index)\n        {\n            ThrowIfNotAllocatedOrInvalid();\n            ThrowIfNotNumeric();\n            if ((index + VectorLength) > Length)\n            {\n                BufferIndexIsOutOfRange(index);\n            }\n            return Unsafe.Read<Vector<T>>(BufferHelpers.Add<T>(handle, index).ToPointer());\n        }\n        #endregion\n\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfNotAllocatedOrInvalid()\n        {\n            if (IsNotAllocated)\n            {\n                BufferIsNotAllocated();\n            }\n            else if (IsInvalid)\n            {\n                HandleIsInvalid();\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfRetained()\n        {\n            if (IsRetained)\n            {\n                throw new InvalidOperationException($\"SafeBuffer<{typeof(T)}[{Length}] has outstanding references.\");\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfNotAllocated()\n        {\n            if (IsNotAllocated)\n            {\n                BufferIsNotAllocated();\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfCannotAcquire()\n        {\n            if (!Acquire())\n            {\n                throw new InvalidOperationException(\"Could not acquire handle.\");\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfNotVectorisable()\n        {\n            if (!IsVectorizable)\n            {\n                BufferIsNotVectorisable();\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfNotNumeric()\n        {\n            if (!IsNumeric)\n            {\n                BufferIsNotNumeric();\n            }\n        }\n\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfIndexOutOfRange(int index)\n        {\n            if (index < 0 || index >= Length)\n            {\n                BufferIndexIsOutOfRange(index);\n            }\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private void ThrowIfLengthOutOfRange(int length)\n        {\n            if (length < 0 || length>= Length)\n            {\n                LengthIsOutOfRange(length);\n            }\n        }\n\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static void HandleIsInvalid()\n        {\n            throw new InvalidOperationException(\"The handle is invalid.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static void BufferIsNotAllocated()\n        {\n            Contract.Assert(false, \"Unallocated safe buffer used.\");\n            throw new InvalidOperationException(\"Unallocated safe buffer used.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static void BufferIsNotVectorisable()\n        {\n            Contract.Assert(false, \"Buffer is not vectorisable.\");\n            throw new InvalidOperationException(\"Buffer is not vectorisable.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static void BufferIsNotNumeric()\n        {\n            Contract.Assert(false, \"Buffer is not numeric.\");\n            throw new InvalidOperationException(\"Buffer is not numeric.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static void BufferIndexIsOutOfRange(int index)\n        {\n            Contract.Assert(false, $\"Index {index} into buffer is out of range.\");\n            throw new IndexOutOfRangeException($\"Index {index} into buffer is out of range.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static void LengthIsOutOfRange(int length)\n        {\n            Contract.Assert(false, $\"Length {length} exceeds buffer length.\");\n            throw new Exception($\"Length {length} exceeds buffer length.\");\n        }\n\n        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        [DebuggerStepThrough]\n        private static void SizeIsOutOfRange(ulong size)\n        {\n            Contract.Assert(false, $\"Length {size} exceeds buffer size.\");\n            throw new Exception($\"Length {size} exceeds buffer size.\");\n        }\n\n        #region Arithmetic\n        public void VectorFill(T value)\n        {\n            Span<Vector<T>> s = GetSpan<Vector<T>>();\n            Vector<T> fill = new Vector<T>(value);\n            for (int i = 0; i < s.Length; i++)\n            {\n                s[i] = fill;\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public void VectorMultiply(T value)\n        {\n            ThrowIfNotVectorisable();\n            Span<Vector<T>> vectorSpan = GetSpan<Vector<T>>();\n            Vector<T> mulVector = new Vector<T>(value);\n            for (int i = 0; i < vectorSpan.Length; i++)\n            {\n                vectorSpan[i] = Vector.Multiply(vectorSpan[i], mulVector);\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public void VectorSqrt()\n        {\n            ThrowIfNotVectorisable();\n            Span<Vector<T>> vector = GetSpan<Vector<T>>();\n            for (int i = 0; i < vector.Length; i++)\n            {\n                vector[i] = Vector.SquareRoot(vector[i]);\n            }\n        }\n        #endregion\n\n        #endregion\n\n        #region Operators\n        public ref T this[int index]\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get\n            {\n                ThrowIfNotAllocatedOrInvalid();\n                ThrowIfIndexOutOfRange(index);\n                return ref this.Read(index);\n            }\n         }\n        #endregion\n\n        #region Fields\n        protected static readonly Type CLRType = typeof(T);\n        protected static readonly T Element = default;\n        protected static readonly uint ElementSizeInBytes = (uint) JemUtil.SizeOfStruct<T>();\n        protected static readonly UInt64 NotAllocated = UInt64.MaxValue;\n        protected static bool IsNumeric = JemUtil.IsNumericType<T>();\n        protected static int VectorLength = IsNumeric ? Vector<T>.Count : 0;\n        protected static bool SIMD = Vector.IsHardwareAccelerated;\n        protected internal unsafe void* voidPtr;\n        //Debugger Display = {T[length]}\n        protected string DebuggerDisplay => string.Format(\"{{{0}[{1}]}}\", typeof(T).Name, Length);\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/SafeBufferEnumerator.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Text;\n\nnamespace jemalloc\n{\n    /// <summary>Enumerates the elements of a <see cref=\"SafeBuffer{T}\"/>.</summary>\n    public class SafeBufferEnumerator<T> : IEnumerator, IEnumerator<T> where T : struct, IEquatable<T>\n    {\n        /// <summary>The SafeBuffer being enumerated.</summary>\n        private readonly SafeBuffer<T> _buffer;\n        /// <summary>The next index to yield.</summary>\n        private int _index;\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        internal SafeBufferEnumerator(SafeBuffer<T> buffer)\n        {\n            _buffer = buffer;\n            _buffer.Acquire();\n            _index = -1;\n        }\n\n        /// <summary>Advances the enumerator to the next element of the buffer.</summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public bool MoveNext()\n        {\n            int index = _index + 1;\n            if (index < _buffer.Length)\n            {\n                _index = index;\n                return true;\n            }\n            else\n            {\n                return false;\n            }\n            \n        }\n\n        public void Reset()\n        {\n            _index = -1;\n        }\n\n        /// <summary>Gets the element at the current position of the enumerator.</summary>\n        object IEnumerator.Current\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => _buffer[_index];\n        }\n\n        public T Current\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => _buffer[_index];\n        }\n\n        void IDisposable.Dispose()\n        {\n            _buffer.Release();\n        }\n    }\n\n}\n"
  },
  {
    "path": "jemalloc.Api/Utf8Buffer.cs",
    "content": "﻿//B\n// Copyright (c) Microsoft. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nusing System;\nusing System.Buffers;\nusing System.Buffers.Text;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Runtime.CompilerServices;\nusing System.Text;\nusing System.Text.Primitives;\nusing System.Text.Utf8;\n\nnamespace jemalloc\n{\n    [DebuggerDisplay(\"{ToString()} utf8\")]\n    public readonly struct Utf8Buffer : IEquatable<Utf8Buffer>, IRetainable, IDisposable\n    {\n        #region Constructors\n        public Utf8Buffer(ReadOnlySpan<byte> utf8Bytes) => buffer = new FixedBuffer<byte>(utf8Bytes);\n\n        public Utf8Buffer(Utf8Span utf8Span) : this(utf8Span.Bytes) { }\n\n        public Utf8Buffer(string utf16String)\n        {\n            if (utf16String == null)\n            {\n                throw new ArgumentNullException(nameof(utf16String));\n            }\n\n            if (utf16String == string.Empty)\n            {\n                buffer = new FixedBuffer<byte>();\n            }\n            else\n            {\n                byte[] b = Encoding.UTF8.GetBytes(utf16String);\n                buffer = new FixedBuffer<byte>(b);\n            }\n        }\n\n        private Utf8Buffer(byte[] utf8Bytes) => buffer = new FixedBuffer<byte>(utf8Bytes);\n\n        #endregion\n\n        #region Implemented members\n        public void Retain() => buffer.Retain();\n        public bool Release() => buffer.Release();\n        #region Disposer\n        void IDisposable.Dispose()\n        {\n            if (IsRetained)\n            {\n                throw new InvalidOperationException($\"FixedString<[{this.Length}] has outstanding references.\");\n            }\n            else\n            {\n                Dispose(true);\n                GC.SuppressFinalize(this);\n            }\n        }\n        #endregion\n        #endregion\n\n        #region Overidden members\n        public override int GetHashCode() => Span.GetHashCode();\n\n        public override string ToString() => Span.ToString();\n\n        public override bool Equals(object obj)\n        {\n            if (obj is Utf8Buffer)\n            {\n                return Equals((Utf8Buffer)obj);\n            }\n            if (obj is string)\n            {\n                return Equals((string)obj);\n            }\n\n            return false;\n        }\n        #endregion\n\n        #region Properties\n        public static Utf8Buffer Empty => s_empty;\n\n        public bool IsEmpty => Bytes.Length == 0;\n\n        public bool IsRetained => buffer.IsRetained;\n\n        public int Length => buffer.Length;\n\n        public ReadOnlySpan<byte> Bytes => buffer.Span;\n\n        internal Utf8Span Span\n        {\n            get\n            {\n                ThrowIfInvalid();\n                return new Utf8Span(this);\n            }\n        }\n\n        #endregion\n\n        #region Operators\n        public ref byte this[int index]\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get => ref this.buffer[index];\n        }\n\n        public static bool operator ==(Utf8Buffer left, Utf8Buffer right) => left.Equals(right);\n        public static bool operator !=(Utf8Buffer left, Utf8Buffer right) => !left.Equals(right);\n        public static bool operator ==(Utf8Buffer left, Utf8Span right) => left.Equals(right);\n        public static bool operator !=(Utf8Buffer left, Utf8Span right) => !left.Equals(right);\n        public static bool operator ==(Utf8Span left, Utf8Buffer right) => right.Equals(left);\n        public static bool operator !=(Utf8Span left, Utf8Buffer right) => !right.Equals(left);\n\n        // TODO: do we like all these O(N) operators? \n        public static bool operator ==(Utf8Buffer left, string right) => left.Equals(right);\n        public static bool operator !=(Utf8Buffer left, string right) => !left.Equals(right);\n        public static bool operator ==(string left, Utf8Buffer right) => right.Equals(left);\n        public static bool operator !=(string left, Utf8Buffer right) => !right.Equals(left);\n\n        public static implicit operator ReadOnlySpan<byte>(Utf8Buffer utf8String) => utf8String.Bytes;\n\n        public static implicit operator Utf8Span(Utf8Buffer utf8String) => utf8String.Span;\n\n        public static explicit operator Utf8Buffer(string utf16String) => new Utf8Buffer(utf16String);\n\n        public static explicit operator string(Utf8Buffer utf8String) => utf8String.ToString();\n        #endregion\n\n        #region Methods\n        public void ThrowIfInvalid() => buffer.ThrowIfInvalid();\n\n        public bool Free() => buffer.Free();\n\n        public bool Equals(Utf8Buffer other) => Bytes.SequenceEqual(other.Bytes);\n\n        public bool Equals(Utf8Span other) => Bytes.SequenceEqual(other.Bytes);\n\n        public bool Equals(string other) => Span.Equals(other);\n\n        public Utf8CodePointEnumerator GetEnumerator() => new Utf8CodePointEnumerator(buffer.Span);\n\n        public int CompareTo(Utf8Buffer other) => Span.CompareTo(other);\n\n        public int CompareTo(string other) => Span.CompareTo(other);\n\n        public int CompareTo(Utf8Span other) => Span.CompareTo(other);\n\n        public bool StartsWith(uint codePoint) => Span.StartsWith(codePoint);\n\n        public bool StartsWith(Utf8Buffer value) => Span.StartsWith(value.Span);\n\n        public bool StartsWith(Utf8Span value) => Span.StartsWith(value);\n\n        public bool EndsWith(Utf8Buffer value) => Span.EndsWith(value.Span);\n\n        public bool EndsWith(Utf8Span value) => Span.EndsWith(value);\n\n        public bool EndsWith(uint codePoint) => Span.EndsWith(codePoint);\n\n        #region Slicing\n        // TODO: should Utf8String slicing operations return Utf8Span? \n        // TODO: should we add slicing overloads that take char delimiters?\n        // TODO: why do we even have Try versions? If the delimiter is not found, the result should be the original.\n        public bool TrySubstringFrom(Utf8Buffer value, out Utf8Buffer result)\n        {\n            int idx = IndexOf(value);\n\n            if (idx == StringNotFound)\n            {\n                result = default;\n                return false;\n            }\n\n            result = Substring(idx);\n            return true;\n        }\n\n        public bool TrySubstringFrom(uint codePoint, out Utf8Buffer result)\n        {\n            int idx = IndexOf(codePoint);\n\n            if (idx == StringNotFound)\n            {\n                result = default;\n                return false;\n            }\n\n            result = Substring(idx);\n            return true;\n        }\n\n        public bool TrySubstringTo(Utf8Buffer value, out Utf8Buffer result)\n        {\n            int idx = IndexOf(value);\n\n            if (idx == StringNotFound)\n            {\n                result = default;\n                return false;\n            }\n\n            result = Substring(0, idx);\n            return true;\n        }\n\n        public bool TrySubstringTo(uint codePoint, out Utf8Buffer result)\n        {\n            int idx = IndexOf(codePoint);\n\n            if (idx == StringNotFound)\n            {\n                result = default;\n                return false;\n            }\n\n            result = Substring(0, idx);\n            return true;\n        }\n        #endregion\n\n        #region Index-based operations\n        // TODO: should we even have index based operations?\n        // TODO: should we have search (e.g. IndexOf) overlaods that take char?\n\n        public Utf8Buffer Substring(int index) => index == 0 ? this : Substring(index, Bytes.Length - index);\n\n        public Utf8Buffer Substring(int index, int length)\n        {\n            if (length == 0)\n            {\n                return Empty;\n            }\n            if (index == 0 && length == Bytes.Length) return this;\n\n            return new Utf8Buffer(buffer.Span.Slice(index, length));\n        }\n\n        public int IndexOf(Utf8Buffer value) => Bytes.IndexOf(value.Bytes);\n\n        public int IndexOf(uint codePoint) => Span.IndexOf(codePoint);\n\n        public int IndexOf(string s) => Span.IndexOf(new Utf8Span(Encoding.UTF8.GetBytes(s)));\n\n        public int LastIndexOf(Utf8Buffer value) => Span.LastIndexOf(value.Span);\n\n        public int LastIndexOf(uint codePoint) => Span.LastIndexOf(codePoint);\n\n        public bool TryFormat(Span<byte> buffer, out int written, StandardFormat format = default, SymbolTable symbolTable = null)\n        {\n            if (!format.IsDefault) throw new ArgumentOutOfRangeException(nameof(format));\n            if (symbolTable == SymbolTable.InvariantUtf8)\n            {\n                written = Bytes.Length;\n                return Bytes.TryCopyTo(buffer);\n            }\n\n            return symbolTable.TryEncode(Bytes, buffer, out var consumed, out written);\n        }\n        #endregion\n\n        /*\n        // TODO: unless we change the type of Trim to Utf8Span, this double allocates.\n        public FixedUtf8String Trim() => TrimStart().TrimEnd();\n\n        // TODO: implement Utf8String.Trim(uint[])\n        public FixedString Trim(uint[] codePoints) => throw new NotImplementedException();\n\n        public FixedString TrimStart()\n        {\n            Utf8CodePointEnumerator it = GetEnumerator();\n            while (it.MoveNext() &&Char.IsWhiteSpace(it.Current)) { }\n            return Substring(it.PositionInCodeUnits);\n        }\n\n        public FixedUtf8String TrimStart(uint[] codePoints) {\n            if (codePoints == null || codePoints.Length == 0) return TrimStart(); // Trim Whitespace\n\n            Utf8CodePointEnumerator it = GetEnumerator();       \n            while (it.MoveNext()) {\n                if(Array.IndexOf(codePoints, it.Current) == -1){\n                    break;\n                }\n            }\n\n            return Substring(it.PositionInCodeUnits);\n        }\n        \n        // TODO: do we even want this overload? System.String does not have an overload that takes string\n        public FixedString TrimStart(FixedString characters)\n        {\n            if (characters == Empty)\n            {\n                // Trim Whitespace\n                return TrimStart();\n            }\n\n            Utf8CodePointEnumerator it = GetEnumerator();\n            Utf8CodePointEnumerator itPrefix = characters.GetEnumerator();\n\n            while (it.MoveNext())\n            {\n                bool found = false;\n                // Iterate over prefix set\n                while (itPrefix.MoveNext())\n                {\n                    if (it.Current == itPrefix.Current)\n                    {\n                        // Character found, don't check further\n                        found = true;\n                        break;\n                    }\n                }\n\n                if (!found)\n                {\n                    // Reached the end, char was not found\n                    break;\n                }\n\n                itPrefix.Reset();\n            }\n\n            return Substring(it.PositionInCodeUnits);\n        }\n\n        public FixedString TrimEnd()\n        {\n            var it = new Utf8CodePointReverseEnumerator(Bytes);\n            while (it.MoveNext() && Unicode.IsWhitespace(it.Current))\n            {\n            }\n\n            return Substring(0, it.PositionInCodeUnits);\n        }\n\n        // TODO: implement Utf8String.TrimEnd(uint[])\n        public FixedString TrimEnd(uint[] codePoints) => throw new NotImplementedException();\n\n        // TODO: do we even want this overload? System.String does not have an overload that takes string\n        public FixedString TrimEnd(FixedString characters)\n        {\n            if (characters == Empty)\n            {\n                // Trim Whitespace\n                return TrimEnd();\n            }\n\n            var it = new Utf8CodePointReverseEnumerator(Bytes);\n            Utf8CodePointEnumerator itPrefix = characters.GetEnumerator();\n\n            while (it.MoveNext())\n            {\n                bool found = false;\n                // Iterate over prefix set\n                while (itPrefix.MoveNext())\n                {\n                    if (it.Current == itPrefix.Current)\n                    {\n                        // Character found, don't check further\n                        found = true;\n                        break;\n                    }\n                }\n\n                if (!found)\n                {\n                    // Reached the end, char was not found\n                    break;\n                }\n\n                itPrefix.Reset();\n            }\n\n            return Substring(0, it.PositionInCodeUnits);\n        }\n        */\n\n        #region Disposer\n        private void Dispose(bool disposing)\n        {\n            buffer.Free();\n        }\n\n        #endregion\n        #endregion\n\n        #region Fields\n        //private readonly byte[] _buffer;\n        private readonly FixedBuffer<byte> buffer;\n\n        private const int StringNotFound = -1;\n\n        static Utf8Buffer s_empty = new Utf8Buffer(string.Empty);\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "jemalloc.Api/jemalloc.Api.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netstandard2.0</TargetFramework>\n    <Platforms>AnyCPU;x64</Platforms>\n    <RootNamespace>jemalloc</RootNamespace>\n    <LangVersion>latest</LangVersion>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>\n    <PackageId>jemalloc.NET</PackageId>\n    <Version>0.2.4-alpha</Version>\n    <Authors>Allister Beharry</Authors>\n    <Company />\n    <Product>jemalloc.NET</Product>\n    <AssemblyVersion>0.2.4.0</AssemblyVersion>\n    <FileVersion>0.2.4.0</FileVersion>\n    <PackageProjectUrl>https://github.com/allisterb/jemalloc.NET</PackageProjectUrl>\n    <PackageLicenseUrl>https://github.com/allisterb/jemalloc.NET/LICENSE</PackageLicenseUrl>\n    <RepositoryUrl>https://github.com/allisterb/jemalloc.NET</RepositoryUrl>\n    <Description>Native memory manager for .NET</Description>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <LangVersion>latest</LangVersion>\n    <PlatformTarget>x64</PlatformTarget>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <OutputPath>..\\x64\\Debug\\</OutputPath>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <PlatformTarget>x64</PlatformTarget>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <OutputPath>..\\x64\\Debug\\</OutputPath>\n    <LangVersion>latest</LangVersion>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <PlatformTarget>x64</PlatformTarget>\n    <LangVersion>latest</LangVersion>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <OutputPath>..\\x64\\Release\\</OutputPath>\n    <DebugType>portable</DebugType>\n    <DebugSymbols>true</DebugSymbols>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Compile Remove=\"Utf16LittleEndianCodePointEnumerator.cs\" />\n    <Compile Remove=\"Utf8CodePointReverseEnumerator.cs\" />\n    <Compile Remove=\"Utf8Helper.cs\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"System.Collections.Immutable\" Version=\"1.4.0\" />\n    <PackageReference Include=\"System.Memory\" Version=\"4.5.0-preview1-26021-02\" />\n    <PackageReference Include=\"System.Numerics.Vectors\" Version=\"4.5.0-preview2-25707-02\" />\n    <PackageReference Include=\"System.Reflection.Emit\" Version=\"4.3.0\" />\n    <PackageReference Include=\"System.Reflection.Emit.ILGeneration\" Version=\"4.3.0\" />\n    <PackageReference Include=\"System.Runtime.CompilerServices.Unsafe\" Version=\"4.5.0-preview2-25707-02\" />\n    <PackageReference Include=\"System.Text.Utf8String\" Version=\"0.1.0-e171221-2\" />\n  </ItemGroup>\n\n  <Target Name=\"PostBuild\" AfterTargets=\"PostBuildEvent\">\n    <Exec Command=\"copy $(ProjectDir)..\\x64\\Debug\\jemallocd.dll $(TargetDir)\" />\n  </Target>\n\n</Project>\n"
  },
  {
    "path": "jemalloc.Api/jemalloc.cs",
    "content": "using System;\nusing System.Runtime.ConstrainedExecution;\nusing System.Runtime.InteropServices;\nusing System.Security;\n\nnamespace jemalloc\n{\n    #region Delegates\n    [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]\n    public unsafe delegate global::System.IntPtr ExtentAllocT(global::System.IntPtr _0, global::System.IntPtr _1, ulong _2, ulong _3, bool* _4, bool* _5, uint _6);\n\n    [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]\n    [return: MarshalAs(UnmanagedType.I1)]\n    public unsafe delegate bool ExtentDallocT(global::System.IntPtr _0, global::System.IntPtr _1, ulong _2, [MarshalAs(UnmanagedType.I1)] bool _3, uint _4);\n\n    [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]\n    public unsafe delegate void ExtentDestroyT(global::System.IntPtr _0, global::System.IntPtr _1, ulong _2, [MarshalAs(UnmanagedType.I1)] bool _3, uint _4);\n\n    [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]\n    [return: MarshalAs(UnmanagedType.I1)]\n    public unsafe delegate bool ExtentCommitT(global::System.IntPtr _0, global::System.IntPtr _1, ulong _2, ulong _3, ulong _4, uint _5);\n\n    [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]\n    [return: MarshalAs(UnmanagedType.I1)]\n    public unsafe delegate bool ExtentDecommitT(global::System.IntPtr _0, global::System.IntPtr _1, ulong _2, ulong _3, ulong _4, uint _5);\n\n    [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]\n    [return: MarshalAs(UnmanagedType.I1)]\n    public unsafe delegate bool ExtentPurgeT(global::System.IntPtr _0, global::System.IntPtr _1, ulong _2, ulong _3, ulong _4, uint _5);\n\n    [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]\n    [return: MarshalAs(UnmanagedType.I1)]\n    public unsafe delegate bool ExtentSplitT(global::System.IntPtr _0, global::System.IntPtr _1, ulong _2, ulong _3, ulong _4, [MarshalAs(UnmanagedType.I1)] bool _5, uint _6);\n\n    [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]\n    [return: MarshalAs(UnmanagedType.I1)]\n    public unsafe delegate bool ExtentMergeT(global::System.IntPtr _0, global::System.IntPtr _1, ulong _2, global::System.IntPtr _3, ulong _4, [MarshalAs(UnmanagedType.I1)] bool _5, uint _6);\n\n    public delegate void JeMallocMessageAction(string m);\n    #endregion\n\n    public unsafe static partial class Jem\n    {\n        public partial struct __Internal\n        {\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_malloc\")]\n            internal static extern global::System.IntPtr JeMalloc([In] ulong size);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_calloc\")]\n            internal static extern global::System.IntPtr JeCalloc([In] ulong num, [In] ulong size);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_posix_memalign\")]\n            internal static extern int JePosixMemalign(void** memptr, ulong alignment, ulong size);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_aligned_alloc\")]\n            internal static extern global::System.IntPtr JeAlignedAlloc(ulong alignment, ulong size);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_realloc\")]\n            internal static extern global::System.IntPtr JeRealloc(global::System.IntPtr ptr, ulong size);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_free\")]\n            internal static extern void JeFree(global::System.IntPtr ptr);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_mallocx\")]\n            internal static extern global::System.IntPtr JeMallocx(ulong size, int flags);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_rallocx\")]\n            internal static extern global::System.IntPtr JeRallocx(global::System.IntPtr ptr, ulong size, int flags);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_xallocx\")]\n            internal static extern ulong JeXallocx(global::System.IntPtr ptr, ulong size, ulong extra, int flags);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_sallocx\")]\n            internal static extern ulong JeSallocx(global::System.IntPtr ptr, int flags);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_dallocx\")]\n            internal static extern void JeDallocx(global::System.IntPtr ptr, int flags);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_sdallocx\")]\n            internal static extern void JeSdallocx(global::System.IntPtr ptr, ulong size, int flags);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_nallocx\")]\n            internal static extern ulong JeNallocx(ulong size, int flags);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_mallctl\")]\n            internal static extern int JeMallctl([MarshalAs(UnmanagedType.LPStr)] [In] string name, global::System.IntPtr oldp, ulong* oldlenp, global::System.IntPtr newp, ulong newlen);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_mallctlnametomib\")]\n            internal static extern int JeMallctlnametomib([MarshalAs(UnmanagedType.LPStr)] string name, ulong* mibp, ulong* miblenp);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_mallctlbymib\")]\n            internal static extern int JeMallctlbymib(ulong* mib, ulong miblen, global::System.IntPtr oldp, ulong* oldlenp, global::System.IntPtr newp, ulong newlen);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_malloc_stats_print\")]\n            internal static extern void JeMallocStatsPrint(global::System.IntPtr write_cb, global::System.IntPtr je_cbopaque, [MarshalAs(UnmanagedType.LPStr)] string opts);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,\n                EntryPoint=\"je_malloc_usable_size\")]\n            internal static extern ulong JeMallocUsableSize(global::System.IntPtr ptr);\n\n            [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]\n            internal unsafe delegate void JeMallocMessageCallback(global::System.IntPtr _0, [MarshalAs(UnmanagedType.LPStr)] string _1);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl, \n                EntryPoint = \"je_set_malloc_conf\", CharSet = CharSet.Ansi)]\n            internal static extern void JeSetMallocConf(IntPtr ptr);\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl, \n                EntryPoint = \"je_get_malloc_conf\", CharSet = CharSet.Ansi)]\n            internal static extern IntPtr JeGetMallocConf();\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl, EntryPoint = \"je_get_malloc_message_ptr\")]\n            internal static extern global::System.IntPtr JeGetMallocMessagePtr();\n\n            [SuppressUnmanagedCodeSecurity]\n            [DllImport(\"jemallocd\", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl, EntryPoint = \"je_set_malloc_message_ptr\")]\n            internal static extern void JeSetMallocMessagePtr(global::System.IntPtr p);\n\n            internal static JeMallocMessageCallback JeMallocMessage\n            {\n                get\n                {\n                    var ret = __Internal.JeGetMallocMessagePtr();\n                    return ret == IntPtr.Zero ? null :\n                        (__Internal.JeMallocMessageCallback)Marshal.GetDelegateForFunctionPointer(ret, typeof(__Internal.JeMallocMessageCallback));\n                }\n\n                set\n                {\n                    IntPtr ptr = value == null ? global::System.IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(value);\n                    __Internal.JeSetMallocMessagePtr(ptr);\n                }\n            }\n        }\n\n\n    }   \n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/BenchmarkStatisticColumn.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Columns;\nnamespace jemalloc.Benchmarks\n{\n    public class BenchmarkStatisticColumn : IColumn\n    {\n        #region Constructors\n        public BenchmarkStatisticColumn(string columnName, string legend)\n        {\n            ColumnName = columnName;\n            Legend = legend;\n        }\n        #endregion\n\n        #region Implemented properties\n        //\n        // Summary:\n        //     An unique identificator of the column. If there are several columns with the\n        //     same Id, only one of them will be shown in the summary.\n        public string Id => ColumnName;\n        //\n        // Summary:\n        //     Defines order of column in the same category.\n        public int PriorityInCategory { get; } = 99;\n\n        // Summary:\n        //     Defines how to format column's value\n        public UnitType UnitType { get; } = UnitType.Size;\n        //\n        // Summary:\n        //     Column description.\n        public string Legend { get; protected set; }\n\n        public bool AlwaysShow => true;\n\n        public bool IsNumeric => true;\n\n        public ColumnCategory Category => ColumnCategory.Statistics;\n\n        #endregion\n\n        #region Implemented methods\n        public bool IsDefault(Summary summary, Benchmark benchmark) => false;\n\n        public string GetValue(Summary summary, Benchmark benchmark)\n        {\n            if (JemUtil.BenchmarkStatistics.ContainsKey($\"{benchmark.Target.Method.Name}_{ColumnName}_{benchmark.Parameters[0].Value.GetHashCode()}\"))\n            {       \n                return JemUtil.BenchmarkStatistics[$\"{benchmark.Target.Method.Name}_{ColumnName}_{benchmark.Parameters[0].Value.GetHashCode()}\"];\n            }\n            else if (JemUtil.BenchmarkStatistics.ContainsKey($\"{benchmark.Target.Method.Name}_{ColumnName}\"))\n            {\n                return JemUtil.BenchmarkStatistics[$\"{benchmark.Target.Method.Name}_{ColumnName}\"];\n            }\n            else return string.Empty;\n            /*\n            string[] catgegories = new string[2] { \"Managed\", \"Unmanaged\" };\n            foreach (string c in catgegories)\n            {\n                if (benchmark.Target.Categories.Contains(c))\n                {\n                    if (JemUtil.BenchmarkStatistics.ContainsKey($\"{c}_{ColumnName}\"))\n                    {\n                        return JemUtil.BenchmarkStatistics[$\"{c}_{ColumnName}\"];\n                    }\n                }\n            }*/\n\n        }\n\n        public bool IsAvailable(Summary summary)\n        {\n            foreach(Benchmark benchmark in summary.Benchmarks)\n            {\n                if (JemUtil.BenchmarkStatistics.ContainsKey($\"{benchmark.Target.Method.Name}_{ColumnName}\"))\n                {\n                    return true;\n                }\n            }\n            return false;\n        }\n       \n        public string GetValue(Summary summary, Benchmark benchmark, ISummaryStyle style) => GetValue(summary, benchmark);\n\n        public string ColumnName { get; }\n        #endregion\n\n        #region Overriden methods\n        public override string ToString() => ColumnName;\n        #endregion\n\n        #region Available columns\n        public static readonly IColumn PrivateMemory = new BenchmarkStatisticColumn(\"PrivateMemory\", \"Total memory allocated for process(native and managed, 1KB = 1024B)\");\n        public static readonly IColumn WorkingSet = new BenchmarkStatisticColumn(\"WorkingSet\", \"Memory that is currently being used by process(native and managed, 1KB = 1024B)\");\n        public static readonly IColumn JemAllocated = new BenchmarkStatisticColumn(\"JemAllocated\", \"Total memory allocated by jemalloc(native only, inclusive, 1KB = 1024B)\");\n        public static readonly IColumn JemResident = new BenchmarkStatisticColumn(\"JemResident\", \"Resident memory allocated by jemalloc(native only, inclusive, 1KB = 1024B)\");\n        public static readonly IColumn ThreadCycles = new BenchmarkStatisticColumn(\"ThreadCycles\", \"RDTSC time elapsed.\");\n        public static readonly IColumn ISPCResult = new BenchmarkStatisticColumn(\"ISPCResult\", \"Result obtained with Intel ISPC compiler on a AVX2 CPU.\");\n        public static readonly IColumn ISPCResult2 = new BenchmarkStatisticColumn(\"ISPCResult2\", \"Result obtained with Intel ISPC compiler on a SSE4.2 CPU.\");\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/Benchmarks/FixedBufferVsManagedArray.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\n\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Loggers;\n\nnamespace jemalloc.Benchmarks\n{\n    [OrderProvider(methodOrderPolicy: MethodOrderPolicy.Declared)]\n    public class FixedBufferVsManagedArrayBenchmark<T> : JemBenchmark<T, int> where T : struct, IEquatable<T>, IComparable<T>, IConvertible\n    {\n        public int ArraySize  => Parameter;\n        public readonly T fill = typeof(T) == typeof(TestUDT) ? \n            JemUtil.ValToGenericStruct<TestUDT, T>(TestUDT.MakeTestRecord(JemUtil.Rng)) : GM<T>.Random();\n        public readonly (T factor, T max) mul = GM<T>.RandomMultiplyFactorAndValue();\n\n        \n        public override void GlobalSetup()\n        {\n            DebugInfoThis();\n            base.GlobalSetup();\n            Info($\"Array size is {ArraySize}.\");\n            T[] managedArray = new T[ArraySize];\n            SetValue(\"managedArray\", managedArray);\n            FixedBuffer<T> nativeArray = new FixedBuffer<T>(ArraySize);\n            nativeArray.Acquire();\n            SetValue(\"nativeArray\", nativeArray);\n            if (Operation == Operation.FILL)\n            {\n                Info($\"Array fill value is {fill}.\");\n                SetValue(\"fill\", fill);\n            }\n            else if (Operation == Operation.MATH)\n            {\n                Info($\"Array fill value is {mul.max}.\");\n                nativeArray.Fill(mul.max);\n                new Span<T>(managedArray).Fill(mul.max);\n                SetValue(\"fill\", mul.max);\n                Info($\"Array multiply factor is {mul.factor}.\");\n                SetValue(\"mul\", mul.factor);\n            }\n        }\n\n\n        #region Fill\n        [Benchmark(Description = \"Fill a managed array with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillManagedArray()\n        {\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            T fill = GetValue<T>(\"fill\");\n            for (int i = 0; i < managedArray.Length; i++)\n            {\n                managedArray[i] = fill;\n            }\n        }\n\n        [Benchmark(Description = \"Fill a FixedBuffer on the system unmanaged heap with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillFixedBuffer()\n        {\n            FixedBuffer<T> nativeArray = GetValue<FixedBuffer<T>>(\"nativeArray\");\n            T fill = GetValue<T>(\"fill\");\n            nativeArray.Fill(fill);\n        }\n\n        [Benchmark(Description = \"Create and Fill a managed array with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillManagedArrayWithCreate()\n        {\n            T[] managedArray = new T[ArraySize];\n            T fill = GetValue<T>(\"fill\");\n            for (int i = 0; i < managedArray.Length; i++)\n            {\n                managedArray[i] = fill;\n            }\n            managedArray = null;\n        }\n\n        [Benchmark(Description = \"Create and Fill a FixedBuffer on the system unmanaged heap with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillFixedBufferWithCreate()\n        {\n            FixedBuffer<T> nativeArray = new FixedBuffer<T>(ArraySize);\n            T fill = GetValue<T>(\"fill\");\n            nativeArray.Fill(fill);\n            nativeArray.Free();\n        }\n\n        [GlobalCleanup(Target = nameof(FillFixedBuffer))]\n        public void FillValidateAndCleanup()\n        {\n            InfoThis();\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            FixedBuffer<T> nativeArray = GetValue<FixedBuffer<T>>(\"nativeArray\");\n            T fill = GetValue<T>(\"fill\");\n            for (int i = 0; i < ArraySize / 1000; i++)\n            {\n                int index = GM<T>.Rng.Next(0, ArraySize);\n                if (!nativeArray[index].Equals(fill))\n                {\n                    Log.WriteLineError($\"Native array at index {index} is {nativeArray[index]} not {fill}.\");\n                    throw new Exception();\n                }\n            }\n            nativeArray.Release();\n            nativeArray.Free();\n            managedArray = null;\n            RemoveValue(\"managedArray\");\n            RemoveValue(\"nativeArray\");\n            RemoveValue(\"fill\");\n        }\n        #endregion\n\n        #region Arithmetic\n        [Benchmark(Description = \"Multiply all values of a managed array with a single value.\")]\n        [BenchmarkCategory(\"Arithmetic\")]\n        public void ArithmeticMutiplyManagedArray()\n        {\n            T mul = GetValue<T>(\"mul\");\n            T fill = GetValue<T>(\"fill\");\n            T[] m = GetValue<T[]>(\"managedArray\");\n            new Span<T>(m).Fill(fill);\n            for (int i = 0; i < m.Length; i++)\n            {\n                m[i] = GM<T>.Multiply(m[i], mul);\n            }\n            this.SetStatistic($\"{nameof(ArithmeticMutiplyManagedArray)}_PrivateMemory\", JemUtil.PrintBytes(JemUtil.ProcessPrivateMemory));\n        }\n\n        [Benchmark(Description = \"Vector multiply all values of a native array with a single value.\")]\n        [BenchmarkCategory(\"Arithmetic\")]\n        public void ArithmeticMultiplyNativeArray()\n        {\n            DebugInfoThis();\n            T mul = GetValue<T>(\"mul\");\n            T fill = GetValue<T>(\"fill\");\n            FixedBuffer<T> array = GetValue<FixedBuffer<T>>(\"nativeArray\");\n            array.Fill(fill);\n            array.VectorMultiply(mul);\n            this.SetStatistic($\"{nameof(ArithmeticMultiplyNativeArray)}_PrivateMemory\", JemUtil.PrintBytes(JemUtil.ProcessPrivateMemory));\n        }\n\n        [GlobalCleanup(Target = nameof(ArithmeticMultiplyNativeArray))]\n        public void ArithmeticMultiplyValidateAndCleanup()\n        {\n            InfoThis();\n            int index; \n            FixedBuffer<T> nativeArray = GetValue<FixedBuffer<T>>(\"nativeArray\");\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            T mul = GetValue<T>(\"mul\");\n            T fill = GetValue<T>(\"fill\");\n            T val = GM<T>.Multiply(fill, mul);\n            for (int i = 0; i < ArraySize % 100; i++)\n            {\n                index = GM<T>.Rng.Next(0, ArraySize);\n                if (!nativeArray[index].Equals(val))\n                {\n                    Log.WriteLineError($\"Native array at index {index} is {nativeArray[index]} not {val}.\");\n                    throw new Exception();\n                }\n                else if (!managedArray[index].Equals(val))\n                {\n                    Log.WriteLineError($\"Managed array at index {index} is {managedArray[index]} not {val}.\");\n                    throw new Exception();\n                }\n\n            }\n            managedArray = null;\n            nativeArray.Release();\n            nativeArray.Free();\n            RemoveValue(\"managedArray\");\n            RemoveValue(\"nativeArray\");\n            RemoveValue(\"fill\");\n            RemoveValue(\"mul\");\n        }\n        #endregion\n\n        #region Create\n        [BenchmarkCategory(\"Create\")]\n        [Benchmark(Description = \"Create arrays on the .NET LOH\", Baseline = true)]\n        public void CreateManagedArray()\n        {\n            T[] someData = new T[ArraySize];\n        }\n\n        [BenchmarkCategory(\"Create\")]\n        [Benchmark(Description = \"Create SafeArrays on the system unmanaged heap\")]\n        public void CreateNativeArray()\n        {\n            SafeArray<T> array = new SafeArray<T>(ArraySize);\n\n        }\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/Benchmarks/HugeNativeVsManagedArray.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Order;\n\nnamespace jemalloc.Benchmarks\n{\n    [OrderProvider(methodOrderPolicy: MethodOrderPolicy.Declared)]\n    public class HugeNativeVsManagedArrayBenchmark<T> : JemBenchmark<T, ulong> where T : struct, IEquatable<T>, IComparable<T>, IConvertible\n    {\n        public ulong ArraySize => Parameter;\n        public readonly int MaxManagedArraySize = 2146435071;\n        public T fill = typeof(T) == typeof(TestUDT) ? JemUtil.ValToGenericStruct<TestUDT, T>(TestUDT.MakeTestRecord(JemUtil.Rng)) : GM<T>.Random();\n        public (T factor, T max) mul = GM<T>.RandomMultiplyFactorAndValue();\n\n        \n        public override void GlobalSetup()\n        {\n            DebugInfoThis();\n            base.GlobalSetup();\n            Info($\"Unmanaged array size is {ArraySize}.\");\n            Info($\"Managed array size is {MaxManagedArraySize}.\");\n            T[] managedArray = new T[MaxManagedArraySize];\n            SetValue(\"managedArray\", managedArray);\n            HugeArray<T> hugeArray = new HugeArray<T>(ArraySize);\n            hugeArray.Acquire();\n            SetValue(\"hugeArray\", hugeArray);\n            if (Operation == Operation.FILL)\n            {\n                SetValue(\"fill\", fill);\n                Info($\"Array fill value is {fill}.\");\n                SetValue(\"fill\", fill);\n            }\n        }\n\n        #region Fill\n        [Benchmark(Description = \"Fill a managed array with the maximum size [2146435071] with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillManagedArray()\n        {\n            DebugInfoThis();\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            T fill = GetValue<T>(\"fill\");\n            for (int i = 0; i < managedArray.Length; i++)\n            {\n                managedArray[i] = fill;\n            }\n        }\n\n        [Benchmark(Description = \"Fill a HugeArray on the system unmanaged heap with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillHugeNativeArray()\n        {\n            DebugInfoThis();\n            HugeArray<T> hugeArray = GetValue<HugeArray<T>>(\"hugeArray\");\n            T fill = GetValue<T>(\"fill\");\n            hugeArray.Fill(fill);\n        }\n\n        [Benchmark(Description = \"Create and Fill a managed array with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillManagedArrayWithCreate()\n        {\n            DebugInfoThis();\n            T[] managedArray = new T[MaxManagedArraySize];\n            T fill = GetValue<T>(\"fill\");\n            for (int i = 0; i < managedArray.Length; i++)\n            {\n                managedArray[i] = fill;\n            }\n            managedArray = null;\n        }\n\n        [Benchmark(Description = \"Create and Fill a HugeArray on the system unmanaged heap with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillHugeNativeArrayWithCreate()\n        {\n            DebugInfoThis();\n            HugeArray<T> hugeArray = new HugeArray<T>(ArraySize);\n            T fill = GetValue<T>(\"fill\");\n            hugeArray.Fill(fill);\n            hugeArray.Close();\n            hugeArray = null;\n        }\n\n        [GlobalCleanup(Target = nameof(FillHugeNativeArray))]\n        public void CleanupFillArray()\n        {\n            InfoThis();\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            HugeArray<T> hugeArray = GetValue<HugeArray<T>>(\"hugeArray\");\n            T fill = GetValue<T>(\"fill\");\n            ulong index = GM<UInt64>.Random(ArraySize);\n            if (!hugeArray[index].Equals(fill))\n            {\n                Error($\"Native array at index {index} is {hugeArray[index]} not {fill}.\");\n                throw new Exception();\n            }\n            hugeArray.Release();\n            managedArray = null;\n            RemoveValue(\"managedArray\");\n            RemoveValue(\"hugeArray\");\n            RemoveValue(\"fill\");\n        }\n        #endregion\n\n        #region Create\n        [BenchmarkCategory(\"Create\")]\n        [Benchmark(Description = \"Create an array with the maximum size [2146435071] on the .NET managed heap\")]\n        public void CreateManagedArray()\n        {\n            T[] someData = new T[2146435071];\n        }\n\n        [BenchmarkCategory(\"Create\")]\n        [Benchmark(Description = \"Create a HugeArray on the system unmanaged heap\")]\n        public void CreateHugeNativeArray()\n        {\n            HugeArray<T> array = new HugeArray<T>(ArraySize);\n            array.Release();\n        }\n        #endregion\n\n\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/Benchmarks/MallocVsArray.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Runtime;\nusing System.Runtime.InteropServices;\n\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Order;\n\nnamespace jemalloc.Benchmarks\n{\n    [OrderProvider(methodOrderPolicy: MethodOrderPolicy.Declared)]\n    public class MallocVsArrayBenchmark<T> : JemBenchmark<T, int> where T : struct, IEquatable<T>, IComparable<T>, IConvertible\n    {\n        public int ArraySize => Parameter;\n        public const int InitialLargeBlockSize = 64 * 1024 * 1024; //64 MB\n        public const int SmallBlockSize = 90000;\n        public int LoopCount => Parameter;\n\n        \n        public override void GlobalSetup()\n        {\n            base.GlobalSetup();\n            Jem.Init(\"dirty_decay_ms:0,muzzy_decay_ms:0,junk:false,tcache:false\");\n        }\n\n        #region Create\n        [Benchmark(Description = \"Create array of data on the managed heap.\")]\n        [BenchmarkCategory(\"Create\")]\n        public void CreateManagedArray()\n        {\n            T[] someData = new T[ArraySize];\n            SetMemoryStatistics();\n            someData = null;\n         }\n\n        [Benchmark(Description = \"Malloc buffer and Span<T> on the system managed heap.\")]\n        [BenchmarkCategory(\"Create\")]\n        public void CreateSpan()\n        {\n            ulong msize = (ulong)(ArraySize * JemUtil.SizeOfStruct<T>());\n            IntPtr ptr = Jem.Malloc(msize);\n            unsafe\n            {\n                Span<T> s = new Span<T>(ptr.ToPointer(), ArraySize);\n            }\n            SetMemoryStatistics();\n            Jem.Free(ptr);\n        }\n        #endregion\n\n        #region Fill\n        [Benchmark(Description = \"Fill array of data on the managed heap.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillManagedArray()\n        {\n            T fill = GM<T>.Random();\n            T[] someData = new T[ArraySize];\n            for (int i = 0; i < someData.Length; i++)\n            {\n                someData[i] = fill;\n            }\n            T r = someData[ArraySize / 2];\n        }\n\n        [Benchmark(Description = \"Fill memory on the system unmanaged heap using Span<T> with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillSpan()\n        {\n            T fill = GM<T>.Random();\n            ulong msize = (ulong)(ArraySize * JemUtil.SizeOfStruct<T>());\n            IntPtr ptr = Jem.Malloc(msize);\n            Span<T> s = JemUtil.PtrToSpan<T>(ptr, ArraySize);\n            s.Fill(fill);\n            T r = s[ArraySize / 2];\n            Jem.Free(ptr);\n        }\n        #endregion\n\n        #region Fragment\n        [Benchmark(Description = \"Run an allocation pattern that won't fragment the Large Object Heap.\", Baseline = true)]\n        [BenchmarkCategory(\"Managed\", \"Fragment\")]\n        public void FragmentLOHBaseline()\n        {\n            int largeBlockSize = InitialLargeBlockSize;\n            int i = 0;\n            try\n            {\n                for (i = 0; i < LoopCount; i++)\n                {\n                    T[] bigBlock = new T[largeBlockSize];\n                    T[] smallBlock = new T[SmallBlockSize];\n                    largeBlockSize = largeBlockSize + (1 * 1024 * 1024);\n                }\n                this.SetStatistic($\"{nameof(FragmentLOHBaseline)}_WorkingSet\", JemUtil.PrintBytes(JemUtil.ProcessWorkingSet));\n                this.SetStatistic($\"{nameof(FragmentLOHBaseline)}_JemResident\", JemUtil.PrintBytes(Jem.ResidentBytes));\n                this.SetStatistic($\"{nameof(FragmentLOHBaseline)}_PrivateMemory\", JemUtil.PrintBytes(JemUtil.ProcessPrivateMemory));\n                this.SetStatistic($\"{nameof(FragmentLOHBaseline)}_JemAllocated\", JemUtil.PrintBytes(Jem.AllocatedBytes));\n            }\n            catch (OutOfMemoryException)\n            {\n                Error($\"OOM at index {i}.\");\n                throw;\n            }\n            finally\n            {\n                GC.Collect();\n            }\n        }\n\n        [Benchmark(Description = \"Run an allocation pattern that fragments the Large Object Heap.\")]\n        [BenchmarkCategory(\"Managed\", \"Fragment\")]\n        public void FragmentLOH()\n        {\n            int largeBlockSize = InitialLargeBlockSize;\n            List<T[]> smallBlocks = new List<T[]>();\n            int i = 0;\n            try\n            {\n                for (i = 0; i < LoopCount; i++)\n                {\n                    T[] bigBlock = new T[largeBlockSize];\n                    T[] smallBlock = new T[SmallBlockSize];\n                    smallBlocks.Add(smallBlock);\n                    largeBlockSize = largeBlockSize + (1 * 1024 * 1024);\n\n                }\n                this.SetStatistic($\"{nameof(FragmentLOH)}_WorkingSet\", JemUtil.PrintBytes(JemUtil.ProcessWorkingSet));\n                this.SetStatistic($\"{nameof(FragmentLOH)}_JemResident\", JemUtil.PrintBytes(Jem.ResidentBytes));\n                this.SetStatistic($\"{nameof(FragmentLOH)}_PrivateMemory\", JemUtil.PrintBytes(JemUtil.ProcessPrivateMemory));\n                this.SetStatistic($\"{nameof(FragmentLOH)}_JemAllocated\", JemUtil.PrintBytes(Jem.AllocatedBytes));\n\n            }\n            catch (OutOfMemoryException)\n            {\n                Error($\"OOM at index {i}.\");\n                throw;\n            }\n            finally\n            {\n                smallBlocks = null;\n                GC.Collect();\n            }\n        }\n\n        [Benchmark(Description = \"Run an allocation pattern that fragments the Large Object Heap with regular GC compaction.\")]\n        [BenchmarkCategory(\"Managed\", \"Fragment\")]\n        public void FragmentLOHWithCompact()\n        {\n            int largeBlockSize = InitialLargeBlockSize;\n            List<T[]> smallBlocks = new List<T[]>();\n            int i = 0;\n            try\n            {\n                for (i = 0; i < LoopCount; i++)\n                {\n                    if ((i + 1)% 10 == 0)\n                    {\n                        //Info(\"Compacting LOH.\");\n                        GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;\n                        GC.Collect();\n                    }\n                    T[] bigBlock = new T[largeBlockSize];\n                    T[] smallBlock = new T[SmallBlockSize];\n                    smallBlocks.Add(smallBlock);\n                    largeBlockSize = largeBlockSize + (1 * 1024 * 1024);\n                }\n                this.SetStatistic($\"{nameof(FragmentLOHWithCompact)}_WorkingSet\", JemUtil.PrintBytes(JemUtil.ProcessWorkingSet));\n                this.SetStatistic($\"{nameof(FragmentLOHWithCompact)}_JemResident\", JemUtil.PrintBytes(Jem.ResidentBytes));\n                this.SetStatistic($\"{nameof(FragmentLOHWithCompact)}_PrivateMemory\", JemUtil.PrintBytes(JemUtil.ProcessPrivateMemory));\n                this.SetStatistic($\"{nameof(FragmentLOHWithCompact)}_JemAllocated\", JemUtil.PrintBytes(Jem.AllocatedBytes));\n\n            }\n            catch (OutOfMemoryException)\n            {\n                Error($\"OOM at index {i}.\");\n                throw; \n            }\n            finally\n            {\n                smallBlocks = null;\n                GC.Collect();\n            }\n        }\n\n        [Benchmark(Description = \"Run an allocation pattern that won't fragment the unmanaged heap.\")]\n        [BenchmarkCategory(\"Unmanaged\", \"Fragment\")]\n        public void FragmentNativeHeapBaseline()\n        {\n\n            Info($\"Dirty decay time: {Jem.GetMallCtlSInt64(\"arenas.dirty_decay_ms\")} ms\");\n            int largeBlockSize = InitialLargeBlockSize;\n            int i = 0;\n            FixedBuffer<T> bigBlock = default;\n            try\n            {\n                for (i = 0; i < LoopCount; i++)\n                {\n                    bigBlock = new FixedBuffer<T>(largeBlockSize);\n                    FixedBuffer<T> smallBlock = new FixedBuffer<T>(SmallBlockSize);\n                    int j = JemUtil.Rng.Next(0, ArraySize);\n                    T r = GM<T>.Random();\n                    smallBlock[j] = r;\n                    if (!smallBlock[j].Equals(r))\n                    {\n                        throw new Exception($\"Cannot validate small block at index {i}.\");\n                    }\n                    if (!smallBlock.Free()) throw new Exception(\"Cannot free smallBlock.\");\n                    if (!bigBlock.Free()) throw new Exception(\"Cannot free bigBlock.\");\n                    largeBlockSize = largeBlockSize + (1 * 1024 * 1024);\n                }\n                this.SetStatistic($\"{nameof(FragmentNativeHeapBaseline)}_WorkingSet\", JemUtil.PrintBytes(JemUtil.ProcessWorkingSet));\n                this.SetStatistic($\"{nameof(FragmentNativeHeapBaseline)}_JemResident\", JemUtil.PrintBytes(Jem.ResidentBytes));\n                this.SetStatistic($\"{nameof(FragmentNativeHeapBaseline)}_PrivateMemory\", JemUtil.PrintBytes(JemUtil.ProcessPrivateMemory));\n                this.SetStatistic($\"{nameof(FragmentNativeHeapBaseline)}_JemAllocated\", JemUtil.PrintBytes(Jem.AllocatedBytes));\n\n            }\n            catch (OutOfMemoryException)\n            {\n                Info(Jem.MallocStats);\n                Error($\"Out-of-Memory at index {i} with large block size {largeBlockSize}.\");\n                throw;\n            }\n            finally\n            {\n                GC.Collect();\n            }\n        }\n\n        [Benchmark(Description = \"Run an allocation pattern that fragments the unmanaged heap.\")]\n        [BenchmarkCategory(\"Unmanaged\", \"Fragment\")]\n        public void FragmentNativeHeap()\n        {\n\n            Info($\"Dirty decay time: {Jem.GetMallCtlSInt64(\"arenas.dirty_decay_ms\")} ms\");\n            int largeBlockSize = InitialLargeBlockSize;\n            SafeArray<FixedBuffer<T>> smallBlocks = new SafeArray<FixedBuffer<T>>(LoopCount);\n            int i = 0;\n            FixedBuffer<T> bigBlock = default;\n            try\n            {\n                for (i = 0; i < LoopCount; i++)\n                {\n                    bigBlock = new FixedBuffer<T>(largeBlockSize);\n                    FixedBuffer<T> smallBlock = new FixedBuffer<T>(SmallBlockSize);\n                    int j = JemUtil.Rng.Next(0, ArraySize); \n                    T r = GM<T>.Random();\n                    smallBlock[j] = r;\n                    smallBlocks[i] = smallBlock;\n                    if (!smallBlocks[i][j].Equals(r))\n                    {\n                        throw new Exception($\"Cannot validate small block at index {i}.\");\n                    }\n                    if (!bigBlock.Free()) throw new Exception(\"Cannot free bigBlock.\");\n                    largeBlockSize = largeBlockSize + (1 * 1024 * 1024);\n                }\n                this.SetStatistic($\"{nameof(FragmentNativeHeap)}_WorkingSet\", JemUtil.PrintBytes(JemUtil.ProcessWorkingSet));\n                this.SetStatistic($\"{nameof(FragmentNativeHeap)}_JemResident\", JemUtil.PrintBytes(Jem.ResidentBytes));\n                this.SetStatistic($\"{nameof(FragmentNativeHeap)}_PrivateMemory\", JemUtil.PrintBytes(JemUtil.ProcessPrivateMemory));\n                this.SetStatistic($\"{nameof(FragmentNativeHeap)}_JemAllocated\", JemUtil.PrintBytes(Jem.AllocatedBytes));\n                foreach (FixedBuffer<T> b in smallBlocks)\n                {\n                    if (!b.Free()) throw new Exception($\"Cannot free small block at index {i}.\");\n\n                }\n            }\n            catch (OutOfMemoryException)\n            {\n                Info(Jem.MallocStats);\n                Error($\"Out-of-Memory at index {i} with large block size {largeBlockSize}.\");\n                foreach (FixedBuffer<T> b in smallBlocks)\n                {\n                    b.Free();\n                }\n                throw;\n            }\n            finally\n            {\n                GC.Collect();\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/Benchmarks/SafeVsManagedArray.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\nusing System.Threading;\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Loggers;\n\nnamespace jemalloc.Benchmarks\n{\n    [OrderProvider(methodOrderPolicy: MethodOrderPolicy.Declared)]\n    public class SafeVsManagedArrayBenchmark<T> : JemBenchmark<T, int> where T : struct, IEquatable<T>, IComparable<T>, IConvertible\n    {\n        public int ArraySize  => Parameter;\n        public readonly T fill = typeof(T) == typeof(TestUDT) ? JemUtil.ValToGenericStruct<TestUDT, T>(TestUDT.MakeTestRecord(JemUtil.Rng)) : GM<T>.Random();\n        public readonly (T factor, T max) mul = GM<T>.RandomMultiplyFactorAndValue();\n\n        public override void GlobalSetup()\n        {\n            DebugInfoThis();\n            base.GlobalSetup();\n            Info($\"Array size is {ArraySize}.\");\n            T[] managedArray = new T[ArraySize];\n            SetValue(\"managedArray\", managedArray);\n            SafeArray<T> nativeArray = new SafeArray<T>(ArraySize);\n            SetValue(\"nativeArray\", nativeArray);\n            if (Operation == Operation.FILL)\n            {\n                Info($\"Array fill value is {fill}.\");\n                SetValue(\"fill\", fill);\n            }\n            else if (Operation == Operation.MATH)\n            {\n                Info($\"Array fill value is {mul.max}.\");\n                nativeArray.Fill(mul.max);\n                new Span<T>(managedArray).Fill(mul.max);\n                SetValue(\"fill\", mul.max);\n                Info($\"Array multiply factor is {mul.factor}.\");\n                SetValue(\"mul\", mul.factor);\n            }\n          }\n\n        #region Fill      \n        [Benchmark(Description = \"Fill a managed array with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillManagedArray()\n        {\n            DebugInfoThis();\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            T fill = GetValue<T>(\"fill\");\n            for (int i = 0; i < managedArray.Length; i++)\n            {\n                managedArray[i] = fill;\n            }\n        }\n\n        [Benchmark(Description = \"Fill a SafeArray on the system unmanaged heap with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillNativeArray()\n        {\n            DebugInfoThis();\n            SafeArray<T> nativeArray = GetValue<SafeArray<T>>(\"nativeArray\");\n            T fill = GetValue<T>(\"fill\");\n            nativeArray.Fill(fill);\n        }\n\n        [Benchmark(Description = \"Create and Fill a managed array with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillManagedArrayWithCreate()\n        {\n            DebugInfoThis();\n            T[] managedArray = new T[ArraySize];\n            T fill = GetValue<T>(\"fill\");\n            for (int i = 0; i < managedArray.Length; i++)\n            {\n                managedArray[i] = fill;\n            }\n            managedArray = null;\n        }\n\n        [Benchmark(Description = \"Create and Fill a SafeArray on the system unmanaged heap with a single value.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillNativeArrayWithCreate()\n        {\n            DebugInfoThis();\n            SafeArray<T> nativeArray = new SafeArray<T>(ArraySize);\n            T fill = GetValue<T>(\"fill\");\n            nativeArray.Fill(fill);\n            nativeArray.Close();\n        }\n\n        [GlobalCleanup(Target = nameof(FillNativeArrayWithCreate))]\n        public void FillArrayValidateAndCleanup()\n        {\n            InfoThis();\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            SafeArray<T> nativeArray = GetValue<SafeArray<T>>(\"nativeArray\");\n            T fill = GetValue<T>(\"fill\");\n            int index = JemUtil.Rng.Next(0, ArraySize);\n            if (!nativeArray[index].Equals(managedArray[index]))\n            {\n                Log.WriteLineError($\"Native array at index {index} is {nativeArray[index]} not {fill}.\");\n                throw new Exception();\n            }\n            managedArray = null;\n            nativeArray.Close();\n            RemoveValue(\"managedArray\");\n            RemoveValue(\"nativeArray\");\n            RemoveValue(\"fill\");\n        }\n        #endregion\n\n        #region Arithmetic\n        [Benchmark(Description = \"Multiply all values of a managed array with a single value.\")]\n        [BenchmarkCategory(\"Arithmetic\")]\n        public void ArithmeticMutiplyManagedArray()\n        {\n            T mul = GetValue<T>(\"mul\");\n            T fill = GetValue<T>(\"fill\");\n            T[] m = GetValue<T[]>(\"managedArray\");\n            new Span<T>(m).Fill(fill);\n            for (int i = 0; i < m.Length; i++)\n            {\n                m[i] = GM<T>.Multiply(m[i], mul);\n            }\n        }\n\n        [Benchmark(Description = \"Vector multiply all values of a native array with a single value.\")]\n        [BenchmarkCategory(\"Arithmetic\")]\n        public void ArithmeticMultiplyNativeArray()\n        {\n            T mul = GetValue<T>(\"mul\");\n            T fill = GetValue<T>(\"fill\");\n            SafeArray<T> array = GetValue<SafeArray<T>>(\"nativeArray\");\n            array.Fill(fill);\n            array.VectorMultiply(mul);          \n        }\n\n        [GlobalCleanup(Target = nameof(ArithmeticMultiplyNativeArray))]\n        public void ArithmeticMultiplyValidateAndCleanup()\n        {\n            InfoThis();\n            int index = GM<T>.Rng.Next(0, ArraySize);\n            SafeArray<T> nativeArray = GetValue<SafeArray<T>>(\"nativeArray\");\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            T mul = GetValue<T>(\"mul\");\n            T fill = GetValue<T>(\"fill\");\n            T val = GM<T>.Multiply(fill, mul);\n            if (!nativeArray[index].Equals(val))\n            {\n                Log.WriteLineError($\"Native array at index {index} is {nativeArray[index]} not {val}.\");\n                throw new Exception();\n            }\n            else if (!managedArray[index].Equals(val))\n            {\n                Log.WriteLineError($\"Managed array at index {index} is {managedArray[index]} not {val}.\");\n                throw new Exception();\n            }\n            managedArray = null;\n            nativeArray.Close();\n            RemoveValue(\"managedArray\");\n            RemoveValue(\"nativeArray\");\n            RemoveValue(\"fill\");\n            RemoveValue(\"mul\");\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/Benchmarks/Vector.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\nusing System.Text;\n\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Diagnosers;\n\n\nnamespace jemalloc.Benchmarks\n{\n    [OrderProvider(methodOrderPolicy: MethodOrderPolicy.Declared)]\n    public class VectorBenchmark<T> : JemBenchmark<T, int> where T : struct, IEquatable<T>, IComparable<T>, IConvertible\n    {\n        private const int _Mandelbrot_Width = 768, _Mandelbrot_Height = 512;\n\n        public int ArraySize => Parameter;\n        public int Scale => Parameter;\n\n\n        public int Mandelbrot_Width => _Mandelbrot_Width * Scale;\n        public int Mandelbrot_Height => _Mandelbrot_Height * Scale;\n        public int MandelbrotArraySize => Mandelbrot_Width * Mandelbrot_Height;\n\n        readonly Vector<int> One = Vector<int>.One;\n        readonly Vector<int> Zero = Vector<int>.Zero;\n        readonly Vector<float> Limit = new Vector<float>(4);\n\n        #region Mandelbrot\n        [GlobalSetup(Target = nameof(MandelbrotManaged))]\n        public void MandelbrotSetup()\n        {\n            byte[] managedArray = new byte[MandelbrotArraySize];\n            SetValue(\"managedArray\", managedArray);\n            int[] managed3Array = new int[MandelbrotArraySize];\n            SetValue(\"managed3Array\", managed3Array);\n            int[] managed5Array = new int[MandelbrotArraySize];\n            SetValue(\"managed5Array\", managed5Array);\n            int[] managed7Array = new int[MandelbrotArraySize];\n            SetValue(\"managed7Array\", managed5Array);\n            FixedBuffer<byte> nativeArray = new FixedBuffer<byte>(MandelbrotArraySize);\n            SetValue(\"nativeArray\", nativeArray);\n            FixedBuffer<int> native2Array = new FixedBuffer<int>(MandelbrotArraySize);\n            SetValue(\"native2Array\", native2Array);\n            FixedBuffer<int> native3Array = new FixedBuffer<int>(MandelbrotArraySize);\n            SetValue(\"native3Array\", native3Array);\n            FixedBuffer<int> native4Array = new FixedBuffer<int>(MandelbrotArraySize);\n            SetValue(\"native4Array\", native4Array);\n            FixedBuffer<int> native5Array = new FixedBuffer<int>(MandelbrotArraySize);\n            SetValue(\"native5Array\", native4Array);\n        }\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap single-threaded serial using managed memory v1.\", Baseline = true)]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotManaged()\n        {\n            byte[] managedArray = GetValue<byte[]>(\"managedArray\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotManagedv1(ref managedArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCResult());\n            SetStatistic($\"ISPCResult2\", GetISPCResult2());\n        }\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap single-threaded serial using unmanaged memory v1.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotUnmanagedv1()\n        {\n            FixedBuffer<byte> nativeArray = GetValue<FixedBuffer<byte>>(\"nativeArray\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotUnmanagedv1(ref nativeArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCResult());\n            SetStatistic($\"ISPCResult2\", GetISPCResult2());\n        }\n        /*Not working\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap single-threaded linear.\", Baseline = true)]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotManagedv0()\n        {\n            byte[] managedArray = GetValue<byte[]>(\"managed0Array\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotManagedv0(ref managedArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"{nameof(MandelbrotManagedv0)}_ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"{nameof(MandelbrotManagedv0)}_ISPCResult\", GetISPCResult());\n        }\n        */\n\n        /*\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap with dimensions 768 x 512 single-threaded using managed memory vBGNetCore8.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotManagedv2()\n        { \n            uulong start = JemUtil.GetCurrentThreadCycles();\n            byte[] managedArray = _MandelbrotManagedv2();\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetValue(\"managed2Array\", managedArray);\n            SetStatistic($\"{nameof(MandelbrotManagedv2)}_ThreadCycles\", JemUtil.PrintSize(end - start));\n        }\n        */\n\n\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap multi-threaded using managed memory v4.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotManagedv4()\n        {\n\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            int[] managedArray = _MandelbrotManagedv4();\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetValue(\"managed4Array\", managedArray);\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCTasksResult());\n            SetStatistic($\"ISPCResult2\", GetISPCTasksResult2());\n        }\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap single-threaded using unmanaged memory v2.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotUnmanagedv2()\n        {\n            FixedBuffer<int> nativeArray = GetValue<FixedBuffer<int>>(\"native2Array\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotUnmanagedv2(ref nativeArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCResult());\n            SetStatistic($\"ISPCResult2\", GetISPCResult2());\n        }\n\n\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap single-threaded using managed memory v5.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public void MandelbrotManagedv5()\n        {\n            int[] managedArray = GetValue<int[]>(\"managed5Array\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotManagedv5(ref managedArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCResult());\n            SetStatistic($\"ISPCResult2\", GetISPCResult2());\n        }\n\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap single-threaded using managed memory v3.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotManagedv3()\n        {\n            int[] managedArray = GetValue<int[]>(\"managed3Array\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotManagedv3(ref managedArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCResult());\n            SetStatistic($\"ISPCResult2\", GetISPCResult2());\n        }\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap multi-threaded using managed memory v6.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public void MandelbrotManagedv6()\n        {\n\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            int[] managedArray = _MandelbrotManagedv6();\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetValue(\"managed6Array\", managedArray);\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCTasksResult());\n            SetStatistic($\"ISPCResult2\", GetISPCTasksResult2());\n        }\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap single-threaded using managed memory v7.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public void MandelbrotManagedv7()\n        {\n            int[] managedArray = GetValue<int[]>(\"managed7Array\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotManagedv7(ref managedArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCResult());\n            SetStatistic($\"ISPCResult2\", GetISPCResult2());\n        }\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap multi-threaded using managed memory v8.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public void MandelbrotManagedv8()\n        {\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            int[] managedArray = _MandelbrotManagedv8();\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetValue(\"managed8Array\", managedArray);\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCTasksResult());\n            SetStatistic($\"ISPCResult2\", GetISPCTasksResult2());\n        }\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap single-threaded using unmanaged memory v3.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotUnmanagedv3()\n        {\n            FixedBuffer<int> nativeArray = GetValue<FixedBuffer<int>>(\"native3Array\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotUnmanagedv3(ref nativeArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCResult());\n            SetStatistic($\"ISPCResult2\", GetISPCResult2());\n        }\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap single-threaded using unmanaged memory v5.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotUnmanagedv5()\n        {\n            FixedBuffer<int> nativeArray = GetValue<FixedBuffer<int>>(\"native5Array\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotUnmanagedv5(ref nativeArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCResult());\n            SetStatistic($\"ISPCResult2\", GetISPCResult2());\n        }\n\n        [Benchmark(Description = \"Create Mandelbrot plot bitmap multi-threaded using unmanaged memory v4.\")]\n        [BenchmarkCategory(\"Mandelbrot\")]\n        public unsafe void MandelbrotUnmanagedv4()\n        {\n            FixedBuffer<int> nativeArray = GetValue<FixedBuffer<int>>(\"native4Array\");\n            ulong start = JemUtil.GetCurrentThreadCycles();\n            _MandelbrotUnmanagedv4(nativeArray);\n            ulong end = JemUtil.GetCurrentThreadCycles();\n            SetStatistic($\"ThreadCycles\", JemUtil.PrintSize(end - start));\n            SetStatistic($\"ISPCResult\", GetISPCTasksResult());\n            SetStatistic($\"ISPCResult2\", GetISPCTasksResult2());\n        }\n\n\n        [GlobalCleanup(Target = nameof(MandelbrotUnmanagedv4))]\n        public void MandelbrotValidateAndCleanup()\n        {\n            byte[] managedArray = GetValue<byte[]>(\"managedArray\");\n            //byte[] managed2Array = GetValue<byte[]>(\"managed2Array\");\n            int[] managed3Array = GetValue<int[]>(\"managed3Array\");\n            int[] managed4Array = GetValue<int[]>(\"managed4Array\");\n            int[] managed5Array = GetValue<int[]>(\"managed5Array\");\n            int[] managed6Array = GetValue<int[]>(\"managed6Array\");\n            int[] managed7Array = GetValue<int[]>(\"managed7Array\");\n            int[] managed8Array = GetValue<int[]>(\"managed8Array\");\n            FixedBuffer<byte> nativeArray = GetValue<FixedBuffer<byte>>(\"nativeArray\");\n            FixedBuffer<int> native2Array = GetValue<FixedBuffer<int>>(\"native2Array\");\n            FixedBuffer<int> native3Array = GetValue<FixedBuffer<int>>(\"native3Array\");\n            FixedBuffer<int> native4Array = GetValue<FixedBuffer<int>>(\"native4Array\");\n            FixedBuffer<int> native5Array = GetValue<FixedBuffer<int>>(\"native5Array\");\n\n            for (int i = 0; i < MandelbrotArraySize; i++)\n            {\n                if (!nativeArray[i].Equals(managedArray[i]))\n                {\n                    Error($\"Native array at index {i} is {nativeArray[i]} not {managedArray[i]}.\");\n                    throw new Exception();\n                }\n                \n                if (native2Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals((byte)native2Array[i]))\n                    {\n                        Error($\"Native array 2 at index {i} is {native2Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n                \n                if (native3Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals((byte)native3Array[i]))\n                    {\n                        Error($\"Native array 3 at index {i} is {native3Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n\n                if (native4Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals((byte)native4Array[i]))\n                    {\n                        Error($\"Native array 4 at index {i} is {native4Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n\n                if (native5Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals((byte)native5Array[i]))\n                    {\n                        Error($\"Native array 5 at index {i} is {native5Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n\n                /*\n                if (!managedArray[i].Equals(managed2Array[i]))\n                {\n                    Error($\"Managed2 array at index {i} is {managed2Array[i]} not {managedArray[i]}.\");\n                    throw new Exception();\n                }\n                */\n                if (managed3Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals((byte) managed3Array[i]))\n                    {\n                        Error($\"Managed3 array at index {i} is {managed3Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n                \n                if (managed4Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals((byte) managed4Array[i]))\n                    {\n                        Error($\"Managed4 array at index {i} is {managed4Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n\n                \n                if (managed5Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals( (byte) managed5Array[i]))\n                    {\n                        Error($\"Managed5 array at index {i} is {managed5Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n\n                if (managed6Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals((byte)managed6Array[i]))\n                    {\n                        Error($\"Managed6 array at index {i} is {managed6Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n\n                if (managed7Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals((byte)managed7Array[i]))\n                    {\n                        Error($\"Managed7 array at index {i} is {managed7Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n\n                if (managed8Array[i] <= 255)\n                {\n                    if (!managedArray[i].Equals((byte)managed8Array[i]))\n                    {\n                        Error($\"Managed8 array at index {i} is {managed8Array[i]} not {managedArray[i]}.\");\n                        throw new Exception();\n                    }\n                }\n\n            }\n            WriteMandelbrotPPM(managedArray, \"mandelbrot-managed-v1.ppm\");\n            //WriteMandelbrotPPM(managed0Array, \"mandelbrot-managed-v0.ppm\");\n            //WriteMandelbrotPPM(managed2Array, \"mandelbrot-managed2.ppm\");\n            WriteMandelbrotPPM(managed3Array, \"mandelbrot-managed-v3.ppm\");\n            WriteMandelbrotPPM(managed4Array, \"mandelbrot-managed-v4.ppm\");\n            WriteMandelbrotPPM(managed5Array, \"mandelbrot-managed-v5.ppm\");\n            WriteMandelbrotPPM(managed6Array, \"mandelbrot-managed-v6.ppm\");\n            WriteMandelbrotPPM(managed7Array, \"mandelbrot-managed-v7.ppm\");\n            WriteMandelbrotPPM(managed8Array, \"mandelbrot-managed-v8.ppm\");\n            WriteMandelbrotPPM(nativeArray.AcquireSpan(), \"mandelbrot-unmanaged-v1.ppm\");\n            WriteMandelbrotPPM(native2Array.AcquireSpan(), \"mandelbrot-unmanaged-v2.ppm\");\n            WriteMandelbrotPPM(native3Array.AcquireSpan(), \"mandelbrot-unmanaged-v3.ppm\");\n            WriteMandelbrotPPM(native4Array.AcquireSpan(), \"mandelbrot-unmanaged-v4.ppm\");\n            WriteMandelbrotPPM(native5Array.AcquireSpan(), \"mandelbrot-unmanaged-v4.ppm\");\n            nativeArray.Release();\n            native2Array.Release();\n            native3Array.Release();\n            native4Array.Release();\n            native5Array.Release();\n        }\n        #endregion\n\n        #region Fill\n        [GlobalSetup(Target = nameof(FillManagedArray))]\n        public void _FillGlobalSetup()\n        {\n            Info(\"Vector width is {0}.\", Vector<T>.Count);\n            T[] mArray = new T[ArraySize];\n            SetValue(\"managedArray\", mArray);\n            FixedBuffer<T> nativeArray = new FixedBuffer<T>(ArraySize);\n            SetValue(\"nativeArray\", nativeArray);\n            T fill = GM<T>.Random();\n            SetValue(\"fill\", fill);\n            Info(\"Fill value is {0}.\", fill);\n        }\n\n        [Benchmark(Description = \"Serial fill managed memory array.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillManagedArray()\n        {\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            Array.Fill(managedArray, GetValue<T>(\"fill\"));\n        }\n\n        [Benchmark(Description = \"Vector fill managed memory array.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillManagedArrayUsingVector()\n        {\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            Span<Vector<T>> s = new Span<T>(managedArray).NonPortableCast<T, Vector<T>>();\n            Vector<T> fill = new Vector<T>(GetValue<T>(\"fill\"));\n            for (int i = 0; i < s.Length; i ++)\n            {\n                s[i] = fill;\n            }\n        }\n\n        [Benchmark(Description = \"Vector fill unmanaged memory array.\")]\n        [BenchmarkCategory(\"Fill\")]\n        public void FillUnmanagedArray()\n        {\n            FixedBuffer<T> nativeBuffer = GetValue<FixedBuffer<T>>(\"nativeArray\");\n            nativeBuffer.VectorFill(GetValue<T>(\"fill\"));\n        }\n\n\n        [GlobalCleanup(Target = nameof(FillUnmanagedArray))]\n        public void _FillGlobalValidateAndCleanup()\n        {\n            FixedBuffer<T> nativeBuffer = GetValue<FixedBuffer<T>>(\"nativeArray\");\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            for (int i =0; i < managedArray.Length; i++)           \n            if (!managedArray[i].Equals(nativeBuffer[i]))\n            {\n                throw new Exception($\"Native array at index {i} is {nativeBuffer[i]} not {managedArray[i]}.\");\n            }\n        }\n        #endregion\n\n        #region Test\n        [GlobalSetup(Target = nameof(TestManagedArrayLessThan))]\n        public void TestGlobalSetup()\n        {\n            Info(\"Vector width is {0}.\", Vector<T>.Count);\n            T[] mArray = new T[ArraySize];\n            SetValue(\"managedArray\", mArray);\n            FixedBuffer<T> nativeArray = new FixedBuffer<T>(ArraySize);\n            SetValue(\"nativeArray\", nativeArray);\n            for (int i = 0; i < ArraySize / 100; i++)\n            {\n                mArray[i] = GM<T>.Random();\n                nativeArray[i] = mArray[i];\n            }\n            SetValue(\"cmp\", GM<T>.Random());\n        }\n\n        [Benchmark(Description = \"Serial test managed memory array less than.\")]\n        [BenchmarkCategory(\"Test\")]\n        public void TestManagedArrayLessThan()\n        {\n            T cmp = GetValue<T>(\"cmp\");\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            int lessThanResult = Array.FindIndex(managedArray, (a) => a.CompareTo(cmp) >= 0);\n            SetValue(\"managedLessThanResult\", lessThanResult);\n        }\n\n        [Benchmark(Description = \"Vector test managed memory array less than.\")]\n        [BenchmarkCategory(\"Test\")]\n        public void TestVectorManagedArrayLessThan()\n        {\n            int lessThanResult = -1;\n            int c = JemUtil.VectorLength<T>();\n            int i;\n            T cmp = GetValue<T>(\"cmp\");\n            T[] managedArray = GetValue<T[]>(\"managedArray\");\n            Vector<T> O = Vector<T>.One;\n            Vector<T> _cmp = new Vector<T>(cmp);\n            for (i = 0; i < managedArray.Length - c; i+= c)\n            {\n                Vector<T> v = new Vector<T>(managedArray, i);\n                Vector<T> vcmp = Vector.LessThan(v, _cmp);\n                if (vcmp == O)\n                {\n                    continue;\n                }\n                else\n                {\n                    for (int j = 0; j < c; j++)\n                    {\n                        if (vcmp[j].Equals(default))\n                        {\n                            lessThanResult = i + j;\n                            break;\n                        }\n                    }\n                    break;\n                }\n            }\n            for (; i < c; ++i)\n            {\n                if (managedArray[i].CompareTo(cmp) >= 0)\n                {\n                    lessThanResult = i;\n                    break;\n                }\n            }\n            SetValue(\"managedVectorLessThanResult\", lessThanResult);\n        }\n\n        [Benchmark(Description = \"Vector test native array less than.\")]\n        [BenchmarkCategory(\"Test\")]\n        public void TestNativeArrayLessThan()\n        {\n            FixedBuffer<T> nativeArray = GetValue<FixedBuffer<T>>(\"nativeArray\");\n            T cmp = GetValue<T>(\"cmp\");\n            nativeArray.VectorLessThanAll(cmp, out int lessThanResult);\n            SetValue(\"nativeLessThanResult\", lessThanResult);\n        }\n\n   \n        [GlobalCleanup(Target = nameof(TestNativeArrayLessThan))]\n        public void _TestGlobalValidateAndCleanup()\n        {\n            var m = GetValue<int>(\"managedLessThanResult\");\n            var mv = GetValue<int>(\"managedVectorLessThanResult\");\n            var n = GetValue<int>(\"nativeLessThanResult\");\n            Info(\"{0}, {1}, {2}\", m, n, mv);\n            \n            if (m != mv)\n            {\n                Error(\"{0}, {1}\", m, mv);\n                throw new Exception();\n            }\n            else if (n != mv)\n            {\n                Error(\"{0}, {1}\", mv, n);\n                throw new Exception();\n            }\n            \n            if (m != n)\n            {\n                Error(\"{0}, {1}\", m, n);\n                throw new Exception();\n            }\n \n        }\n        #endregion\n\n        #region Implementations\n        int VectorWidth = Vector<float>.Count;\n\n        private byte[] _MandelbrotManagedv0(ref byte[] output)\n        {\n            float[] B = new float[2] { Mandelbrot_Width, Mandelbrot_Height };\n            float[] C0 = new float[2] { -2, -1 };\n            float[] C1 = new float[2] { 1, 1 };\n            float[] D = new float[2] { (C1[0] - C0[0]) / B[0], (C1[1] - C0[1]) / B[1] };\n            float[] V = new float[2];\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i++)\n                {\n                  \n                    index = unchecked(j * Mandelbrot_Width + i);\n                    V[0] = C0[0] + (i * D[0]);\n                    V[1] = C0[1] + (j * D[1]);\n                    output[index] = GetByte(V, 256);\n                }\n            }\n            return output;\n        }\n\n        private byte[] _MandelbrotManagedv1(ref byte[] output)\n        {\n            Vector2 B = new Vector2(Mandelbrot_Width, Mandelbrot_Height);\n            Vector2 C0 = new Vector2(-2, -1);\n            Vector2 C1 = new Vector2(1, 1);\n            Vector2 D = (C1 - C0) / B;\n\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i++)\n                {\n                    Vector2 P = new Vector2(i, j);\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector2 V = C0 + (P * D);\n                    output[index] = GetByte(V, 256);\n                }\n            }\n            return output;\n\n            byte GetByte(Vector2 c, int count)\n            {\n                Vector2 z = c;\n                int i;\n                for (i = 0; i < count; i++)\n                {\n                    if (z.LengthSquared() > 4f)\n                    {\n                        return (byte)i;\n                    }\n                    Vector2 w = z * z;\n                    z = c + new Vector2(w.X - w.Y, 2f * z.X * z.Y);\n                }\n                return (byte)(i - 1);\n            }\n\n        }\n\n        private unsafe byte[] _MandelbrotManagedv2()\n        {\n            var size = Mandelbrot_Width;\n            var Crb = new double[size + 2];\n            var lineLength = size >> 3;\n            var data = new byte[size * lineLength];\n            fixed (double* pCrb = &Crb[0])\n            fixed (byte* pdata = &data[0])\n            {\n                var value = new Vector<double>(\n                      new double[] { 0, 1, 0, 0, 0, 0, 0, 0 }\n                );\n                var invN = new Vector<double>(2.0 / size);\n                var onePtFive = new Vector<double>(1.5);\n                var step = new Vector<double>(2);\n                for (var i = 0; i < size; i += 2)\n                {\n                    Unsafe.Write(pCrb + i, value * invN - onePtFive);\n                    value += step;\n                }\n                var _Crb = pCrb;\n                var _pdata = pdata;\n                Parallel.For(0, size, y =>\n                {\n                    var Ciby = _Crb[y] + 0.5;\n                    for (var x = 0; x < lineLength; x++)\n                    {\n                        _pdata[y * lineLength + x] = GetByte(_Crb + x * 8, Ciby);\n                    }\n                });\n                return data;\n\n                byte GetByte(double* _pCrb, double Ciby)\n                {\n                    var res = 0;\n                    for (var i = 0; i < 8; i += 2)\n                    {\n                        var vCrbx = Unsafe.Read<Vector<double>>(_pCrb + i);\n                        var vCiby = new Vector<double>(Ciby);\n                        var Zr = vCrbx;\n                        var Zi = vCiby;\n                        int b = 0, j = 49;\n                        do\n                        {\n                            var nZr = Zr * Zr - Zi * Zi + vCrbx;\n                            var ZrZi = Zr * Zi;\n                            Zi = ZrZi + ZrZi + vCiby;\n                            Zr = nZr;\n                            var t = Zr * Zr + Zi * Zi;\n                            if (t[0] > 4.0) { b |= 2; if (b == 3) break; }\n                            if (t[1] > 4.0) { b |= 1; if (b == 3) break; }\n                        } while (--j > 0);\n                        res = (res << 2) + b;\n                    }\n                    return (byte)(res ^ -1);\n                }\n\n            }\n        }\n\n        private int[] _MandelbrotManagedv3(ref int[] output)\n        {\n            int VectorWidth = Vector<float>.Count;\n            float[] Vectors = new float[6];\n            float[] P = new float[VectorWidth * 2];\n\n            Span<Vector2> Vector2Span = new Span<float>(Vectors).NonPortableCast<float, Vector2>(); //Lets us read individual Vector2\n            Span<Vector<float>> PSpan = new Span<float>(P).NonPortableCast<float, Vector<float>>(); //Lets us read individual Vectors\n            Vectors[0] = -2f;\n            Vectors[1] = -1f;\n            Vectors[2] = 1f;\n            Vectors[3] = 1f;\n            Vectors[4] = Mandelbrot_Width;\n            Vectors[5] = Mandelbrot_Height;\n\n            ref Vector2 C0 = ref Vector2Span[0];\n            ref Vector2 C1 = ref Vector2Span[1];\n            ref Vector2 B = ref Vector2Span[2];\n            Vector2 D = (C1 - C0) / B;\n\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n                {\n\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        P[h] = C0.X + (D.X * (i + h));\n                        P[h + VectorWidth] = C0.Y + (D.Y * j);\n                    }\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector<float> Vre = PSpan[0];\n                    Vector<float> Vim = PSpan[1]; ;\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 256);\n                    outputVector.CopyTo(output, index);\n\n                }\n            }\n            return output;\n        }\n\n\n        private int[] _MandelbrotManagedv4()\n        {\n            int VectorWidth = Vector<float>.Count;\n            int[] output = new int[MandelbrotArraySize];\n            float[] Vectors = new float[6];\n            Span<Vector2> Vector2Span = new Span<float>(Vectors).NonPortableCast<float, Vector2>(); //Lets us read individual Vector2\n\n            Vectors[0] = -2f;\n            Vectors[1] = -1f;\n            Vectors[2] = 1f;\n            Vectors[3] = 1f;\n            Vectors[4] = Mandelbrot_Width;\n            Vectors[5] = Mandelbrot_Height;\n\n            Vector2 C0 = Vector2Span[0];\n            Vector2 C1 = Vector2Span[1];\n            Vector2 B = Vector2Span[2];\n            Vector2 D = (C1 - C0) / B;\n\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                Parallel.ForEach(MandelbrotBitmapLocation(j), (p) =>\n                {\n                    float[] Pre = new float[VectorWidth];\n                    float[] Pim = new float[VectorWidth];\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        Pre[h] = C0.X + (D.X * (p.Item1 + h));\n                        Pim[h] = C0.Y + (D.Y * p.Item2);\n                    }\n                    int index = unchecked(p.Item2 * Mandelbrot_Width + p.Item1);\n                    Vector<float> Vre = new Vector<float>(Pre);\n                    Vector<float> Vim = new Vector<float>(Pim);\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 256);\n                    outputVector.CopyTo(output, index);\n                });\n\n            }\n            return output;\n        }\n\n        private unsafe int[] _MandelbrotManagedv5(ref int[] output)\n        {\n            int VectorWidth = Vector<float>.Count;\n            Vector<float> C0re = new Vector<float>(-2);\n            Vector<float> C0im = new Vector<float>(-1);\n            Vector<float> C1re = Vector<float>.One;\n            Vector<float> C1im = Vector<float>.One;\n\n            Vector<float> Bx = new Vector<float>(Mandelbrot_Width);\n            Vector<float> By = new Vector<float>(Mandelbrot_Height);\n            Vector<float> Dx = (C1re - C0re) / Bx;\n            Vector<float> Dy = (C1im - C0im) / By;\n\n            int index;\n            Vector<float> Pre = new Vector<float>();\n            Vector<float> Pim;\n\n            Span<float> sPre = new Span<float>(Unsafe.AsPointer(ref Pre), VectorWidth);\n\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n                {\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        sPre[h] = C0re[0] + (Dx[0] * (i + h));\n                    }\n\n                    Pim = C0im + (Dy * j);\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector<int> outputVector = GetByte(ref Pre, ref Pim, 256);\n                    outputVector.CopyTo(output, index);\n                }\n            }\n            return output;\n        }\n\n        private int[] _MandelbrotManagedv6()\n        {\n            int VectorWidth = Vector<float>.Count;\n            int[] output = new int[MandelbrotArraySize];\n\n            Vector<float> C0re = new Vector<float>(-2);\n            Vector<float> C0im = new Vector<float>(-1);\n            Vector<float> C1re = Vector<float>.One;\n            Vector<float> C1im = Vector<float>.One;\n\n            Vector<float> Bx = new Vector<float>(Mandelbrot_Width);\n            Vector<float> By = new Vector<float>(Mandelbrot_Height);\n            Vector<float> Dx = (C1re - C0re) / Bx;\n            Vector<float> Dy = (C1im - C0im) / By;\n\n\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                Parallel.ForEach(MandelbrotBitmapLocation(j), (p) =>\n                {\n                    int i = p.Item1;\n\n                    Vector<float> Pre = new Vector<float>();\n                    unsafe\n                    {\n                        Span<float> sPre = new Span<float>(Unsafe.AsPointer(ref Pre), VectorWidth);\n\n                        for (int h = 0; h < VectorWidth; h++)\n                        {\n                            sPre[h] = C0re[0] + (Dx[0] * (p.Item1 + h));\n                        }\n                    }\n                    Vector<float> Pim = C0im + (Dy * p.Item2);\n                    int index = unchecked(p.Item2 * Mandelbrot_Width + p.Item1);\n                    Vector<int> outputVector = GetByte(ref Pre, ref Pim, 256);\n                    outputVector.CopyTo(output, index);\n\n                });\n\n            }\n            return output;\n        }\n\n        private unsafe int[] _MandelbrotManagedv7(ref int[] output)\n        {\n            int VectorWidth = Vector<float>.Count;\n            float[] Vectors = new float[6];\n            Span<Vector2> Vector2Span = new Span<float>(Vectors).NonPortableCast<float, Vector2>(); //Lets us read individual Vector2\n\n            Vectors[0] = -2f;\n            Vectors[1] = -1f;\n            Vectors[2] = 1f;\n            Vectors[3] = 1f;\n            Vectors[4] = Mandelbrot_Width;\n            Vectors[5] = Mandelbrot_Height;\n\n            Vector2 C0 = Vector2Span[0];\n            Vector2 C1 = Vector2Span[1];\n            Vector2 B = Vector2Span[2];\n            Vector2 D = (C1 - C0) / B;\n\n            int index;\n            float[] PreArray = new float[VectorWidth];\n            float[] PimArray = new float[VectorWidth];\n\n\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n                {\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        PreArray[h] = C0.X + (D.X * (i + h));\n                        PimArray[h] = C0.Y + (D.Y * j);\n                    }\n                    Vector<float> Pre = new Vector<float>(PreArray);\n                    Vector<float> Pim = new Vector<float>(PimArray);\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector<int> outputVector = GetByte(ref Pre, ref Pim, 256);\n                    outputVector.CopyTo(output, index);\n                }\n            }\n            return output;\n        }\n\n        private int[] _MandelbrotManagedv8()\n        {\n            int[] output = new int[MandelbrotArraySize];\n            Vector2 C0 = new Vector2(-2, -1);\n            Vector2 C1 = new Vector2(1, 1);\n            Vector2 B = new Vector2(Mandelbrot_Width, Mandelbrot_Height);\n            Vector2 D = (C1 - C0) / B;\n            Parallel.For(0, Mandelbrot_Height, (j) =>\n            {\n                float[] scanLine = new float[Mandelbrot_Width];\n                for (int x = 0; x < Mandelbrot_Width; x++)\n                {\n                    scanLine[x] = C0.X + (D.X * (x));\n                }\n                Vector<float> Vim = new Vector<float>(C0.Y + (D.Y * j));\n                int index;\n                for (int h = 0; h < Mandelbrot_Width; h += VectorWidth)\n                {\n                    Vector<float> Vre = new Vector<float>(scanLine, h);\n                    index = unchecked(j * Mandelbrot_Width + h);\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 256);\n                    outputVector.CopyTo(output, index);\n                }\n            });\n            return output;\n        }\n\n        private FixedBuffer<byte> _MandelbrotUnmanagedv1(ref FixedBuffer<byte> output)\n        {\n            FixedBuffer<float> Vectors = new FixedBuffer<float>(10);\n            Span<Vector2> Vector2Span = Vectors.AcquireWriteSpan().NonPortableCast<float, Vector2>(); //Lets us read individual vectors\n\n            Vectors[0] = -2f;\n            Vectors[1] = -1f;\n            Vectors[2] = 1f;\n            Vectors[3] = 1f;\n            Vectors[4] = Mandelbrot_Width;\n            Vectors[5] = Mandelbrot_Height;\n\n            ref Vector2 C0 = ref Vector2Span[0];\n            ref Vector2 C1 = ref Vector2Span[1];\n            ref Vector2 B = ref Vector2Span[2];\n            ref Vector2 P = ref Vector2Span[3];\n            Vector2 D = (C1 - C0) / B;\n\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i++)\n                {\n                    Vectors[6] = i;\n                    Vectors[7] = j;\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector2 V = C0 + (P * D);\n                    output[index] = GetByte(ref V, 256);\n                }\n            }\n            Vectors.Release();\n            return output;\n        }\n\n        private FixedBuffer<int> _MandelbrotUnmanagedv2(ref FixedBuffer<int> output)\n        {\n            int VectorWidth = Vector<float>.Count;\n            Span<Vector<int>> outputVectorSpan = output.AcquireVectorWriteSpan();\n            Vector<int> One = Vector<int>.One;\n            Vector<int> Zero = Vector<int>.Zero;\n\n            FixedBuffer<float> Vectors = new FixedBuffer<float>(6);\n            FixedBuffer<float> P = new FixedBuffer<float>(VectorWidth * 2);\n            Span<Vector2> Vector2Span = Vectors.AcquireWriteSpan().NonPortableCast<float, Vector2>(); //Lets us read individual Vector2\n            Span<Vector<float>> PSpan = P.AcquireWriteSpan().NonPortableCast<float, Vector<float>>(); //Lets us read individual Vectors\n            Vectors[0] = -2f;\n            Vectors[1] = -1f;\n            Vectors[2] = 1f;\n            Vectors[3] = 1f;\n            Vectors[4] = Mandelbrot_Width;\n            Vectors[5] = Mandelbrot_Height;\n\n            ref Vector2 C0 = ref Vector2Span[0];\n            ref Vector2 C1 = ref Vector2Span[1];\n            ref Vector2 B = ref Vector2Span[2];\n            Vector2 D = (C1 - C0) / B;\n\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n                {\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        P[h] = C0.X + (D.X * (i + h));\n                    }\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector<float> Vre = PSpan[0];\n                    Vector<float> Vim = new Vector<float>(C0.Y + (D.Y * j));\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 256);\n                    outputVectorSpan[index / Vector<int>.Count] = outputVector;\n                }\n            }\n\n            Vectors.Release();\n            Vectors.Free();\n            P.Release();\n            P.Free();\n            output.Release();\n            return output;\n        }\n\n        private FixedBuffer<int> _MandelbrotUnmanagedv3(ref FixedBuffer<int> output)\n        {\n            int VectorWidth = Vector<float>.Count;\n            FixedBuffer<float> P = new FixedBuffer<float>(VectorWidth);\n            Vector2 C0 = new Vector2(-2, -1);\n            Vector2 C1 = new Vector2(1, 1);\n            Vector2 B = new Vector2(Mandelbrot_Width, Mandelbrot_Height);\n            Vector2 D = (C1 - C0) / B;\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n                {\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        P[h] = C0.X + (D.X * (i + h));\n                    }\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector<float> Vre = P.Read<Vector<float>>(0);\n                    Vector<float> Vim = new Vector<float>(C0.Y + (D.Y * j));\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 256);\n                    output.Write(index, ref outputVector);\n                }\n            }\n            P.Free();\n            return output;\n        }\n\n        private unsafe void _MandelbrotUnmanagedv4(FixedBuffer<int> output)\n        {\n            Vector2 C0 = new Vector2(-2, -1);\n            Vector2 C1 = new Vector2(1, 1);\n            Vector2 B = new Vector2(Mandelbrot_Width, Mandelbrot_Height);\n            Vector2 D = (C1 - C0) / B;          \n            Parallel.For(0, Mandelbrot_Height, (j) =>\n            {\n                FixedBuffer<float> scanLine = new FixedBuffer<float>(Mandelbrot_Width);\n                for (int x = 0; x < Mandelbrot_Width; x++)\n                {\n                    float px = C0.X + (D.X * (x));\n                    scanLine.Write(x, ref px);\n                }\n                Vector<float> Vim = new Vector<float>(C0.Y + (D.Y * j));\n                for (int h = 0; h < Mandelbrot_Width; h+=VectorWidth)\n                {\n                    int index = j * Mandelbrot_Width + h;\n                    Vector<float> Vre = scanLine.Read<Vector<float>>(h);\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 256);\n                    output.Write(index, ref outputVector);\n                }\n                scanLine.Free();\n            });\n            \n            return;\n        }\n\n        private unsafe void _MandelbrotUnmanagedv5(ref FixedBuffer<int> output)\n        {\n            Vector2 C0 = new Vector2(-2, -1);\n            Vector2 C1 = new Vector2(1, 1);\n            Vector2 B = new Vector2(Mandelbrot_Width, Mandelbrot_Height);\n            Vector2 D = (C1 - C0) / B;\n            FixedBuffer<float> scanLine = new FixedBuffer<float>(Mandelbrot_Width);\n            for (int j = 0; j < Mandelbrot_Height; j++) \n            {\n                for (int x = 0; x < Mandelbrot_Width; x++)\n                {\n                    float px = C0.X + (D.X * (x));\n                    scanLine.Write(x, ref px);\n                }\n                Vector<float> Vim = new Vector<float>(C0.Y + (D.Y * j));\n                for (int h = 0; h < Mandelbrot_Width; h += VectorWidth)\n                {\n                    int index = j * Mandelbrot_Width + h;\n                    Vector<float> Vre = scanLine.Read<Vector<float>>(h);\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 256);\n                    output.Write(index, ref outputVector);\n                }\n            }\n            scanLine.Free();\n            return;\n        }\n\n\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        byte GetByte(float[] c, int maxIterations)\n        {\n            float[] Z = new float[] { c[0], c[1] }; // make a copy\n            int i;\n            for (i = 0; i < maxIterations; i++)\n            {\n                if ((Z[0] * Z[0]) + (Z[1] * Z[1]) > 4f)\n                {\n                    return (byte)i;\n                }\n                float z0 = Z[0];\n                float z1 = Z[1];\n                float[] w = new float[] { (z0 * z0), (z1 * z1) };\n                Z[0] = c[0] + w[0] - w[1];\n                Z[1] = c[1] + 2f * z0 * z1;\n            }\n            return (byte)(i - 1);\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        byte GetByte(ref Vector2 c, int max_iterations)\n        {\n            Vector2 z = c; //make a copy\n            int i;\n            for (i = 0; i < max_iterations; i++)\n            {\n                if (z.LengthSquared() > 4f)\n                {\n                    return (byte)i;\n                }\n                Vector2 w = z * z;\n                z = c + new Vector2(w.X - w.Y, 2f * z.X * z.Y);\n            }\n            return (byte)(i - 1);\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        Vector<int> GetByte(ref Vector<float> Cre, ref Vector<float> Cim, int max_iterations)\n        {\n            Vector<float> Zre = Cre; //make a copy\n            Vector<float> Zim = Cim; //make a copy\n            Vector<int> MaxIterations = new Vector<int>(max_iterations);\n            Vector<int> Increment = One;\n            Vector<int> I;\n            for (I = Zero; Increment != Zero; I += Vector.Abs(Increment))\n            {\n                Vector<float> S = SquareAbs(Zre, Zim);\n                Increment = Vector.LessThanOrEqual(S, Limit) & Vector.LessThan(I, MaxIterations);\n                if (Increment.Equals(Zero))\n                {\n                    break;\n                }\n                else\n                {\n                    Vector<float> Tre = Zre;\n                    Zre = Cre + (Zre * Zre - Zim * Zim);\n                    Zim = Cim + 2f * Tre * Zim;\n                }\n            }\n            return I;\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        Vector<float> SquareAbs(Vector<float> Vre, Vector<float> Vim)\n        {\n            return (Vre * Vre) + (Vim * Vim);\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private void WriteMandelbrotPPM(ReadOnlySpan<byte> output, string name)\n        {\n            using (StreamWriter sw = new StreamWriter(name))\n            {\n                sw.Write(\"P6\\n\");\n                sw.Write(string.Format(\"{0} {1}\\n\", Mandelbrot_Width, Mandelbrot_Height));\n                sw.Write(\"255\\n\");\n                sw.Close();\n            }\n            using (BinaryWriter bw = new BinaryWriter(new FileStream(name, FileMode.Append)))\n            {\n                for (int i = 0; i < Mandelbrot_Width * Mandelbrot_Height; i++)\n                {\n                    byte b = (output[i] & 0x01) == 1 ? (byte)20 : (byte)240;\n                    bw.Write(b);\n                    bw.Write(b);\n                    bw.Write(b);\n                }\n            }\n\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private void WriteMandelbrotPPM(ReadOnlySpan<int> output, string name)\n        {\n            using (StreamWriter sw = new StreamWriter(name))\n            {\n                sw.Write(\"P6\\n\");\n                sw.Write(string.Format(\"{0} {1}\\n\", Mandelbrot_Width, Mandelbrot_Height));\n                sw.Write(\"255\\n\");\n                sw.Close();\n            }\n            using (BinaryWriter bw = new BinaryWriter(new FileStream(name, FileMode.Append)))\n            {\n                for (int i = 0; i < Mandelbrot_Width * Mandelbrot_Height; i++)\n                {\n                    byte b = (output[i] & 0x01) == 1 ? (byte)20 : (byte)240;\n                    bw.Write(b);\n                    bw.Write(b);\n                    bw.Write(b);\n                }\n            }\n\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private void WriteMandelbrotPPM(int[] output, string name)\n        {\n            using (StreamWriter sw = new StreamWriter(name))\n            {\n                sw.Write(\"P6\\n\");\n                sw.Write(string.Format(\"{0} {1}\\n\", Mandelbrot_Width, Mandelbrot_Height));\n                sw.Write(\"255\\n\");\n                sw.Close();\n            }\n            using (BinaryWriter bw = new BinaryWriter(new FileStream(name, FileMode.Append)))\n            {\n                for (int i = 0; i < Mandelbrot_Width * Mandelbrot_Height; i++)\n                {\n                    byte b = (output[i] & 0x01) == 1 ? (byte)20 : (byte)240;\n                    bw.Write(b);\n                    bw.Write(b);\n                    bw.Write(b);\n                }\n            }\n        }\n\n        public IEnumerable<ValueTuple<int, int>> MandelbrotBitmapLocation(int j)\n        {\n            \n            for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n            {\n                yield return (i, j);\n            }\n        }\n\n        public string GetISPCBaselineResult()\n        {\n            switch (Scale)\n            {\n                case 1:\n                    return \"328 M\";\n                case 3:\n                    return \"3 G\";\n                case 6:\n                    return \"11.9 G\";\n                default:\n                    return string.Empty;\n            }\n        }\n\n        public string GetISPCResult()\n        {\n            switch (Scale)\n            {\n                case 1:\n                    return \"26.8 M\";\n                case 3:\n                    return \"236 M\";\n                case 6:\n                    return \"940 M\";\n                default:\n                    return string.Empty;\n            }\n        }\n\n        public string GetISPCTasksResult()\n        {\n            switch (Scale)\n            {\n                case 1:\n                    return \"5.6 M\";\n                case 3:\n                    return \"48.2M\";\n                case 6:\n                    return \"196.2M\";\n                default:\n                    return string.Empty;\n            }\n        }\n\n        public string GetISPCResult2()\n        {\n            switch (Scale)\n            {\n                case 1:\n                    return \"95 M\";\n                case 3:\n                    return \"819.5 M\";\n                case 6:\n                    return \"3.3 G\";\n                default:\n                    return string.Empty;\n            }\n        }\n\n \n        public string GetISPCTasksResult2()\n        {\n            switch (Scale)\n            {\n                case 1:\n                    return \"7.3 M\";\n                case 3:\n                    return \"61.6 M\";\n                case 6:\n                    return \"244.6 M\";\n                default:\n                    return string.Empty;\n            }\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/Design.md",
    "content": "﻿## Catgeories\n\n1. Malloc: Benchmark low-level malloc operations and creating Span<Y>\n\n2. Arrays: Bench\n\n\n1. Allocate uint arrays of various sizes from small to very large. Benchmark how long it takes\n2. Generate random values and assign to random indices of the array. Benchmark.\n3. Allocate memory and use span\n\nThings to test:\n\nFragmentation: allocate small and large sizes consecutively.\n\nLOH stress:\nhttps://www.red-gate.com/simple-talk/dotnet/net-framework/the-dangers-of-the-large-object-heap/\n\n\n    Create an Int32[100000000]; //goes on the LOH\n    Create an Int32[30000]; //smaller but still big enough to go on the LOH\n    Throw away the big array but keep the small array. //Creates a 100000000 hole on the LOH immediately followed by an in-use region for the small array.\n    next iteration will create another big array slightly bigger the first. //This won't fit in the 'hole' of the previous array. The heap must be extended now for the new array to fit.\n    Loop for a while.\n\nWe should find it taking longer and longer to allocate the large arrays and using lots of memory until eventually an OOM happens.\n\nWe can do the exact same operations with SafeArray<Int32> and then compare the performance."
  },
  {
    "path": "jemalloc.Benchmarks/JemBenchmark.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\n\nusing System.Threading;\nusing BenchmarkDotNet;\nusing BenchmarkDotNet.Order;\n\nusing BenchmarkDotNet.Attributes;\nusing BenchmarkDotNet.Attributes.Columns;\nusing BenchmarkDotNet.Diagnosers;\nusing BenchmarkDotNet.Code;\nusing BenchmarkDotNet.Loggers;\n\nnamespace jemalloc.Benchmarks\n{\n    #region Enums\n    public enum Category\n    {\n        MALLOC,\n        NARRAY,\n        HUGEARRAY,\n        BUFFER,\n        VECTOR\n    }\n\n    public enum Operation\n    {\n        CREATE,\n        FILL,\n        MATH,\n        FRAGMENT,\n        MANDELBROT,\n        TEST\n    }\n    #endregion\n\n    [JemBenchmarkJob]\n    [MemoryDiagnoser]\n    public abstract class JemBenchmark<TData, TParam> where TData : struct, IEquatable<TData>, IComparable<TData>, IConvertible where TParam : struct\n    {\n        #region Constructors\n        static JemBenchmark()\n        {\n\n        }\n        public JemBenchmark()\n        {\n            \n        }\n        #endregion\n\n        #region Properties\n        [ParamsSource(nameof(GetParameters))]\n        public TParam Parameter;\n\n        public static List<TParam> BenchmarkParameters { get; set; }\n\n        public static Category Category { get; set; }\n\n        public static Operation Operation { get; set; }\n\n        public static bool Debug { get; set; }\n\n        public static bool Validate { get; set; }\n\n        public static ILogger Log { get; } = new ConsoleLogger();\n\n        public static Process CurrentProcess { get; } = Process.GetCurrentProcess();\n\n        public static long InitialPrivateMemorySize { get; protected set; }\n\n        public static long PrivateMemorySize\n        {\n            get\n            {\n                CurrentProcess.Refresh();\n                return CurrentProcess.PrivateMemorySize64;\n            }\n        }\n\n        public static long PeakWorkingSet\n        {\n            get\n            {\n                CurrentProcess.Refresh();\n                return CurrentProcess.PeakWorkingSet64;\n            }\n        }\n        #endregion\n\n        #region Methods\n        public IEnumerable<IParam> GetParameters() \n        {\n            IEnumerable<IParam> param;\n            param = BenchmarkParameters.Select(p => new JemBenchmarkParam<TParam>(p));\n            return param;\n        }\n        public static int GetBenchmarkMethodCount<TBench>() where TBench : JemBenchmark<TData, TParam>\n        {\n            return typeof(TBench).GenericTypeArguments.First().GetMethods(BindingFlags.Public).Count();\n        }\n\n        [GlobalSetup]\n        public virtual void GlobalSetup()\n        {\n            DebugInfoThis();\n            Info(\"Data type is {0}.\", typeof(TData).Name);\n            CurrentProcess.Refresh();\n            InitialPrivateMemorySize = CurrentProcess.PeakWorkingSet64;\n        }\n\n        public static void SetColdStartOverride(bool value)\n        {\n            JemBenchmarkJobAttribute.ColdStartOverride = value;\n        }\n\n        public static void SetTargetCountOverride(int value)\n        {\n            JemBenchmarkJobAttribute.TargetCountOverride = value;\n        }\n\n        public static void SetInvocationCountOverride(int value)\n        {\n            JemBenchmarkJobAttribute.InvocationCountOverride = value;\n        }\n\n        public static void SetWarmupCountOverride(int value)\n        {\n            JemBenchmarkJobAttribute.WarmupCountOverride = value;\n        }\n\n        public TValue GetValue<TValue>(string name, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            if (JemUtil.BenchmarkValues.TryGetValue($\"{name}_{Parameter.GetHashCode()}\", out object v))\n            {\n                return (TValue) v;\n            }\n            else throw new Exception($\"Could not get value {name}.\");\n        }\n\n        public void SetValue<TValue>(string name, TValue value, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            JemUtil.BenchmarkValues.GetOrAdd($\"{name}_{Parameter.GetHashCode()}\", value);\n         \n        }\n\n        public void RemoveValue(string name, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            JemUtil.BenchmarkValues.Remove($\"{name}_{Parameter.GetHashCode()}\", out object o);\n        }\n\n        public void SetStatistic(string name, string value, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            JemUtil.BenchmarkStatistics.AddOrUpdate($\"{memberName}_{name}\", value, ((k, v) => value));\n        }\n\n        public void SetMemoryStatistics([CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            this.SetStatistic($\"{memberName}_WorkingSet\", JemUtil.PrintBytes(JemUtil.ProcessWorkingSet));\n            this.SetStatistic($\"{memberName}_JemResident\", JemUtil.PrintBytes(Jem.ResidentBytes));\n            this.SetStatistic($\"{memberName}_PrivateMemory\", JemUtil.PrintBytes(JemUtil.ProcessPrivateMemory));\n            this.SetStatistic($\"{memberName}_JemAllocated\", JemUtil.PrintBytes(Jem.AllocatedBytes));\n        }\n\n\n        #region Log\n        public static void Info(string format, params object[] values) => Log.WriteLineInfo(string.Format(format, values));\n\n        public static void DebugInfo(string format, params object[] values)\n        {\n            if (Debug)\n            {\n                Info(format, values);\n            }\n        }\n\n        public static void InfoThis([CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0) => Info(\"Executing {0}() on thread {1}.\", memberName, Thread.CurrentThread.ManagedThreadId);\n\n        public static void DebugInfoThis([CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0)\n        {\n            if (Debug)\n            {\n                InfoThis(memberName, fileName, lineNumber);\n            }\n        }\n\n        public static void Error(string text, [CallerMemberName] string memberName = \"\", [CallerFilePath] string fileName = \"\", [CallerLineNumber] int lineNumber = 0) => \n            Log.WriteLineError(string.Format(\"Error : {0} At {1} in {2} on line {3}.\", text, memberName, fileName, lineNumber));\n\n        public static void Error(string format, params object[] values) => Log.WriteLineError(string.Format(format, values));\n        #endregion\n\n        public static string PrintBytes(double bytes, string suffix = \"\")\n        {\n            if (bytes >= 0 && bytes <= 1024)\n            {\n                return string.Format(\"{0:N0} B{1}\", bytes, suffix);\n            }\n            else if (bytes >= 1024 && bytes < (1024 * 1024))\n            {\n                return string.Format(\"{0:N1} KB{1}\", bytes / 1024, suffix);\n            }\n            else if (bytes >= (1024 * 1024) && bytes < (1024 * 1024 * 1024))\n            {\n                return string.Format(\"{0:N1} MB{1}\", bytes / (1024 * 1024), suffix);\n            }\n            else if (bytes >= (1024 * 1024 * 1024))\n            {\n                return string.Format(\"{0:N1} GB{1}\", bytes / (1024 * 1024 * 1024), suffix);\n            }\n            else throw new ArgumentOutOfRangeException();\n\n        }\n\n        public static Tuple<double, string> PrintBytesToTuple(double bytes, string suffix = \"\")\n        {\n            string[] s = PrintBytes(bytes, suffix).Split(' ');\n            return new Tuple<double, string>(Double.Parse(s[0]), s[1]);\n        }\n\n        private static object benchmarkLock = new object();\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/JemBenchmarkAttribute.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing BenchmarkDotNet.Configs;\n\nusing BenchmarkDotNet.Attributes;\n\nnamespace jemalloc.Benchmarks\n{\n    public class JemBenchmarkAttribute : BenchmarkAttribute\n    {\n        public static Category Category { get; set; }\n\n        public static Operation Operation { get; set; }\n  \n        public static IConfig CurrentConfig { get; set; }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/JemBenchmarkJobAttribute.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing BenchmarkDotNet.Engines;\nusing BenchmarkDotNet.Environments;\nusing BenchmarkDotNet.Jobs;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Order;\nusing BenchmarkDotNet.Toolchains.InProcess;\n\nnamespace jemalloc.Benchmarks\n{\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false, Inherited = true)]\n    public class JemBenchmarkJobAttribute : Attribute, IConfigSource\n    {\n        public JemBenchmarkJobAttribute(\n            RunStrategy RunStrategy = RunStrategy.Throughput,\n            int TargetCount = DefaultValue,\n            int InvocationCount = DefaultValue,\n            int WarmupCount = DefaultValue\n            )\n        {\n            Job job = new Job()\n                .WithGcAllowVeryLargeObjects(true)\n                .WithId(\"JemBenchmark\");\n            job.Env.Platform = Platform.X64;\n            job.Env.Runtime = Runtime.Core;\n            job.Env.Jit = Jit.RyuJit;\n\n\n            if (WarmupCountOverride.HasValue)\n            {\n                job.Run.WarmupCount = WarmupCountOverride.Value;\n            }\n            else if (WarmupCount != DefaultValue)\n            {\n                job.Run.WarmupCount = WarmupCount;\n            }\n            \n\n            if (TargetCountOverride.HasValue)\n            {\n                job.Run.TargetCount = TargetCountOverride.Value;\n            }\n            else if (TargetCount != DefaultValue)\n            {\n                job.Run.TargetCount = TargetCount;\n            }\n\n            if (InvocationCountOverride.HasValue)\n            {\n                job.Run.InvocationCount = InvocationCountOverride.Value;\n            }\n            else if (InvocationCount != DefaultValue)\n            {\n                job.Run.InvocationCount = InvocationCount;\n            }\n\n            if (ColdStartOverride.HasValue)\n            {\n                job.Run.RunStrategy = ColdStartOverride.Value ? RunStrategy.ColdStart : RunStrategy.Throughput;\n            }\n            else \n            {\n                job.Run.RunStrategy = RunStrategy;\n            }\n            \n            job.Infrastructure.Toolchain = new InProcessToolchain(TimeSpan.FromMinutes(TimeoutInMinutes), BenchmarkActionCodegen.ReflectionEmit, true);\n            Config = ManualConfig.CreateEmpty()\n                .With(job);\n        }\n\n        #region Properties\n        public IConfig Config { get; }\n        public int TimeoutInMinutes { get; set; } = 10;\n        public static int? TargetCountOverride { get; set; } = null;\n        public static int? WarmupCountOverride { get; set; } = null;\n        public static int? InvocationCountOverride { get; set; } = null;\n        public static bool? ColdStartOverride { get; set; } = null;\n        #endregion\n\n        #region Fields\n        private const int DefaultValue = -1;\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/JemBenchmarkParam.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing BenchmarkDotNet.Code;\nusing BenchmarkDotNet.Parameters;\n\nnamespace jemalloc.Benchmarks\n{\n    public class JemBenchmarkParam<T> : IParam where T : struct\n    {\n        private static string ctorName = typeof(T).Name;\n\n        private readonly T value;\n\n        public JemBenchmarkParam(T value) => this.value = value;\n\n        public object Value => value;\n\n        public string DisplayText => $\"{value}\";\n\n        public string ToSourceCode() => $\"new {ctorName}({value})\";\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/JemStatisticColumn.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Columns;\nnamespace jemalloc.Benchmarks\n{\n    public class JemStatisticColumn : IColumn\n    {\n        #region Constructors\n        public JemStatisticColumn(string columnName, Func<string> jemStatFunction, string legend)\n        {\n            ColumnName = columnName;\n            JemStatFunction = jemStatFunction;\n            Legend = legend;\n        }\n        #endregion\n\n        #region Implemented properties\n        //\n        // Summary:\n        //     An unique identificator of the column. If there are several columns with the\n        //     same Id, only one of them will be shown in the summary.\n        public string Id => ColumnName;\n        //\n        // Summary:\n        //     Defines order of column in the same category.\n        public int PriorityInCategory { get; } = 99;\n\n        // Summary:\n        //     Defines how to format column's value\n        public UnitType UnitType { get; } = UnitType.Size;\n        //\n        // Summary:\n        //     Column description.\n        public string Legend { get; protected set; }\n        public bool AlwaysShow => true;\n\n        public bool IsNumeric => true;\n\n        public ColumnCategory Category => ColumnCategory.Statistics;\n\n        #endregion\n\n        #region Implemented methods\n        public bool IsDefault(Summary summary, Benchmark benchmark) => false;\n\n        public string GetValue(Summary summary, Benchmark benchmark) => JemStatFunction.Invoke();\n\n        public bool IsAvailable(Summary summary) => Jem.Initialized;\n        //\n        // Summary:\n        //     Value in this column formatted using the specified style.\n        public string GetValue(Summary summary, Benchmark benchmark, ISummaryStyle style) => (JemStatFunction.Invoke());\n\n        public string ColumnName { get; }\n        #endregion\n\n        #region Overriden methods\n        public override string ToString() => ColumnName;\n        #endregion\n\n        #region Fields\n        Func<string> JemStatFunction;\n        #endregion\n\n        #region Available columns\n        public static readonly IColumn Allocated = new JemStatisticColumn(\"JEM allocated\", () => JemUtil.PrintBytes(Jem.AllocatedBytes),\n            \"Allocated pages using jemalloc (native only, inclusive, 1KB = 1024B)\");\n        public static readonly IColumn Active = new JemStatisticColumn(\"JEM active\", () => JemUtil.PrintBytes(Jem.ActiveBytes),\n            \"Active pages using jemalloc (native only, inclusive, 1KB = 1024B)\");\n        public static readonly IColumn Mapped = new JemStatisticColumn(\"JEM mapped\", () => JemUtil.PrintBytes(Jem.MappedBytes),\n            \"Mapped memory using jemalloc (native only, inclusive, 1KB = 1024B)\");\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/ProcessStatisticColumn.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Reports;\nusing BenchmarkDotNet.Columns;\nnamespace jemalloc.Benchmarks\n{\n    public class ProcessStatisticColumn : IColumn\n    {\n        #region Constructors\n        public ProcessStatisticColumn(string columnName, Func<string> jemStatFunction, string legend)\n        {\n            ColumnName = columnName;\n            JemStatFunction = jemStatFunction;\n            Legend = legend;\n        }\n        #endregion\n\n        #region Implemented properties\n        //\n        // Summary:\n        //     An unique identificator of the column. If there are several columns with the\n        //     same Id, only one of them will be shown in the summary.\n        public string Id => ColumnName;\n        //\n        // Summary:\n        //     Defines order of column in the same category.\n        public int PriorityInCategory { get; } = 99;\n\n        // Summary:\n        //     Defines how to format column's value\n        public UnitType UnitType { get; } = UnitType.Size;\n        //\n        // Summary:\n        //     Column description.\n        public string Legend { get; protected set; }\n        public bool AlwaysShow => true;\n\n        public bool IsNumeric => true;\n\n        public ColumnCategory Category => ColumnCategory.Statistics;\n\n        #endregion\n\n        #region Implemented methods\n        public bool IsDefault(Summary summary, Benchmark benchmark) => false;\n\n        public string GetValue(Summary summary, Benchmark benchmark) => JemStatFunction.Invoke();\n\n        public bool IsAvailable(Summary summary) => Jem.Initialized;\n        //\n        // Summary:\n        //     Value in this column formatted using the specified style.\n        public string GetValue(Summary summary, Benchmark benchmark, ISummaryStyle style) => (JemStatFunction.Invoke());\n\n        public string ColumnName { get; }\n        #endregion\n\n        #region Overriden methods\n        public override string ToString() => ColumnName;\n        #endregion\n\n        #region Fields\n        Func<string> JemStatFunction;\n        #endregion\n\n        #region Available columns\n        public static readonly IColumn PeakVirtualMemory = new JemStatisticColumn(\"PeakVirtualMem\", () => JemUtil.PrintBytes(JemUtil.ProcessPeakVirtualMem),\n            \"Peak virtual memory for entire process (native and managed, inclusive, 1KB = 1024B)\");\n\n        public static readonly IColumn PeakWorkingSet = new JemStatisticColumn(\"PeakWorkingSet\", () => JemUtil.ProcessPeakWorkingSet.ToString(),\n            \"Peak working set for entire process per single operation (native and managed, inclusive, 1KB = 1024B)\");\n\n        public static readonly IColumn VirtualMemory = new JemStatisticColumn(\"VirtualMemory\", () => JemUtil.PrintBytes(JemUtil.ProcessVirtualMemory),\n            \"Virtual memory allocated for entire process per single operation (native and managed, inclusive, 1KB = 1024B)\");\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/TestUDT.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\n\nnamespace jemalloc.Benchmarks\n{\n    public struct TestUDT : IEquatable<TestUDT>, IComparable<TestUDT>, IConvertible\n    {\n        public Guid ID { get; set; }               \n        public Utf8Buffer FirstName { get; set; }      \n        public Utf8Buffer LastName { get; set; }       \n        public DateTime? DOB { get; set; }         \n        public decimal Balance { get; set; }       \n        public FixedBuffer<float> Data { get; set; }          \n        public FixedBuffer<byte> Photo { get; set; } \n\n        public static TestUDT MakeTestRecord(Random rng)\n        {\n            Guid _id = Guid.NewGuid();\n            string _ids = _id.ToString(\"N\");\n            byte[] photo = new byte[4096];\n            rng.NextBytes(photo);\n            return new TestUDT()\n            {\n                ID = _id,\n                FirstName = new Utf8Buffer(\"Gavial-\" + _id.ToString(\"D\").Substring(0, 4)),\n                LastName = new Utf8Buffer(\"Buxarinovich-\" + _id.ToString(\"D\").Substring(0, 4)),\n                DOB = _ids.StartsWith(\"7\") ? (DateTime?)null : DateTime.UtcNow,\n                Balance = 2131m,\n                Photo = new FixedBuffer<byte>(photo)\n            };\n        }\n\n        public bool Equals(TestUDT r)\n        {\n            return this.ID == r.ID;\n        }\n\n        #region IConvertible\n\n\n        public TypeCode GetTypeCode()\n        {\n            return TypeCode.Object;\n        }\n\n        bool IConvertible.ToBoolean(IFormatProvider provider)\n        {\n            throw new InvalidCastException();        \n        }\n\n        double GetDoubleValue()\n        {\n            throw new InvalidCastException(); \n        }\n\n        byte IConvertible.ToByte(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        char IConvertible.ToChar(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        DateTime IConvertible.ToDateTime(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        decimal IConvertible.ToDecimal(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        double IConvertible.ToDouble(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        short IConvertible.ToInt16(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        int IConvertible.ToInt32(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        long IConvertible.ToInt64(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        sbyte IConvertible.ToSByte(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        float IConvertible.ToSingle(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        string IConvertible.ToString(IFormatProvider provider)\n        {\n            return String.Format(\"({0}, {1})\", FirstName, LastName);\n        }\n\n        object IConvertible.ToType(Type conversionType, IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        ushort IConvertible.ToUInt16(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        uint IConvertible.ToUInt32(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        ulong IConvertible.ToUInt64(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n        #endregion\n\n        #region IComparable\n        public int CompareTo(TestUDT other)\n        {\n            return 0;\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Benchmarks/jemalloc.Benchmarks.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.0</TargetFramework>\n    <Platform>x64</Platform>\n    <LangVersion>latest</LangVersion>\n    <Platforms>AnyCPU;x64</Platforms>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <PlatformTarget>x64</PlatformTarget>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <PlatformTarget>x64</PlatformTarget>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <PlatformTarget>x64</PlatformTarget>\n    <LangVersion>latest</LangVersion>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\n    <PlatformTarget>x64</PlatformTarget>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <PlatformTarget>x64</PlatformTarget>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <PlatformTarget>x64</PlatformTarget>\n    <OutputPath>..\\x64\\Release\\</OutputPath>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <LangVersion>latest</LangVersion>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"BenchmarkDotNet\" Version=\"0.10.11\" />\n    <PackageReference Include=\"ZKWeb.System.Drawing\" Version=\"4.0.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    \n    <ProjectReference Include=\"..\\jemalloc.Api\\jemalloc.Api.csproj\" />\n  </ItemGroup>\n\n  <Target Name=\"PostBuild\" AfterTargets=\"PostBuildEvent\">\n    <Exec Command=\"copy C:\\Projects\\jemalloc.NET\\x64\\Debug\\jemallocd.dll $(OutDir)\" />\n  </Target>\n</Project>\n"
  },
  {
    "path": "jemalloc.Bindings/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.6.1\" />\n    </startup>\n</configuration>"
  },
  {
    "path": "jemalloc.Bindings/JemallocLibrary.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing CppSharp;\nusing CppSharp.AST;\nusing CppSharp.Generators;\nusing CppSharp.Passes;\n\nnamespace jemalloc.Bindings\n{\n    public class JemallocLibrary : ILibrary\n    {\n        /// Setup the driver options here.\n        public void Setup(Driver driver)\n        {\n            DriverOptions options = driver.Options;\n            options.GeneratorKind = GeneratorKind.CSharp;\n            Module module = options.AddModule(\"jemalloc\");\n            module.Defines.AddRange(@\"JEMALLOC_NO_PRIVATE_NAMESPACE;REENTRANT;WINDLL;DLLEXPORT;JEMALLOC_DEBUG;DEBUG\".Split(';'));\n            module.IncludeDirs.Add(@\"..\\..\\jemalloc\\include\\jemalloc\");\n            module.IncludeDirs.Add(@\"..\\..\\jemalloc\\include\\jemalloc\\internal\");\n            module.IncludeDirs.Add(@\"..\\..\\jemalloc\\include\\msvc_compat\");\n            module.IncludeDirs.Add(@\".\\\");\n            module.Headers.Add(\"jemalloc-win-msvc.h\");\n            module.LibraryDirs.Add(@\".\\\");\n            module.Libraries.Add(\"jemallocd.lib\");\n            module.OutputNamespace = \"jemalloc\";\n            options.OutputDir = @\".\\\";\n            options.Verbose = true;\n        }\n\n        /// Setup your passes here.\n        public void SetupPasses(Driver driver)\n        {\n            \n        }\n\n        /// Do transformations that should happen before passes are processed.\n        public void Preprocess(Driver driver, ASTContext ctx)\n        {\n            \n        }\n\n        /// Do transformations that should happen after passes are processed.\n        public void Postprocess(Driver driver, ASTContext ctx)\n        {\n            ctx.SetClassBindName(\"ExtentHooksS\", \"ExtentHooks\");\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Bindings/Program.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing CppSharp;\n\nnamespace jemalloc.Bindings\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            ConsoleDriver.Run(new JemallocLibrary());\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Bindings/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"jemalloc.Bindings\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"jemalloc.Bindings\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2017\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible\n// to COM components.  If you need to access a type in this assembly from\n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"c24a6949-ba9e-443b-a67e-188ab489057e\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers\n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "jemalloc.Bindings/jemalloc-win-msvc.h",
    "content": "#define JEMALLOC_H_\nextern \"C\" {\n\n\n/* Defined if __attribute__((...)) syntax is supported. */\n/* #undef JEMALLOC_HAVE_ATTR */\n\n/* Defined if alloc_size attribute is supported. */\n/* #undef JEMALLOC_HAVE_ATTR_ALLOC_SIZE */\n\n/* Defined if format(gnu_printf, ...) attribute is supported. */\n/* #undef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF */\n\n/* Defined if format(printf, ...) attribute is supported. */\n/* #undef JEMALLOC_HAVE_ATTR_FORMAT_PRINTF */\n\n/*\n * Define overrides for non-standard allocator-related functions if they are\n * present on the system.\n */\n/* #undef JEMALLOC_OVERRIDE_MEMALIGN */\n/* #undef JEMALLOC_OVERRIDE_VALLOC */\n\n/*\n * At least Linux omits the \"const\" in:\n *\n *   size_t malloc_usable_size(const void *ptr);\n *\n * Match the operating system's prototype.\n */\n#define JEMALLOC_USABLE_SIZE_CONST const\n\n/*\n * If defined, specify throw() for the public function prototypes when compiling\n * with C++.  The only justification for this is to match the prototypes that\n * glibc defines.\n */\n/* #undef JEMALLOC_USE_CXX_THROW */\n\n#define LG_SIZEOF_PTR_WIN 3\n\n/* sizeof(void *) == 2^LG_SIZEOF_PTR. */\n#define LG_SIZEOF_PTR LG_SIZEOF_PTR_WIN\n\n/*\n * Name mangling for public symbols is controlled by --with-mangling and\n * --with-jemalloc-prefix.  With default settings the je_ prefix is stripped by\n * these macro definitions.\n */\n\n#  define je_aligned_alloc je_aligned_alloc\n#  define je_calloc je_calloc\n#  define je_dallocx je_dallocx\n#  define je_free je_free\n#  define je_mallctl je_mallctl\n#  define je_mallctlbymib je_mallctlbymib\n#  define je_mallctlnametomib je_mallctlnametomib\n#  define je_malloc je_malloc\n#  define je_malloc_conf je_malloc_conf\n#  define je_malloc_message je_malloc_message\n#  define je_malloc_stats_print je_malloc_stats_print\n#  define je_malloc_usable_size je_malloc_usable_size\n#  define je_mallocx je_mallocx\n#  define je_nallocx je_nallocx\n#  define je_posix_memalign je_posix_memalign\n#  define je_rallocx je_rallocx\n#  define je_realloc je_realloc\n#  define je_sallocx je_sallocx\n#  define je_sdallocx je_sdallocx\n#  define je_xallocx je_xallocx\n\n\n/*\n#include <stdlib.h>\n#include <stdbool.h>\n#include <stdint.h>\n#include <limits.h>\n#include <strings.h>\n*/\n\n#define JEMALLOC_VERSION \"5.0.1-64-gcb3b72b9756d124565ed12e005065ad6f0769568\"\n#define JEMALLOC_VERSION_MAJOR 5\n#define JEMALLOC_VERSION_MINOR 0\n#define JEMALLOC_VERSION_BUGFIX 1\n#define JEMALLOC_VERSION_NREV 64\n#define JEMALLOC_VERSION_GID \"cb3b72b9756d124565ed12e005065ad6f0769568\"\n\n#define MALLOCX_LG_ALIGN(la)\t((int)(la))\n#define MALLOCX_ALIGN(a)\t\t\t\t\t\t\\\n     ((int)(((size_t)(a) < (size_t)INT_MAX) ? ffs((int)(a))-1 :\t\\\n     ffs((int)(((size_t)(a))>>32))+31))\n\n#define MALLOCX_ZERO\t((int)0x40)\n/*\n * Bias tcache index bits so that 0 encodes \"automatic tcache management\", and 1\n * encodes MALLOCX_TCACHE_NONE.\n */\n#define MALLOCX_TCACHE(tc)\t((int)(((tc)+2) << 8))\n#define MALLOCX_TCACHE_NONE\tMALLOCX_TCACHE(-1)\n/*\n * Bias arena index bits so that 0 encodes \"use an automatically chosen arena\".\n */\n#define MALLOCX_ARENA(a)\t((((int)(a))+1) << 20)\n\n/*\n * Use as arena index in \"arena.<i>.{purge,decay,dss}\" and\n * \"stats.arenas.<i>.*\" mallctl interfaces to select all arenas.  This\n * definition is intentionally specified in raw decimal format to support\n * cpp-based string concatenation, e.g.\n *\n *   #define STRINGIFY_HELPER(x) #x\n *   #define STRINGIFY(x) STRINGIFY_HELPER(x)\n *\n *   mallctl(\"arena.\" STRINGIFY(MALLCTL_ARENAS_ALL) \".purge\", NULL, NULL, NULL,\n *       0);\n */\n#define MALLCTL_ARENAS_ALL\t4096\n/*\n * Use as arena index in \"stats.arenas.<i>.*\" mallctl interfaces to select\n * destroyed arenas.\n */\n#define MALLCTL_ARENAS_DESTROYED\t4097\n\n#if defined(__cplusplus) && defined(JEMALLOC_USE_CXX_THROW)\n#  define JEMALLOC_CXX_THROW throw()\n#else\n#  define JEMALLOC_CXX_THROW\n#endif\n\n\n#  define JEMALLOC_ATTR(s)\n#  define JEMALLOC_ALIGNED(s) __declspec(align(s))\n#  define JEMALLOC_ALLOC_SIZE(s)\n#  define JEMALLOC_ALLOC_SIZE2(s1, s2)\n#  define JEMALLOC_EXPORT __declspec(dllexport)\n#  define JEMALLOC_FORMAT_PRINTF(s, i)\n#  define JEMALLOC_NOINLINE __declspec(noinline)\n#  define JEMALLOC_NOTHROW\n#  define JEMALLOC_SECTION(s) __declspec(allocate(s))\n#  define JEMALLOC_RESTRICT_RETURN __declspec(restrict)\n#  define JEMALLOC_ALLOCATOR\n\n/*\n * The je_ prefix on the following public symbol declarations is an artifact\n * of namespace management, and should be omitted in application code unless\n * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle.h).\n */\nextern JEMALLOC_EXPORT const char\t*je_malloc_conf;\nextern JEMALLOC_EXPORT void\t\t(*je_malloc_message)(void *cbopaque, const char *s);\n\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*je_malloc(size_t size)\n    JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1);\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*je_calloc(size_t num, size_t size)\n    JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2);\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\tje_posix_memalign(void **memptr,\n    size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1));\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*je_aligned_alloc(size_t alignment,\n    size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc)\n    JEMALLOC_ALLOC_SIZE(2);\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*je_realloc(void *ptr, size_t size)\n    JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2);\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\tje_free(void *ptr)\n    JEMALLOC_CXX_THROW;\n\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*je_mallocx(size_t size, int flags)\n    JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1);\nJEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN\n    void JEMALLOC_NOTHROW\t*je_rallocx(void *ptr, size_t size,\n    int flags) JEMALLOC_ALLOC_SIZE(2);\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\tje_xallocx(void *ptr, size_t size,\n    size_t extra, int flags);\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\tje_sallocx(const void *ptr,\n    int flags) JEMALLOC_ATTR(pure);\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\tje_dallocx(void *ptr, int flags);\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\tje_sdallocx(void *ptr, size_t size,\n    int flags);\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\tje_nallocx(size_t size, int flags)\n    JEMALLOC_ATTR(pure);\n\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\tje_mallctl(const char *name,\n    void *oldp, size_t *oldlenp, void *newp, size_t newlen);\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\tje_mallctlnametomib(const char *name,\n    size_t *mibp, size_t *miblenp);\nJEMALLOC_EXPORT int JEMALLOC_NOTHROW\tje_mallctlbymib(const size_t *mib,\n    size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW\tje_malloc_stats_print(\n    void (*write_cb)(void *, const char *), void *je_cbopaque,\n    const char *opts);\nJEMALLOC_EXPORT size_t JEMALLOC_NOTHROW\tje_malloc_usable_size(\n    JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW;\n\nJEMALLOC_EXPORT void JEMALLOC_NOTHROW je_set_malloc_conf(const char *name);\nJEMALLOC_EXPORT char* JEMALLOC_NOTHROW je_get_malloc_conf();\ntypedef void(*je_malloc_message_ptr)(void *, const char *);\nJEMALLOC_EXPORT je_malloc_message_ptr je_get_malloc_message_ptr();\nJEMALLOC_EXPORT void je_set_malloc_message_ptr(je_malloc_message_ptr p);\n\ntypedef struct extent_hooks_s extent_hooks_t;\n\n/*\n * void *\n * extent_alloc(extent_hooks_t *extent_hooks, void *new_addr, size_t size,\n *     size_t alignment, bool *zero, bool *commit, unsigned arena_ind);\n */\ntypedef void *(extent_alloc_t)(extent_hooks_t *, void *, size_t, size_t, bool *,\n    bool *, unsigned);\n\n/*\n * bool\n * extent_dalloc(extent_hooks_t *extent_hooks, void *addr, size_t size,\n *     bool committed, unsigned arena_ind);\n */\ntypedef bool (extent_dalloc_t)(extent_hooks_t *, void *, size_t, bool,\n    unsigned);\n\n/*\n * void\n * extent_destroy(extent_hooks_t *extent_hooks, void *addr, size_t size,\n *     bool committed, unsigned arena_ind);\n */\ntypedef void (extent_destroy_t)(extent_hooks_t *, void *, size_t, bool,\n    unsigned);\n\n/*\n * bool\n * extent_commit(extent_hooks_t *extent_hooks, void *addr, size_t size,\n *     size_t offset, size_t length, unsigned arena_ind);\n */\ntypedef bool (extent_commit_t)(extent_hooks_t *, void *, size_t, size_t, size_t,\n    unsigned);\n\n/*\n * bool\n * extent_decommit(extent_hooks_t *extent_hooks, void *addr, size_t size,\n *     size_t offset, size_t length, unsigned arena_ind);\n */\ntypedef bool (extent_decommit_t)(extent_hooks_t *, void *, size_t, size_t,\n    size_t, unsigned);\n\n/*\n * bool\n * extent_purge(extent_hooks_t *extent_hooks, void *addr, size_t size,\n *     size_t offset, size_t length, unsigned arena_ind);\n */\ntypedef bool (extent_purge_t)(extent_hooks_t *, void *, size_t, size_t, size_t,\n    unsigned);\n\n/*\n * bool\n * extent_split(extent_hooks_t *extent_hooks, void *addr, size_t size,\n *     size_t size_a, size_t size_b, bool committed, unsigned arena_ind);\n */\ntypedef bool (extent_split_t)(extent_hooks_t *, void *, size_t, size_t, size_t,\n    bool, unsigned);\n\n/*\n * bool\n * extent_merge(extent_hooks_t *extent_hooks, void *addr_a, size_t size_a,\n *     void *addr_b, size_t size_b, bool committed, unsigned arena_ind);\n */\ntypedef bool (extent_merge_t)(extent_hooks_t *, void *, size_t, void *, size_t,\n    bool, unsigned);\n\nstruct extent_hooks_s {\n\textent_alloc_t\t\t*alloc;\n\textent_dalloc_t\t\t*dalloc;\n\textent_destroy_t\t*destroy;\n\textent_commit_t\t\t*commit;\n\textent_decommit_t\t*decommit;\n\textent_purge_t\t\t*purge_lazy;\n\textent_purge_t\t\t*purge_forced;\n\textent_split_t\t\t*split;\n\textent_merge_t\t\t*merge;\n};\n\n\n}\n\n"
  },
  {
    "path": "jemalloc.Bindings/jemalloc.Bindings.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{C24A6949-BA9E-443B-A67E-188AB489057E}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <RootNamespace>jemalloc.Bindings</RootNamespace>\n    <AssemblyName>jemalloc.Bindings</AssemblyName>\n    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n    <NuGetPackageImportStamp>\n    </NuGetPackageImportStamp>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>x64</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|x64'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>..\\x64\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <DebugType>full</DebugType>\n    <PlatformTarget>x64</PlatformTarget>\n    <ErrorReport>prompt</ErrorReport>\n    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|x64'\">\n    <OutputPath>..\\x64\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <Optimize>true</Optimize>\n    <DebugType>pdbonly</DebugType>\n    <PlatformTarget>x64</PlatformTarget>\n    <ErrorReport>prompt</ErrorReport>\n    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"CppSharp, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\CppSharp.0.8.16\\lib\\CppSharp.dll</HintPath>\n    </Reference>\n    <Reference Include=\"CppSharp.AST, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\CppSharp.0.8.16\\lib\\CppSharp.AST.dll</HintPath>\n    </Reference>\n    <Reference Include=\"CppSharp.Generator, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\CppSharp.0.8.16\\lib\\CppSharp.Generator.dll</HintPath>\n    </Reference>\n    <Reference Include=\"CppSharp.Parser, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\CppSharp.0.8.16\\lib\\CppSharp.Parser.dll</HintPath>\n    </Reference>\n    <Reference Include=\"CppSharp.Parser.CLI, Version=0.0.0.0, Culture=neutral, processorArchitecture=AMD64\">\n      <HintPath>..\\packages\\CppSharp.0.8.16\\lib\\CppSharp.Parser.CLI.dll</HintPath>\n    </Reference>\n    <Reference Include=\"CppSharp.Runtime, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\CppSharp.0.8.16\\lib\\CppSharp.Runtime.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"JemallocLibrary.cs\" />\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"jemalloc-win-msvc.h\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <Import Project=\"..\\packages\\Baseclass.Contrib.Nuget.Output.2.3.0\\build\\net40\\Baseclass.Contrib.Nuget.Output.targets\" Condition=\"Exists('..\\packages\\Baseclass.Contrib.Nuget.Output.2.3.0\\build\\net40\\Baseclass.Contrib.Nuget.Output.targets')\" />\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\packages\\Baseclass.Contrib.Nuget.Output.2.3.0\\build\\net40\\Baseclass.Contrib.Nuget.Output.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\packages\\Baseclass.Contrib.Nuget.Output.2.3.0\\build\\net40\\Baseclass.Contrib.Nuget.Output.targets'))\" />\n  </Target>\n</Project>"
  },
  {
    "path": "jemalloc.Bindings/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Baseclass.Contrib.Nuget.Output\" version=\"2.3.0\" targetFramework=\"net461\" />\n  <package id=\"CppSharp\" version=\"0.8.16\" targetFramework=\"net461\" developmentDependency=\"true\" />\n</packages>"
  },
  {
    "path": "jemalloc.Buffers/JemPinnable.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace jemalloc\n{\n    [StructLayout(LayoutKind.Sequential)]\n    internal sealed class JemPinnable<T>\n    {\n        public T Data;\n    }\n}\n"
  },
  {
    "path": "jemalloc.Buffers/NativeHelpers.cs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Reflection;\nusing System.Diagnostics;\nusing System.Numerics;\nusing System.Runtime.InteropServices;\nusing System.Runtime.CompilerServices;\n\n\nnamespace jemalloc\n{\n    internal static partial class NativeHelpers\n    {\n        public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)\n        {\n            Debug.Assert(searchSpaceLength >= 0);\n            Debug.Assert(valueLength >= 0);\n\n            if (valueLength == 0)\n                return 0;  // A zero-length sequence is always treated as \"found\" at the start of the search space.\n\n            byte valueHead = value;\n            ref byte valueTail = ref Unsafe.Add(ref value, 1);\n            int valueTailLength = valueLength - 1;\n\n            int index = 0;\n            for (; ; )\n            {\n                Debug.Assert(0 <= index && index <= searchSpaceLength); // Ensures no deceptive underflows in the computation of \"remainingSearchSpaceLength\".\n                int remainingSearchSpaceLength = searchSpaceLength - index - valueTailLength;\n                if (remainingSearchSpaceLength <= 0)\n                    break;  // The unsearched portion is now shorter than the sequence we're looking for. So it can't be there.\n\n                // Do a quick search for the first element of \"value\".\n                int relativeIndex = IndexOf(ref Unsafe.Add(ref searchSpace, index), valueHead, remainingSearchSpaceLength);\n                if (relativeIndex == -1)\n                    break;\n                index += relativeIndex;\n\n                // Found the first element of \"value\". See if the tail matches.\n                if (SequenceEqual(ref Unsafe.Add(ref searchSpace, index + 1), ref valueTail, valueTailLength))\n                    return index;  // The tail matched. Return a successful find.\n\n                index++;\n            }\n            return -1;\n        }\n\n        public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)\n        {\n            Debug.Assert(searchSpaceLength >= 0);\n            Debug.Assert(valueLength >= 0);\n\n            if (valueLength == 0)\n                return 0;  // A zero-length sequence is always treated as \"found\" at the start of the search space.\n\n            int index = -1;\n            for (int i = 0; i < valueLength; i++)\n            {\n                var tempIndex = IndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength);\n                if (tempIndex != -1)\n                {\n                    index = (index == -1 || index > tempIndex) ? tempIndex : index;\n                }\n            }\n            return index;\n        }\n\n        public static unsafe int IndexOf(ref byte searchSpace, byte value, int length)\n        {\n            Debug.Assert(length >= 0);\n\n            uint uValue = value; // Use uint for comparisons to avoid unnecessary 8->32 extensions\n            IntPtr index = (IntPtr)0; // Use UIntPtr for arithmetic to avoid unnecessary 64->32->64 truncations\n            IntPtr nLength = (IntPtr)(uint)length;\n\n            if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)\n            {\n                unchecked\n                {\n                    int unaligned = (int)(byte*)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);\n                    nLength = (IntPtr)(uint)((Vector<byte>.Count - unaligned) & (Vector<byte>.Count - 1));\n                }\n            }\n            SequentialScan:\n\n            while ((byte*)nLength >= (byte*)8)\n            {\n                nLength -= 8;\n\n                if (uValue == Unsafe.Add(ref searchSpace, index))\n                    goto Found;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 1))\n                    goto Found1;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 2))\n                    goto Found2;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 3))\n                    goto Found3;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 4))\n                    goto Found4;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 5))\n                    goto Found5;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 6))\n                    goto Found6;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 7))\n                    goto Found7;\n\n                index += 8;\n            }\n\n            if ((byte*)nLength >= (byte*)4)\n            {\n                nLength -= 4;\n\n                if (uValue == Unsafe.Add(ref searchSpace, index))\n                    goto Found;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 1))\n                    goto Found1;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 2))\n                    goto Found2;\n                if (uValue == Unsafe.Add(ref searchSpace, index + 3))\n                    goto Found3;\n\n                index += 4;\n            }\n\n            while ((byte*)nLength > (byte*)0)\n            {\n                nLength -= 1;\n\n                if (uValue == Unsafe.Add(ref searchSpace, index))\n                    goto Found;\n\n                index += 1;\n            }\n\n            if (Vector.IsHardwareAccelerated && ((int)(byte*)index < length))\n            {\n                nLength = (IntPtr)(uint)((length - (uint)index) & ~(Vector<byte>.Count - 1));\n                // Get comparison Vector\n                Vector<byte> vComparison = GetVector(value);\n                while ((byte*)nLength > (byte*)index)\n                {\n                    var vMatches = Vector.Equals(vComparison, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, index)));\n                    if (Vector<byte>.Zero.Equals(vMatches))\n                    {\n                        index += Vector<byte>.Count;\n                        continue;\n                    }\n                    // Find offset of first match\n                    return (int)(byte*)index + LocateFirstFoundByte(vMatches);\n                }\n\n                if ((int)(byte*)index < length)\n                {\n                    unchecked\n                    {\n                        nLength = (IntPtr)(length - (int)(byte*)index);\n                    }\n                    goto SequentialScan;\n                }\n            }\n\n            return -1;\n            Found: // Workaround for https://github.com/dotnet/coreclr/issues/13549\n            return (int)(byte*)index;\n            Found1:\n            return (int)(byte*)(index + 1);\n            Found2:\n            return (int)(byte*)(index + 2);\n            Found3:\n            return (int)(byte*)(index + 3);\n            Found4:\n            return (int)(byte*)(index + 4);\n            Found5:\n            return (int)(byte*)(index + 5);\n            Found6:\n            return (int)(byte*)(index + 6);\n            Found7:\n            return (int)(byte*)(index + 7);\n        }\n\n        public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte value1, int length)\n        {\n            Debug.Assert(length >= 0);\n\n            uint uValue0 = value0; // Use uint for comparisons to avoid unnecessary 8->32 extensions\n            uint uValue1 = value1; // Use uint for comparisons to avoid unnecessary 8->32 extensions\n            IntPtr index = (IntPtr)0; // Use UIntPtr for arithmetic to avoid unnecessary 64->32->64 truncations\n            IntPtr nLength = (IntPtr)(uint)length;\n\n            if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)\n            {\n                unchecked\n                {\n                    int unaligned = (int)(byte*)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);\n                    nLength = (IntPtr)(uint)((Vector<byte>.Count - unaligned) & (Vector<byte>.Count - 1));\n                }\n            }\n            SequentialScan:\n\n            uint lookUp;\n            while ((byte*)nLength >= (byte*)8)\n            {\n                nLength -= 8;\n\n                lookUp = Unsafe.Add(ref searchSpace, index);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found;\n                lookUp = Unsafe.Add(ref searchSpace, index + 1);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found1;\n                lookUp = Unsafe.Add(ref searchSpace, index + 2);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found2;\n                lookUp = Unsafe.Add(ref searchSpace, index + 3);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found3;\n                lookUp = Unsafe.Add(ref searchSpace, index + 4);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found4;\n                lookUp = Unsafe.Add(ref searchSpace, index + 5);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found5;\n                lookUp = Unsafe.Add(ref searchSpace, index + 6);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found6;\n                lookUp = Unsafe.Add(ref searchSpace, index + 7);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found7;\n\n                index += 8;\n            }\n\n            if ((byte*)nLength >= (byte*)4)\n            {\n                nLength -= 4;\n\n                lookUp = Unsafe.Add(ref searchSpace, index);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found;\n                lookUp = Unsafe.Add(ref searchSpace, index + 1);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found1;\n                lookUp = Unsafe.Add(ref searchSpace, index + 2);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found2;\n                lookUp = Unsafe.Add(ref searchSpace, index + 3);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found3;\n\n                index += 4;\n            }\n\n            while ((byte*)nLength > (byte*)0)\n            {\n                nLength -= 1;\n\n                lookUp = Unsafe.Add(ref searchSpace, index);\n                if (uValue0 == lookUp || uValue1 == lookUp)\n                    goto Found;\n\n                index += 1;\n            }\n\n            if (Vector.IsHardwareAccelerated && ((int)(byte*)index < length))\n            {\n                nLength = (IntPtr)(uint)((length - (uint)index) & ~(Vector<byte>.Count - 1));\n                // Get comparison Vector\n                Vector<byte> values0 = GetVector(value0);\n                Vector<byte> values1 = GetVector(value1);\n\n                while ((byte*)nLength > (byte*)index)\n                {\n                    var vData = Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, index));\n                    var vMatches = Vector.BitwiseOr(\n                                    Vector.Equals(vData, values0),\n                                    Vector.Equals(vData, values1));\n                    if (Vector<byte>.Zero.Equals(vMatches))\n                    {\n                        index += Vector<byte>.Count;\n                        continue;\n                    }\n                    // Find offset of first match\n                    return (int)(byte*)index + LocateFirstFoundByte(vMatches);\n                }\n\n                if ((int)(byte*)index < length)\n                {\n                    unchecked\n                    {\n                        nLength = (IntPtr)(length - (int)(byte*)index);\n                    }\n                    goto SequentialScan;\n                }\n            }\n\n            return -1;\n            Found: // Workaround for https://github.com/dotnet/coreclr/issues/13549\n            return (int)(byte*)index;\n            Found1:\n            return (int)(byte*)(index + 1);\n            Found2:\n            return (int)(byte*)(index + 2);\n            Found3:\n            return (int)(byte*)(index + 3);\n            Found4:\n            return (int)(byte*)(index + 4);\n            Found5:\n            return (int)(byte*)(index + 5);\n            Found6:\n            return (int)(byte*)(index + 6);\n            Found7:\n            return (int)(byte*)(index + 7);\n        }\n\n        public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length)\n        {\n            Debug.Assert(length >= 0);\n\n            uint uValue0 = value0; // Use uint for comparisons to avoid unnecessary 8->32 extensions\n            uint uValue1 = value1; // Use uint for comparisons to avoid unnecessary 8->32 extensions\n            uint uValue2 = value2; // Use uint for comparisons to avoid unnecessary 8->32 extensions\n            IntPtr index = (IntPtr)0; // Use UIntPtr for arithmetic to avoid unnecessary 64->32->64 truncations\n            IntPtr nLength = (IntPtr)(uint)length;\n\n            if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)\n            {\n                unchecked\n                {\n                    int unaligned = (int)(byte*)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);\n                    nLength = (IntPtr)(uint)((Vector<byte>.Count - unaligned) & (Vector<byte>.Count - 1));\n                }\n            }\n            SequentialScan:\n\n            uint lookUp;\n            while ((byte*)nLength >= (byte*)8)\n            {\n                nLength -= 8;\n\n                lookUp = Unsafe.Add(ref searchSpace, index);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found;\n                lookUp = Unsafe.Add(ref searchSpace, index + 1);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found1;\n                lookUp = Unsafe.Add(ref searchSpace, index + 2);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found2;\n                lookUp = Unsafe.Add(ref searchSpace, index + 3);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found3;\n                lookUp = Unsafe.Add(ref searchSpace, index + 4);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found4;\n                lookUp = Unsafe.Add(ref searchSpace, index + 5);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found5;\n                lookUp = Unsafe.Add(ref searchSpace, index + 6);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found6;\n                lookUp = Unsafe.Add(ref searchSpace, index + 7);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found7;\n\n                index += 8;\n            }\n\n            if ((byte*)nLength >= (byte*)4)\n            {\n                nLength -= 4;\n\n                lookUp = Unsafe.Add(ref searchSpace, index);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found;\n                lookUp = Unsafe.Add(ref searchSpace, index + 1);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found1;\n                lookUp = Unsafe.Add(ref searchSpace, index + 2);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found2;\n                lookUp = Unsafe.Add(ref searchSpace, index + 3);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found3;\n\n                index += 4;\n            }\n\n            while ((byte*)nLength > (byte*)0)\n            {\n                nLength -= 1;\n\n                lookUp = Unsafe.Add(ref searchSpace, index);\n                if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp)\n                    goto Found;\n\n                index += 1;\n            }\n\n            if (Vector.IsHardwareAccelerated && ((int)(byte*)index < length))\n            {\n                nLength = (IntPtr)(uint)((length - (uint)index) & ~(Vector<byte>.Count - 1));\n                // Get comparison Vector\n                Vector<byte> values0 = GetVector(value0);\n                Vector<byte> values1 = GetVector(value1);\n                Vector<byte> values2 = GetVector(value2);\n                while ((byte*)nLength > (byte*)index)\n                {\n                    var vData = Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, index));\n\n                    var vMatches = Vector.BitwiseOr(\n                                    Vector.BitwiseOr(\n                                        Vector.Equals(vData, values0),\n                                        Vector.Equals(vData, values1)),\n                                    Vector.Equals(vData, values2));\n\n                    if (Vector<byte>.Zero.Equals(vMatches))\n                    {\n                        index += Vector<byte>.Count;\n                        continue;\n                    }\n                    // Find offset of first match\n                    return (int)(byte*)index + LocateFirstFoundByte(vMatches);\n                }\n\n                if ((int)(byte*)index < length)\n                {\n                    unchecked\n                    {\n                        nLength = (IntPtr)(length - (int)(byte*)index);\n                    }\n                    goto SequentialScan;\n                }\n            }\n\n            return -1;\n            Found: // Workaround for https://github.com/dotnet/coreclr/issues/13549\n            return (int)(byte*)index;\n            Found1:\n            return (int)(byte*)(index + 1);\n            Found2:\n            return (int)(byte*)(index + 2);\n            Found3:\n            return (int)(byte*)(index + 3);\n            Found4:\n            return (int)(byte*)(index + 4);\n            Found5:\n            return (int)(byte*)(index + 5);\n            Found6:\n            return (int)(byte*)(index + 6);\n            Found7:\n            return (int)(byte*)(index + 7);\n        }\n\n        public static unsafe bool SequenceEqual(ref byte first, ref byte second, int length)\n        {\n            Debug.Assert(length >= 0);\n\n            if (Unsafe.AreSame(ref first, ref second))\n                goto Equal;\n\n            IntPtr i = (IntPtr)0; // Use IntPtr and byte* for arithmetic to avoid unnecessary 64->32->64 truncations\n            IntPtr n = (IntPtr)length;\n\n#if !netstandard11\n            if (Vector.IsHardwareAccelerated && (byte*)n >= (byte*)Vector<byte>.Count)\n            {\n                n -= Vector<byte>.Count;\n                while ((byte*)n > (byte*)i)\n                {\n                    if (Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref first, i)) !=\n                        Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref second, i)))\n                    {\n                        goto NotEqual;\n                    }\n                    i += Vector<byte>.Count;\n                }\n                return Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref first, n)) ==\n                       Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref second, n));\n            }\n#endif\n\n            if ((byte*)n >= (byte*)sizeof(UIntPtr))\n            {\n                n -= sizeof(UIntPtr);\n                while ((byte*)n > (byte*)i)\n                {\n                    if (Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref first, i)) !=\n                        Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref second, i)))\n                    {\n                        goto NotEqual;\n                    }\n                    i += sizeof(UIntPtr);\n                }\n                return Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref first, n)) ==\n                       Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref second, n));\n            }\n\n            while ((byte*)n > (byte*)i)\n            {\n                if (Unsafe.AddByteOffset(ref first, i) != Unsafe.AddByteOffset(ref second, i))\n                    goto NotEqual;\n                i += 1;\n            }\n\n            Equal:\n            return true;\n\n            NotEqual: // Workaround for https://github.com/dotnet/coreclr/issues/13549\n            return false;\n        }\n\n#if !netstandard11\n        // Vector sub-search adapted from https://github.com/aspnet/KestrelHttpServer/pull/1138\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static int LocateFirstFoundByte(Vector<byte> match)\n        {\n            var vector64 = Vector.AsVectorUInt64(match);\n            ulong candidate = 0;\n            int i = 0;\n            // Pattern unrolled by jit https://github.com/dotnet/coreclr/pull/8001\n            for (; i < Vector<ulong>.Count; i++)\n            {\n                candidate = vector64[i];\n                if (candidate != 0)\n                {\n                    break;\n                }\n            }\n\n            // Single LEA instruction with jitted const (using function result)\n            return i * 8 + LocateFirstFoundByte(candidate);\n        }\n#endif\n\n#if !netstandard11\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static int LocateFirstFoundByte(ulong match)\n        {\n            unchecked\n            {\n                // Flag least significant power of two bit\n                var powerOfTwoFlag = match ^ (match - 1);\n                // Shift all powers of two into the high byte and extract\n                return (int)((powerOfTwoFlag * XorPowerOfTwoToHighByte) >> 57);\n            }\n        }\n#endif\n\n#if !netstandard11\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private static Vector<byte> GetVector(byte vectorByte)\n        {\n#if !netcoreapp\n            // Vector<byte> .ctor doesn't become an intrinsic due to detection issue\n            // However this does cause it to become an intrinsic (with additional multiply and reg->reg copy)\n            // https://github.com/dotnet/coreclr/issues/7459#issuecomment-253965670\n            return Vector.AsVectorByte(new Vector<uint>(vectorByte * 0x01010101u));\n#else\n            return new Vector<byte>(vectorByte);\n#endif\n        }\n#endif\n\n#if !netstandard11\n        private const ulong XorPowerOfTwoToHighByte = (0x07ul |\n                                                       0x06ul << 8 |\n                                                       0x05ul << 16 |\n                                                       0x04ul << 24 |\n                                                       0x03ul << 32 |\n                                                       0x02ul << 40 |\n                                                       0x01ul << 48) + 1;\n#endif\n\n        public static int IndexOf<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength)\n            where T : IEquatable<T>\n        {\n            Debug.Assert(searchSpaceLength >= 0);\n            Debug.Assert(valueLength >= 0);\n\n            if (valueLength == 0)\n                return 0;  // A zero-length sequence is always treated as \"found\" at the start of the search space.\n\n            T valueHead = value;\n            ref T valueTail = ref Unsafe.Add(ref value, 1);\n            int valueTailLength = valueLength - 1;\n\n            int index = 0;\n            for (;;)\n            {\n                Debug.Assert(0 <= index && index <= searchSpaceLength); // Ensures no deceptive underflows in the computation of \"remainingSearchSpaceLength\".\n                int remainingSearchSpaceLength = searchSpaceLength - index - valueTailLength;\n                if (remainingSearchSpaceLength <= 0)\n                    break;  // The unsearched portion is now shorter than the sequence we're looking for. So it can't be there.\n\n                // Do a quick search for the first element of \"value\".\n                int relativeIndex = IndexOf(ref Unsafe.Add(ref searchSpace, index), valueHead, remainingSearchSpaceLength);\n                if (relativeIndex == -1)\n                    break;\n                index += relativeIndex;\n\n                // Found the first element of \"value\". See if the tail matches.\n                if (SequenceEqual(ref Unsafe.Add(ref searchSpace, index + 1), ref valueTail, valueTailLength))\n                    return index;  // The tail matched. Return a successful find.\n\n                index++;\n            }\n            return -1;\n        }\n\n        public static unsafe int IndexOf<T>(ref T searchSpace, T value, int length)\n            where T : IEquatable<T>\n        {\n            Debug.Assert(length >= 0);\n\n            IntPtr index = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations\n            while (length >= 8)\n            {\n                length -= 8;\n\n                if (value.Equals(Unsafe.Add(ref searchSpace, index)))\n                    goto Found;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 1)))\n                    goto Found1;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 2)))\n                    goto Found2;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 3)))\n                    goto Found3;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 4)))\n                    goto Found4;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 5)))\n                    goto Found5;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 6)))\n                    goto Found6;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 7)))\n                    goto Found7;\n\n                index += 8;\n            }\n\n            if (length >= 4)\n            {\n                length -= 4;\n\n                if (value.Equals(Unsafe.Add(ref searchSpace, index)))\n                    goto Found;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 1)))\n                    goto Found1;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 2)))\n                    goto Found2;\n                if (value.Equals(Unsafe.Add(ref searchSpace, index + 3)))\n                    goto Found3;\n\n                index += 4;\n            }\n\n            while (length > 0)\n            {\n                if (value.Equals(Unsafe.Add(ref searchSpace, index)))\n                    goto Found;\n\n                index += 1;\n                length--;\n            }\n            return -1;\n\n        Found: // Workaround for https://github.com/dotnet/coreclr/issues/13549\n            return (int)(byte*)index;\n        Found1:\n            return (int)(byte*)(index + 1);\n        Found2:\n            return (int)(byte*)(index + 2);\n        Found3:\n            return (int)(byte*)(index + 3);\n        Found4:\n            return (int)(byte*)(index + 4);\n        Found5:\n            return (int)(byte*)(index + 5);\n        Found6:\n            return (int)(byte*)(index + 6);\n        Found7:\n            return (int)(byte*)(index + 7);\n        }\n\n        public static bool SequenceEqual<T>(ref T first, ref T second, int length)\n            where T : IEquatable<T>\n        {\n            Debug.Assert(length >= 0);\n\n            if (Unsafe.AreSame(ref first, ref second))\n                goto Equal;\n\n            IntPtr index = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations\n            while (length >= 8)\n            {\n                length -= 8;\n\n                if (!Unsafe.Add(ref first, index).Equals(Unsafe.Add(ref second, index)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 1).Equals(Unsafe.Add(ref second, index + 1)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 2).Equals(Unsafe.Add(ref second, index + 2)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 3).Equals(Unsafe.Add(ref second, index + 3)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 4).Equals(Unsafe.Add(ref second, index + 4)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 5).Equals(Unsafe.Add(ref second, index + 5)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 6).Equals(Unsafe.Add(ref second, index + 6)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 7).Equals(Unsafe.Add(ref second, index + 7)))\n                    goto NotEqual;\n\n                index += 8;\n            }\n\n            if (length >= 4)\n            {\n                length -= 4;\n\n                if (!Unsafe.Add(ref first, index).Equals(Unsafe.Add(ref second, index)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 1).Equals(Unsafe.Add(ref second, index + 1)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 2).Equals(Unsafe.Add(ref second, index + 2)))\n                    goto NotEqual;\n                if (!Unsafe.Add(ref first, index + 3).Equals(Unsafe.Add(ref second, index + 3)))\n                    goto NotEqual;\n\n                index += 4;\n            }\n\n            while (length > 0)\n            {\n                if (!Unsafe.Add(ref first, index).Equals(Unsafe.Add(ref second, index)))\n                    goto NotEqual;\n                index += 1;\n                length--;\n            }\n\n        Equal:\n            return true;\n\n        NotEqual: // Workaround for https://github.com/dotnet/coreclr/issues/13549\n            return false;\n        }\n\n        /// <summary>\n        /// Implements the copy functionality used by Span and ReadOnlySpan.\n        ///\n        /// NOTE: Fast span implements TryCopyTo in corelib and therefore this implementation\n        ///       is only used by portable span. The code must live in code that only compiles\n        ///       for portable span which means either each individual span implementation\n        ///       of this shared code file. Other shared SpanHelper.X.cs files are compiled\n        ///       for both portable and fast span implementations.\n        /// </summary>\n        public static unsafe void CopyTo<T>(ref T dst, int dstLength, ref T src, int srcLength)\n        {\n            Debug.Assert(dstLength != 0);\n\n            IntPtr srcByteCount = Unsafe.ByteOffset(ref src, ref Unsafe.Add(ref src, srcLength));\n            IntPtr dstByteCount = Unsafe.ByteOffset(ref dst, ref Unsafe.Add(ref dst, dstLength));\n\n            IntPtr diff = Unsafe.ByteOffset(ref src, ref dst);\n\n            bool isOverlapped = (sizeof(IntPtr) == sizeof(int))\n                ? (uint)diff < (uint)srcByteCount || (uint)diff > (uint)-(int)dstByteCount\n                : (ulong)diff < (ulong)srcByteCount || (ulong)diff > (ulong)-(long)dstByteCount;\n\n            if (!isOverlapped && !NativeHelpers.IsReferenceOrContainsReferences<T>())\n            {\n                ref byte dstBytes = ref Unsafe.As<T, byte>(ref dst);\n                ref byte srcBytes = ref Unsafe.As<T, byte>(ref src);\n                ulong byteCount = (ulong)srcByteCount;\n                ulong index = 0;\n\n                while (index < byteCount)\n                {\n                    uint blockSize = (byteCount - index) > uint.MaxValue ? uint.MaxValue : (uint)(byteCount - index);\n                    Unsafe.CopyBlock(\n                        ref Unsafe.Add(ref dstBytes, (IntPtr)index),\n                        ref Unsafe.Add(ref srcBytes, (IntPtr)index),\n                        blockSize);\n                    index += blockSize;\n                }\n            }\n            else\n            {\n                bool srcGreaterThanDst = (sizeof(IntPtr) == sizeof(int))\n                    ? (uint)diff > (uint)-(int)dstByteCount\n                    : (ulong)diff > (ulong)-(long)dstByteCount;\n\n                int direction = srcGreaterThanDst ? 1 : -1;\n                int runCount = srcGreaterThanDst ? 0 : srcLength - 1;\n\n                int loopCount = 0;\n                for (; loopCount < (srcLength & ~7); loopCount += 8)\n                {\n                    Unsafe.Add<T>(ref dst, runCount + direction * 0) = Unsafe.Add<T>(ref src, runCount + direction * 0);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 1) = Unsafe.Add<T>(ref src, runCount + direction * 1);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 2) = Unsafe.Add<T>(ref src, runCount + direction * 2);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 3) = Unsafe.Add<T>(ref src, runCount + direction * 3);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 4) = Unsafe.Add<T>(ref src, runCount + direction * 4);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 5) = Unsafe.Add<T>(ref src, runCount + direction * 5);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 6) = Unsafe.Add<T>(ref src, runCount + direction * 6);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 7) = Unsafe.Add<T>(ref src, runCount + direction * 7);\n                    runCount += direction * 8;\n                }\n                if (loopCount < (srcLength & ~3))\n                {\n                    Unsafe.Add<T>(ref dst, runCount + direction * 0) = Unsafe.Add<T>(ref src, runCount + direction * 0);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 1) = Unsafe.Add<T>(ref src, runCount + direction * 1);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 2) = Unsafe.Add<T>(ref src, runCount + direction * 2);\n                    Unsafe.Add<T>(ref dst, runCount + direction * 3) = Unsafe.Add<T>(ref src, runCount + direction * 3);\n                    runCount += direction * 4;\n                    loopCount += 4;\n                }\n                for (; loopCount < srcLength; ++loopCount)\n                {\n                    Unsafe.Add<T>(ref dst, runCount) = Unsafe.Add<T>(ref src, runCount);\n                    runCount += direction;\n                }\n            }\n        }\n\n        /// <summary>\n        /// Computes \"start + index * sizeof(T)\", using the unsigned IntPtr-sized multiplication for 32 and 64 bits.\n        ///\n        /// Assumptions:\n        ///     Start and index are non-negative, and already pre-validated to be within the valid range of their containing Span.\n        ///\n        ///     If the byte length (Span.Length * sizeof(T)) does an unsigned overflow (i.e. the buffer wraps or is too big to fit within the address space),\n        ///     the behavior is undefined.\n        ///\n        /// </summary>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public static IntPtr Add<T>(this IntPtr start, int index)\n        {\n            Debug.Assert(start.ToInt64() >= 0);\n            Debug.Assert(index >= 0);\n\n            unsafe\n            {\n                if (sizeof(IntPtr) == sizeof(int))\n                {\n                    // 32-bit path.\n                    uint byteLength = (uint)index * (uint)Unsafe.SizeOf<T>();\n                    return (IntPtr)(((byte*)start) + byteLength);\n                }\n                else\n                {\n                    // 64-bit path.\n                    ulong byteLength = (ulong)index * (ulong)Unsafe.SizeOf<T>();\n                    return (IntPtr)(((byte*)start) + byteLength);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Determine if a type is eligible for storage in unmanaged memory.\n        /// Portable equivalent of RuntimeHelpers.IsReferenceOrContainsReferences{T}()\n        /// </summary>\n        public static bool IsReferenceOrContainsReferences<T>() => PerTypeValues<T>.IsReferenceOrContainsReferences;\n\n        private static bool IsReferenceOrContainsReferencesCore(Type type)\n        {\n            if (type.GetTypeInfo().IsPrimitive) // This is hopefully the common case. All types that return true for this are value types w/out embedded references.\n                return false;\n\n            if (!type.GetTypeInfo().IsValueType)\n                return true;\n\n            // If type is a Nullable<> of something, unwrap it first.\n            Type underlyingNullable = Nullable.GetUnderlyingType(type);\n            if (underlyingNullable != null)\n                type = underlyingNullable;\n\n            if (type.GetTypeInfo().IsEnum)\n                return false;\n\n            foreach (FieldInfo field in type.GetTypeInfo().DeclaredFields)\n            {\n                if (field.IsStatic)\n                    continue;\n                if (IsReferenceOrContainsReferencesCore(field.FieldType))\n                    return true;\n            }\n            return false;\n        }\n\n        public static class PerTypeValues<T>\n        {\n            //\n            // Latch to ensure that excruciatingly expensive validation check for constructing a Span around a raw pointer is done\n            // only once per type.\n            //\n            public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T));\n\n            public static readonly T[] EmptyArray = new T[0];\n\n            public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment();\n\n            // Array header sizes are a runtime implementation detail and aren't the same across all runtimes. (The CLR made a tweak after 4.5, and Mono has an extra Bounds pointer.)\n            private static IntPtr MeasureArrayAdjustment()\n            {\n                T[] sampleArray = new T[1];\n                return Unsafe.ByteOffset<T>(ref Unsafe.As<JemPinnable<T>>(sampleArray).Data, ref sampleArray[0]);\n            }\n        }\n\n        public unsafe static void ClearLessThanPointerSized(byte* ptr, UIntPtr byteLength)\n        {\n            if (sizeof(UIntPtr) == sizeof(uint))\n            {\n                Unsafe.InitBlockUnaligned(ptr, 0, (uint)byteLength);\n            }\n            else\n            {\n                // PERF: Optimize for common case of length <= uint.MaxValue\n                ulong bytesRemaining = (ulong)byteLength;\n                uint bytesToClear = (uint)(bytesRemaining & uint.MaxValue);\n                Unsafe.InitBlockUnaligned(ptr, 0, bytesToClear);\n                bytesRemaining -= bytesToClear;\n                ptr += bytesToClear;\n                // Clear any bytes > uint.MaxValue\n                while (bytesRemaining > 0)\n                {\n                    bytesToClear = (bytesRemaining >= uint.MaxValue) ? uint.MaxValue : (uint)bytesRemaining;\n                    Unsafe.InitBlockUnaligned(ptr, 0, bytesToClear);\n                    ptr += bytesToClear;\n                    bytesRemaining -= bytesToClear;\n                }\n            }\n        }\n\n        public static unsafe void ClearLessThanPointerSized(ref byte b, UIntPtr byteLength)\n        {\n            if (sizeof(UIntPtr) == sizeof(uint))\n            {\n                Unsafe.InitBlockUnaligned(ref b, 0, (uint)byteLength);\n            }\n            else\n            {\n                // PERF: Optimize for common case of length <= uint.MaxValue\n                ulong bytesRemaining = (ulong)byteLength;\n                uint bytesToClear = (uint)(bytesRemaining & uint.MaxValue);\n                Unsafe.InitBlockUnaligned(ref b, 0, bytesToClear);\n                bytesRemaining -= bytesToClear;\n                long byteOffset = bytesToClear;\n                // Clear any bytes > uint.MaxValue\n                while (bytesRemaining > 0)\n                {\n                    bytesToClear = (bytesRemaining >= uint.MaxValue) ? uint.MaxValue : (uint)bytesRemaining;\n                    ref byte bOffset = ref Unsafe.Add(ref b, (IntPtr)byteOffset);\n                    Unsafe.InitBlockUnaligned(ref bOffset, 0, bytesToClear);\n                    byteOffset += bytesToClear;\n                    bytesRemaining -= bytesToClear;\n                }\n            }\n        }\n\n        public unsafe static void ClearPointerSizedWithoutReferences(ref byte b, UIntPtr byteLength)\n        {\n            // TODO: Perhaps do switch casing to improve small size perf\n\n            var i = IntPtr.Zero;\n            while (i.LessThanEqual(byteLength - sizeof(Reg64)))\n            {\n                Unsafe.As<byte, Reg64>(ref Unsafe.Add<byte>(ref b, i)) = default(Reg64);\n                i += sizeof(Reg64);\n            }\n            if (i.LessThanEqual(byteLength - sizeof(Reg32)))\n            {\n                Unsafe.As<byte, Reg32>(ref Unsafe.Add<byte>(ref b, i)) = default(Reg32);\n                i += sizeof(Reg32);\n            }\n            if (i.LessThanEqual(byteLength - sizeof(Reg16)))\n            {\n                Unsafe.As<byte, Reg16>(ref Unsafe.Add<byte>(ref b, i)) = default(Reg16);\n                i += sizeof(Reg16);\n            }\n            if (i.LessThanEqual(byteLength - sizeof(long)))\n            {\n                Unsafe.As<byte, long>(ref Unsafe.Add<byte>(ref b, i)) = 0;\n                i += sizeof(long);\n            }\n            // JIT: Should elide this if 64-bit\n            if (sizeof(IntPtr) == sizeof(int))\n            {\n                if (i.LessThanEqual(byteLength - sizeof(int)))\n                {\n                    Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, i)) = 0;\n                    i += sizeof(int);\n                }\n            }\n        }\n\n        public unsafe static void ClearPointerSizedWithReferences(ref IntPtr ip, UIntPtr pointerSizeLength)\n        {\n            // TODO: Perhaps do switch casing to improve small size perf\n\n            var i = IntPtr.Zero;\n            var n = IntPtr.Zero;\n            while ((n = i + 8).LessThanEqual(pointerSizeLength))\n            {\n                Unsafe.Add<IntPtr>(ref ip, i + 0) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 1) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 2) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 3) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 4) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 5) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 6) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 7) = default(IntPtr);\n                i = n;\n            }\n            if ((n = i + 4).LessThanEqual(pointerSizeLength))\n            {\n                Unsafe.Add<IntPtr>(ref ip, i + 0) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 1) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 2) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 3) = default(IntPtr);\n                i = n;\n            }\n            if ((n = i + 2).LessThanEqual(pointerSizeLength))\n            {\n                Unsafe.Add<IntPtr>(ref ip, i + 0) = default(IntPtr);\n                Unsafe.Add<IntPtr>(ref ip, i + 1) = default(IntPtr);\n                i = n;\n            }\n            if ((i + 1).LessThanEqual(pointerSizeLength))\n            {\n                Unsafe.Add<IntPtr>(ref ip, i) = default(IntPtr);\n            }\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        private unsafe static bool LessThanEqual(this IntPtr index, UIntPtr length)\n        {\n            return (sizeof(UIntPtr) == sizeof(uint))\n                ? (int)index <= (int)length\n                : (long)index <= (long)length;\n        }\n\n        [StructLayout(LayoutKind.Sequential, Size = 64)]\n        private struct Reg64 { }\n        [StructLayout(LayoutKind.Sequential, Size = 32)]\n        private struct Reg32 { }\n        [StructLayout(LayoutKind.Sequential, Size = 16)]\n        private struct Reg16 { }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Buffers/NativeMemory.cs",
    "content": "﻿using System;\nusing System.Buffers;\nusing System.Runtime.InteropServices;\nusing System.Diagnostics.Contracts;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing System.Reflection;\nusing System.Runtime.ConstrainedExecution;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Threading;\n\nnamespace jemalloc.Buffers\n{\n    public class NativeMemory<T> : OwnedMemory<T> where T : struct\n    {\n        #region Constructors\n        public NativeMemory(int length) : base()\n        {\n            if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())\n            {\n                throw new ArgumentException(\"Only structures without reference fields can be used with this class.\");\n            }\n            this.length = length;\n            Allocate();\n        }\n\n        public NativeMemory(params T[] values) : this(values.Length)\n        {\n            Span<T> span = Span;\n            for (int i = 0; i < length; i++)\n            {\n                span[i] = values[i];\n            }\n        }\n        #endregion\n\n        #region Overriden members\n        public override int Length => length;\n        \n        protected override bool IsRetained => referenceCount > 0;\n\n        public override bool IsDisposed => disposed;\n\n        public unsafe override Span<T> Span\n        {\n            get\n            {\n                return new Span<T>(ptr.ToPointer(), Length);\n            }\n        }\n\n        public override void Retain()\n        {\n            if (IsDisposed)\n            {\n                throw new InvalidOperationException(\"This buffer has been disposed.\");\n            }\n            else\n            {\n                Interlocked.Increment(ref referenceCount);\n            }\n        }\n\n        public override bool Release()\n        {\n            if (IsDisposed)\n            {\n                throw new InvalidOperationException(\"This buffer has been disposed.\");\n            }\n            int newRefCount = Interlocked.Decrement(ref referenceCount);\n            if (newRefCount < 0)\n            {\n                throw new InvalidOperationException(\"Reference count was decremented to < 0.\");\n            }\n            else if (newRefCount == 0)\n            {\n                OnNoReferences();\n                return false;\n            }\n            else\n            {\n                return true;\n            }\n        }\n\n        public override MemoryHandle Pin()\n        {\n            Retain();\n            unsafe\n            {\n                return new MemoryHandle(this, ptr.ToPointer());\n            }\n        }\n\n        protected override bool TryGetArray(out ArraySegment<T> arraySegment)\n        {\n            arraySegment = default;\n            return false;\n        }\n        #endregion\n\n        #region Properties\n        public ulong SizeInBytes => sizeInBytes;\n        public int ReferenceCount => referenceCount;\n        #endregion\n\n        #region Methods\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public Tensor<T> AsTensor(params int[] dimensions)\n        {\n            Retain();\n            return new DenseTensor<T>(this.Memory, new ReadOnlySpan<int>(dimensions), false);\n        }\n\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]\n        public unsafe Vector<T> AsVector()\n        {\n            int count = Vector<T>.Count;\n            if (!NumericTypes.Contains(CLRType))\n            {\n                throw new InvalidOperationException($\"{CLRType.Name} is not a numeric type.\");\n            }\n            else if (length != count)\n            {\n                throw new InvalidOperationException($\"The length of the memory buffer must be {Vector<T>.Count} elements to create a vector of type {CLRType.Name}.\");\n            }\n            else\n            {\n                Retain();\n                object[] args = new object[2] { ptr, 0 };\n                Vector<T> v = (Vector<T>)VectorInternalConstructorUsingPointer.Invoke(args);\n                return v;\n            }\n        }\n\n        protected virtual IntPtr Allocate()\n        {\n            ptr = Jem.Calloc((ulong)length, (ulong) ElementSizeInBytes);\n            sizeInBytes = (ulong)Length * (ulong) ElementSizeInBytes;\n            return ptr;\n        }\n\n        protected virtual void OnNoReferences() {}\n\n        \n        protected bool IsNumericType()\n        {\n\n            if (\n                CLRType == ByteCLRType || CLRType == SByteCLRType ||\n                CLRType == UInt16CLRType || CLRType == Int16CLRType ||\n                CLRType == UInt32CLRType || CLRType == Int32CLRType ||\n                CLRType == UInt64CLRType || CLRType == Int64CLRType\n            )\n            {\n                return true;\n            }\n            else\n            {\n                return false;\n            }\n        }\n        #endregion\n\n        #region Operators\n        public ref T this[int index]\n        {\n            [MethodImpl(MethodImplOptions.AggressiveInlining)]\n            get\n            {\n                Contract.Requires(!IsDisposed);\n                if ((uint)index >= (Length))\n                    throw new IndexOutOfRangeException();\n                unsafe\n                {\n                    return ref Unsafe.Add(ref Unsafe.AsRef<T>(ptr.ToPointer()), index);\n                }\n            }\n        }\n        #endregion\n\n        #region Fields\n        protected static readonly Type CLRType = typeof(T);\n        protected static readonly T Element = default;\n        protected static readonly int ElementSizeInBytes = Marshal.SizeOf(Element);\n        private static ConstructorInfo VectorInternalConstructorUsingPointer = typeof(Vector<T>).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null,\n            new Type[] { typeof(void*), typeof(int) }, null);\n        private static readonly Type ByteCLRType = typeof(Byte);\n        private static readonly Type SByteCLRType = typeof(SByte);\n        private static readonly Type Int16CLRType = typeof(Int16);\n        private static readonly Type UInt16CLRType = typeof(UInt16);\n        private static readonly Type Int32CLRType = typeof(Int32);\n        private static readonly Type UInt32CLRType = typeof(UInt32);\n        private static readonly Type Int64CLRType = typeof(Int64);\n        private static readonly Type UInt64CLRType = typeof(UInt64);\n        private static readonly Type SingleCLRType = typeof(Single);\n        private static readonly Type DoubleCLRType = typeof(Double);\n        private static readonly Type StringCLRType = typeof(String);\n        private static readonly HashSet<Type> NumericTypes = new HashSet<Type>(new Type[]\n        {\n            ByteCLRType, SByteCLRType, Int16CLRType, UInt16CLRType, Int32CLRType, UInt32CLRType, Int64CLRType, UInt64CLRType,\n            SingleCLRType, DoubleCLRType\n        });\n        IntPtr ptr;\n        int length;\n        ulong sizeInBytes;\n        int referenceCount;\n        bool disposed;\n\n        #endregion\n\n        #region Disposer and finalizer\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && referenceCount > 0)\n            {\n                throw new InvalidOperationException($\"This buffer cannot be disposed until all references are released. Reference count is {referenceCount}.\");\n            }\n            if (ptr != null)\n            {\n                Jem.Free(ptr);\n            }\n            ptr = IntPtr.Zero;\n            disposed = disposing;\n        }\n\n        ~NativeMemory()\n        {\n            Dispose(false);\n        }\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Buffers/jemalloc.Buffers.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.0</TargetFramework>\n    <Platforms>AnyCPU;x64</Platforms>\n    <LangVersion>7.1</LangVersion>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <LangVersion>7.1</LangVersion>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <OutputPath>..\\x64\\Debug\\</OutputPath>\n    <PlatformTarget>x64</PlatformTarget>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LangVersion>7.1</LangVersion>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <OutputPath>..\\x64\\Debug\\</OutputPath>\n    <PlatformTarget>x64</PlatformTarget>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\n    <PlatformTarget>x64</PlatformTarget>\n    <LangVersion>7.1</LangVersion>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <PlatformTarget>x64</PlatformTarget>\n    <OutputPath>..\\x64\\Release</OutputPath>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <LangVersion>7.1</LangVersion>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"System.Numerics.Tensors\" Version=\"0.1.0-e171125-2\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\jemalloc.Api\\jemalloc.Api.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "jemalloc.Cli/Options.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing CommandLine;\nusing CommandLine.Text;\n\nnamespace jemalloc.Cli\n{\n    class Options\n    {\n        [Option('u', \"unsigned\", Required = false, HelpText = \"Use the unsigned version of the underlying data type.\")]\n        public bool Unsigned { get; set; }\n\n        [Option('b', \"int8\", Required = false, HelpText = \"Use byte as the underlying data type.\", SetName = \"type\")]\n        public bool Int8 { get; set; }\n\n        [Option('h', \"int16\", Required = false, HelpText = \"Use Int16 short integer as the underlying data type.\", SetName = \"type\")]\n        public bool Int16 { get; set; }\n\n        [Option('i', \"int32\", Required = false, HelpText = \"Use Int32 integer as the underlying data type.\", SetName = \"type\")]\n        public bool Int32 { get; set; }\n\n        [Option('l', \"int64\", Required = false, HelpText = \"Use Int64 long integer as the underlying data type.\", SetName = \"type\")]\n        public bool Int64 { get; set; }\n\n        [Option('f', \"float\", Required = false, HelpText = \"Use single-precision floating point as the underlying data type.\", SetName = \"type\")]\n        public bool Float { get; set; }\n\n        [Option('d', \"double\", Required = false, HelpText = \"Use double-precision floating point as the underlying data type.\", SetName = \"type\")]\n        public bool Double { get; set; }\n\n        [Option('s', \"string\", Required = false, HelpText = \"Use String as the underlying data type.\", SetName = \"type\")]\n        public bool String { get; set; }\n\n        [Option(\"udt\", Required = false, HelpText = \"Use a user-defined data type as the underlying data type.\", SetName = \"type\")]\n        public bool Udt { get; set; }\n\n        [Option('c', \"cold-start\", Required = false, HelpText = \"Don't run warmup phase of benchmarks.\")]\n        public bool ColdStart { get; set; }\n\n        [Option(\"once\", Required = false, HelpText = \"Run 1 iteration of benchmarks.\")]\n        public bool Once { get; set; }\n\n        [Option('t', \"target-count\", Required = false, HelpText = \"Set the target count of benchmark runs.\", Default = 0)]\n        public int TargetCount { get; set; }\n\n        [Option(\"debug\", Required = false, HelpText = \"Run benchmarks in debug mode.\")]\n        public bool Debug { get; set; }\n\n    }\n\n    [Verb(\"malloc\", HelpText = \"Benchmark native memory allocation using jemalloc vs. .NET managed heap and Large Object Heap allocation.\")]\n    class MallocBenchmarkOptions : Options\n    {\n        [Option(\"create\", Required = false, HelpText = \"Benchmark malloc vs managed array alloc.\")]\n        public bool Create { get; set; }\n\n        [Option(\"fill\", Required = false, HelpText = \"Benchmark fill Span<T> on system unmanaged heap vs fill managed arrays.\")]\n        public bool Fill { get; set; }\n\n        [Option(\"fragment\", Required = false, HelpText = \"Run an allocation pattern that fragments the LOH vs. native memory.\")]\n        public bool Fragment { get; set; }\n\n        [Value(0, Required = true, HelpText = \"The sizes of data structures to benchmark.\")]\n        public IEnumerable<int> Sizes { get; set; }\n    }\n\n    [Verb(\"buffer\", HelpText = \"Benchmark FixedBuffer arrays backed by native memory allocated using jemalloc vs. .NET managed arrays.\")]\n    class FixedBufferBenchmarkOptions : Options\n    {\n        [Option(\"create\", Required = false, HelpText = \"Benchmark native array creation vs managed arrays.\")]\n        public bool Create { get; set; }\n\n        [Option(\"fill\", Required = false, HelpText = \"Benchmark fill native array vs managed arrays.\")]\n        public bool Fill { get; set; }\n\n        [Option(\"math\", Required = false, HelpText = \"Benchmark arithmetic and other math operations on native array vs managed arrays.\")]\n        public bool Math { get; set; }\n\n        [Value(0, Required = true, HelpText = \"The sizes of data structures to benchmark.\")]\n        public IEnumerable<int> Sizes { get; set; }\n    }\n\n    [Verb(\"safe\", HelpText = \"Benchmark SafeArray arrays backed by native memory allocated using jemalloc vs. .NET managed arrays.\")]\n    class SafeArrayBenchmarkOptions : Options\n    {\n        [Option(\"create\", Required = false, HelpText = \"Benchmark native array creation vs managed arrays.\")]\n        public bool Create { get; set; }\n\n        [Option(\"fill\", Required = false, HelpText = \"Benchmark fill native array vs managed arrays.\")]\n        public bool Fill { get; set; }\n\n        [Option(\"math\", Required = false, HelpText = \"Benchmark arithmetic and other math operations on native array vs managed arrays.\")]\n        public bool Math { get; set; }\n\n        [Value(0, Required = true, HelpText = \"The sizes of data structures to benchmark.\")]\n        public IEnumerable<int> Sizes { get; set; }\n    }\n\n    [Verb(\"huge\", HelpText = \"Benchmark HugeArray arrays backed by native memory allocated using jemalloc vs. .NET managed arrays.\")]\n    class HugeNativeArrayBenchmarkOptions : Options\n    {\n        [Option(\"create\", Required = false, HelpText = \"Benchmark huge native array creation vs managed arrays.\")]\n        public bool Create { get; set; }\n\n        [Option(\"fill\", Required = false, HelpText = \"Benchmark huge native array fill vs managed arrays.\")]\n        public bool Fill { get; set; }\n\n        [Value(0, Required = true, HelpText = \"The sizes of data structures to benchmark.\")]\n        public IEnumerable<ulong> Sizes { get; set; }\n    }\n\n    [Verb(\"vector\", HelpText = \"Benchmark SIMD vectorized algorithms on native memory data structures vs. SIMD using .NET managed arrays.\")]\n    class VectorBenchmarkOptions : Options\n    {\n        [Option(\"mandel\", Required = false, HelpText = \"Benchmark Mandelbrot bitmap generation.\")]\n        public bool Mandelbrot { get; set; }\n\n        [Option(\"fill\", Required = false, HelpText = \"Benchmark Vector fill.\")]\n        public bool Fill { get; set; }\n\n        [Option(\"test\", Required = false, HelpText = \"Benchmark Vector logical comparison and test.\")]\n        public bool Test { get; set; }\n\n        [Value(0, Required = false, HelpText = \"The scales of operations on vectors.\")]\n        public IEnumerable<int> Scales { get; set; }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Cli/Program.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.Contracts;\nusing System.Linq;\nusing System.Reflection;\n\nusing Serilog;\nusing CommandLine;\nusing CommandLine.Text;\nusing BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Running;\nusing BenchmarkDotNet.Reports;\n\nusing jemalloc.Benchmarks;\n\nnamespace jemalloc.Cli\n{\n    class Program\n    {\n        public enum ExitResult\n        {\n            SUCCESS = 0,\n            UNHANDLED_EXCEPTION = 1,\n            INVALID_OPTIONS = 2\n        }\n\n \n        static Version Version = Assembly.GetExecutingAssembly().GetName().Version;\n        static LoggerConfiguration LConfig;\n        static ILogger L;\n        static Dictionary<string, object> BenchmarkOptions = new Dictionary<string, object>();\n        static Summary BenchmarkSummary;\n\n        static void Main(string[] args)\n        {\n            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;\n            LConfig = new LoggerConfiguration()\n                .Enrich.FromLogContext()\n                .Enrich.WithThreadId()\n                .Enrich.WithProcessId()\n                .MinimumLevel.Debug()\n                .WriteTo.Console(outputTemplate: \"{Timestamp:HH:mm:ss}<{ThreadId:d2}> [{Level:u3}] {Message}{NewLine}{Exception}\");\n            L = Log.Logger = LConfig.CreateLogger();\n            Type[] BenchmarkOptionTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(Options))).ToArray();\n            MethodInfo parseArgumentsMethod = typeof(ParserExtensions).GetMethods().Where(m => m.IsGenericMethod && m.Name == \"ParseArguments\" && m.GetGenericArguments().Count() == BenchmarkOptionTypes.Count()).First();\n            Parser p = new Parser();\n            ParserResult<object> result = (ParserResult<object>) parseArgumentsMethod.MakeGenericMethod(BenchmarkOptionTypes).Invoke(p , new object[] { p, args });\n            result.WithNotParsed((IEnumerable<Error> errors) =>\n            {\n                HelpText help = GetAutoBuiltHelpText(result);\n                help.MaximumDisplayWidth = Console.WindowWidth;\n                help.Copyright = string.Empty;\n                help.Heading = new HeadingInfo(\"jemalloc.NET\", Version.ToString(3));\n                help.AddPreOptionsLine(string.Empty);\n                if (errors.Any(e => e.Tag == ErrorType.VersionRequestedError))\n                {\n                    Log.Information(help);\n                    Exit(ExitResult.SUCCESS);\n                }\n                else if (errors.Any(e => e.Tag == ErrorType.HelpVerbRequestedError))\n                {\n                    HelpVerbRequestedError error = (HelpVerbRequestedError)errors.First(e => e.Tag == ErrorType.HelpVerbRequestedError);\n                    if (error.Type != null)\n                    {\n                        help.AddVerbs(error.Type);\n                    }\n                    Log.Information(help);\n                    Exit(ExitResult.SUCCESS);\n                }\n                else if (errors.Any(e => e.Tag == ErrorType.HelpRequestedError))\n                {\n                    help.AddVerbs(BenchmarkOptionTypes);\n                    L.Information(help);\n                    Exit(ExitResult.SUCCESS);\n                }\n                else if (errors.Any(e => e.Tag == ErrorType.NoVerbSelectedError))\n                {\n                    help.AddVerbs(BenchmarkOptionTypes);\n                    help.AddPreOptionsLine(\"No category selected. Select a category from the options below:\");\n                    L.Information(help);\n                    Exit(ExitResult.INVALID_OPTIONS);\n                }\n                else if (errors.Any(e => e.Tag == ErrorType.MissingRequiredOptionError))\n                {\n                    MissingRequiredOptionError error = (MissingRequiredOptionError)errors.First(e => e is MissingRequiredOptionError);\n                    help.AddOptions(result);\n                    help.AddPreOptionsLine($\"A required option or value is missing. The options and values for this benchmark category are: \");\n                    L.Information(help);\n                    Exit(ExitResult.INVALID_OPTIONS);\n                }\n                else if (errors.Any(e => e.Tag == ErrorType.MissingValueOptionError))\n                {\n                    MissingValueOptionError error = (MissingValueOptionError)errors.First(e => e.Tag == ErrorType.MissingValueOptionError);\n                    help.AddOptions(result);\n                    help.AddPreOptionsLine($\"A required option or value is missing. The options and values for this benchmark category are: \");\n                    L.Information(help);\n                    Exit(ExitResult.INVALID_OPTIONS);\n                }\n                else if (errors.Any(e => e.Tag == ErrorType.UnknownOptionError))\n                {\n                    UnknownOptionError error = (UnknownOptionError)errors.First(e => e.Tag == ErrorType.UnknownOptionError);\n                    help.AddOptions(result);\n                    help.AddPreOptionsLine($\"Unknown option: {error.Token}.\");\n                    L.Information(help);\n                    Exit(ExitResult.INVALID_OPTIONS);\n                }\n                else\n                {\n                    help.AddPreOptionsLine($\"An error occurred parsing the program options: {string.Join(' ', errors.Select(e => e.Tag.ToString()).ToArray())}\");\n                    help.AddVerbs(BenchmarkOptionTypes);\n                    L.Information(help);\n                    Exit(ExitResult.INVALID_OPTIONS);\n                }\n            })\n            .WithParsed((Options o) =>\n            {\n              \n                foreach (PropertyInfo prop in o.GetType().GetProperties())\n                {\n                    BenchmarkOptions.Add(prop.Name, prop.GetValue(o));\n                }\n                if (o.ColdStart)\n                {\n                    JemBenchmarkJobAttribute.ColdStartOverride = true;\n                }\n                if (o.TargetCount > 0)\n                {\n                    JemBenchmarkJobAttribute.TargetCountOverride = o.TargetCount;\n                }\n                if (o.Once)\n                {\n                    JemBenchmarkJobAttribute.ColdStartOverride = true;\n                    JemBenchmarkJobAttribute.TargetCountOverride = 1;\n                }\n            })\n            .WithParsed<MallocBenchmarkOptions>(o =>\n            {\n                BenchmarkOptions.Add(\"Category\", Category.MALLOC);\n                if (o.Create)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.CREATE);\n                }\n                else if (o.Fill)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.FILL);\n                }\n                else if (o.Fragment)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.FRAGMENT);\n                }\n                if (!BenchmarkOptions.ContainsKey(\"Operation\"))\n                {\n                    Log.Error(\"You must select an operation to benchmark with --fill.\");\n                    Exit(ExitResult.SUCCESS);\n                }\n                else\n                {\n                    Benchmark(o);\n                }\n            })\n            .WithParsed<FixedBufferBenchmarkOptions>(o =>\n            {\n                BenchmarkOptions.Add(\"Category\", Category.BUFFER);\n                if (o.Create)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.CREATE);\n                }\n                else if (o.Fill)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.FILL);\n                }\n                else if (o.Math)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.MATH);\n                }\n\n                if (!BenchmarkOptions.ContainsKey(\"Operation\"))\n                {\n                    Log.Error(\"You must select an operation to benchmark with --create or --fill.\");\n                    Exit(ExitResult.SUCCESS);\n                }\n                else\n                {\n                    Benchmark(o);\n                }\n\n            })\n            .WithParsed<SafeArrayBenchmarkOptions>(o =>\n            {\n                BenchmarkOptions.Add(\"Category\", Category.NARRAY);\n                if (o.Create)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.CREATE);\n                }\n                else if (o.Fill)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.FILL);\n                }\n                else if (o.Math)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.MATH);\n                }\n\n                if (!BenchmarkOptions.ContainsKey(\"Operation\"))\n                {\n                    Log.Error(\"You must select an operation to benchmark with --create or --fill.\");\n                    Exit(ExitResult.INVALID_OPTIONS);\n                }\n                else\n                {\n                    Benchmark(o);\n                }\n                \n            })\n            .WithParsed<HugeNativeArrayBenchmarkOptions>(o =>\n            {\n                BenchmarkOptions.Add(\"Category\", Category.HUGEARRAY);\n                if (o.Create)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.CREATE);\n                }\n                else if (o.Fill)\n                {\n                    BenchmarkOptions.Add(\"Operation\", Operation.FILL);\n                }\n                \n                if (!BenchmarkOptions.ContainsKey(\"Operation\"))\n                {\n                    Log.Error(\"You must select an operation to benchmark with --create or --fill or --math.\");\n                    Exit(ExitResult.INVALID_OPTIONS);\n                }\n                else\n                {\n                    Benchmark(o);\n                }\n            })\n             .WithParsed<VectorBenchmarkOptions>(o =>\n             {\n                 BenchmarkOptions.Add(\"Category\", Category.VECTOR);\n                 if (o.Mandelbrot)\n                 {\n                     BenchmarkOptions.Add(\"Operation\", Operation.MANDELBROT);\n                     o.Float = true;\n                     o.Int8 = o.Int16 = o.Int32 = o.Int64 = o.Double = o.String = o.Udt = false;\n                 }\n                 else if (o.Fill)\n                 {\n                     BenchmarkOptions.Add(\"Operation\", Operation.FILL);\n                 }\n\n                 else if (o.Test)\n                 {\n                     BenchmarkOptions.Add(\"Operation\", Operation.TEST);\n                 }\n\n                 if (!BenchmarkOptions.ContainsKey(\"Operation\"))\n                 {\n                     Log.Error(\"You must select a vector operation to benchmark with --mandel or --fill or --test.\");\n                     Exit(ExitResult.INVALID_OPTIONS);\n                 }\n                 else\n                 {\n                     Benchmark(o);\n                 }\n             }); \n        }\n\n        static void Benchmark(Options o)\n        {\n            Contract.Requires(BenchmarkOptions.ContainsKey(\"Operation\"));\n            Contract.Requires(BenchmarkOptions.ContainsKey(\"Category\"));\n            Contract.Requires(BenchmarkOptions.ContainsKey(\"Sizes\") || BenchmarkOptions.ContainsKey(\"Scales\"));\n            if (o.Int8 && o.Unsigned)\n            {\n                Benchmark<Byte>();\n            }\n            else if (o.Int8)\n            {\n                Benchmark<SByte>();\n            }\n            else if (o.Int16 && o.Unsigned)\n            {\n                Benchmark<UInt16>();\n            }\n            else if (o.Int16)\n            {\n                Benchmark<Int16>();\n            }\n            else if (o.Int32 && o.Unsigned)\n            {\n                Benchmark<UInt32>();\n            }\n            else if (o.Int32)\n            {\n                Benchmark<Int32>();\n            }\n            else if (o.Int64 && o.Unsigned)\n            {\n                Benchmark<UInt64>();\n            }\n            else if (o.Int64)\n            {\n                Benchmark<Int64>();\n            }\n            else if (o.Float)\n            {\n                Benchmark<Single>();\n            }\n            else if (o.Double)\n            {\n                Benchmark<Double>();\n            }\n            else if (o.Udt)\n            {\n                Benchmark<TestUDT>();\n            }\n            else\n            {\n                L.Error(\"You must select a data type to benchmark with: -b, -i, -h, -l, -d, -s, and -u.\");\n                Exit(ExitResult.INVALID_OPTIONS);\n            }\n        }\n        static void Benchmark<T>() where T : struct, IEquatable<T>, IComparable<T>, IConvertible\n        {\n            Contract.Requires(BenchmarkOptions.ContainsKey(\"Category\"));\n            Contract.Requires(BenchmarkOptions.ContainsKey(\"Operation\"));\n            Contract.Requires(BenchmarkOptions.ContainsKey(\"Sizes\"));\n            IConfig config = ManualConfig\n                         .Create(DefaultConfig.Instance);\n            JemBenchmarkAttribute.CurrentConfig = config;\n            JemBenchmarkAttribute.Category = (Category)BenchmarkOptions[\"Category\"];\n            JemBenchmarkAttribute.Operation = (Operation)BenchmarkOptions[\"Operation\"];\n            try\n            {\n                switch ((Category)BenchmarkOptions[\"Category\"])\n                {\n                    case Category.MALLOC:\n                        MallocVsArrayBenchmark<T>.Debug = (bool)BenchmarkOptions[\"Debug\"];\n                        MallocVsArrayBenchmark<T>.Category = JemBenchmarkAttribute.Category;\n                        MallocVsArrayBenchmark<T>.Operation = JemBenchmarkAttribute.Operation;\n                        MallocVsArrayBenchmark<T>.BenchmarkParameters = ((IEnumerable<int>)BenchmarkOptions[\"Sizes\"]).ToList();\n                        switch ((Operation)BenchmarkOptions[\"Operation\"])\n                        {\n                            case Operation.CREATE:\n                                config = config.With(new NameFilter(name => name.Contains(\"Create\")));\n                                L.Information(\"Starting {num} create benchmarks for data type {t} with array sizes: {s}\", JemBenchmark<T, int>.GetBenchmarkMethodCount<MallocVsArrayBenchmark<T>>(),\n                                    typeof(T).Name, MallocVsArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"Please allow some time for the pilot and warmup phases of the benchmark.\");\n                                break;\n\n                            case Operation.FILL:\n                                config = config.With(new NameFilter(name => name.Contains(\"Fill\")));\n                                L.Information(\"Starting {num} fill benchmarks for data type {t} with array sizes: {s}\", JemBenchmark<T, int>.GetBenchmarkMethodCount<MallocVsArrayBenchmark<T>>(),\n                                    typeof(T).Name, MallocVsArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"Please allow some time for the pilot and warmup phases of the benchmark.\");                        \n                                break;\n\n                            case Operation.FRAGMENT:\n                                config = config.With(new NameFilter(name => name.Contains(\"Fragment\")));\n                                L.Information(\"Starting {num} fragment benchmarks for data type {t} with array sizes: {s}\", JemBenchmark<T, int>.GetBenchmarkMethodCount<MallocVsArrayBenchmark<T>>(),\n                                    typeof(T).Name, MallocVsArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"Please allow some time for the pilot and warmup phases of the benchmark.\");\n                                break;\n\n                            default:\n                                throw new InvalidOperationException($\"Unknown operation: {(Operation)BenchmarkOptions[\"Operation\"]} for category {(Category)BenchmarkOptions[\"Category\"]}.\");\n                        }\n                        BenchmarkSummary = BenchmarkRunner.Run<MallocVsArrayBenchmark<T>>(config);\n                        break;\n\n                    case Category.BUFFER:\n                        FixedBufferVsManagedArrayBenchmark<T>.BenchmarkParameters = ((IEnumerable<int>)BenchmarkOptions[\"Sizes\"]).ToList();\n                        FixedBufferVsManagedArrayBenchmark<T>.Debug = (bool)BenchmarkOptions[\"Debug\"];\n                        FixedBufferVsManagedArrayBenchmark<T>.Category = JemBenchmarkAttribute.Category;\n                        FixedBufferVsManagedArrayBenchmark<T>.Operation = JemBenchmarkAttribute.Operation;\n                        switch ((Operation)BenchmarkOptions[\"Operation\"])\n                        {\n                            case Operation.CREATE:\n                                L.Information(\"Starting {num} create array benchmarks for data type {t} with array sizes: {s}\",\n                                    JemBenchmark<T, int>.GetBenchmarkMethodCount<FixedBufferVsManagedArrayBenchmark<T>>(),\n                                    typeof(T).Name,\n                                    FixedBufferVsManagedArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"Please allow some time for the pilot and warmup phases of the benchmark.\");\n                                config = config\n                                    .With(new NameFilter(name => name.StartsWith(\"Create\")));\n                                break;\n\n                            case Operation.FILL:\n                                L.Information(\"Starting {num} array fill benchmarks for data type {t} with array sizes: {s}\",\n                                    JemBenchmark<T, int>.GetBenchmarkMethodCount<FixedBufferVsManagedArrayBenchmark<T>>(),\n                                    typeof(T).Name, FixedBufferVsManagedArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"Please allow some time for the pilot and warmup phases of the benchmark.\");\n                                config = config\n                                    .With(new NameFilter(name => name.StartsWith(\"Fill\")));\n                                break;\n\n                            case Operation.MATH:\n                                L.Information(\"Starting {num} array math benchmarks for data type {t} with array sizes: {s}\",\n                                    JemBenchmark<T, int>.GetBenchmarkMethodCount<FixedBufferVsManagedArrayBenchmark<T>>(),\n                                    typeof(T).Name, FixedBufferVsManagedArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"Please allow some time for the pilot and warmup phases of the benchmark.\");\n                                config = config\n                                    .With(new NameFilter(name => name.StartsWith(\"Arith\")));\n                                break;\n\n                            default:\n                                throw new InvalidOperationException($\"Unknown operation: {(Operation)BenchmarkOptions[\"Operation\"]} for category {(Category)BenchmarkOptions[\"Category\"]}.\");\n                        }\n                        BenchmarkSummary = BenchmarkRunner.Run<FixedBufferVsManagedArrayBenchmark<T>>(config);\n                        break;\n\n                    case Category.NARRAY:\n                        SafeVsManagedArrayBenchmark<T>.BenchmarkParameters = ((IEnumerable<int>)BenchmarkOptions[\"Sizes\"]).ToList();\n                        SafeVsManagedArrayBenchmark<T>.Debug = (bool)BenchmarkOptions[\"Debug\"];\n                        SafeVsManagedArrayBenchmark<T>.Category = JemBenchmarkAttribute.Category;\n                        SafeVsManagedArrayBenchmark<T>.Operation = JemBenchmarkAttribute.Operation;\n                        switch ((Operation)BenchmarkOptions[\"Operation\"])\n                        {\n                            case Operation.CREATE:\n                                L.Information(\"Starting {num} create array benchmarks for data type {t} with array sizes: {s}\",\n                                    JemBenchmark<T, int>.GetBenchmarkMethodCount<SafeVsManagedArrayBenchmark<T>>(),\n                                    typeof(T).Name,\n                                    SafeVsManagedArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"Please allow some time for the pilot and warmup phases of the benchmark.\");\n                                config = config\n                                    .With(new NameFilter(name => name.StartsWith(\"Create\")));\n                                break;\n\n                            case Operation.FILL:\n                                L.Information(\"Starting {num} array fill benchmarks for data type {t} with array sizes: {s}\",\n                                    JemBenchmark<T, int>.GetBenchmarkMethodCount<SafeVsManagedArrayBenchmark<T>>(),\n                                    typeof(T).Name, SafeVsManagedArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"Please allow some time for the pilot and warmup phases of the benchmark.\");\n                                config = config\n                                    .With(new NameFilter(name => name.StartsWith(\"Fill\")));\n                                break;\n\n                            case Operation.MATH:\n                                L.Information(\"Starting {num} array math benchmarks for data type {t} with array sizes: {s}\",\n                                    JemBenchmark<T, int>.GetBenchmarkMethodCount<SafeVsManagedArrayBenchmark<T>>(),\n                                    typeof(T).Name, SafeVsManagedArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"Please allow some time for the pilot and warmup phases of the benchmark.\");\n                                config = config\n                                    .With(new NameFilter(name => name.StartsWith(\"Arith\")));\n                                break;\n\n                            default:\n                                throw new InvalidOperationException($\"Unknown operation: {(Operation)BenchmarkOptions[\"Operation\"]} for category {(Category)BenchmarkOptions[\"Category\"]}.\");\n                        }\n                        BenchmarkSummary = BenchmarkRunner.Run<SafeVsManagedArrayBenchmark<T>>(config);\n                        break;\n\n                    case Category.HUGEARRAY:\n                        HugeNativeVsManagedArrayBenchmark<T>.BenchmarkParameters = ((IEnumerable<ulong>)BenchmarkOptions[\"Sizes\"]).ToList();\n                        HugeNativeVsManagedArrayBenchmark<T>.Debug = (bool)BenchmarkOptions[\"Debug\"];\n                        HugeNativeVsManagedArrayBenchmark<T>.Category = JemBenchmarkAttribute.Category;\n                        HugeNativeVsManagedArrayBenchmark<T>.Operation = JemBenchmarkAttribute.Operation;\n                        switch ((Operation)BenchmarkOptions[\"Operation\"])\n                        {\n                            case Operation.CREATE:\n                                config = config.With(new NameFilter(name => name.Contains(\"Create\")));\n                                L.Information(\"Starting {num} huge array create benchmarks for data type {t} with array sizes: {s}\",\n                                    JemBenchmark<T, ulong>.GetBenchmarkMethodCount<HugeNativeVsManagedArrayBenchmark<T>>(),\n                                    typeof(T).Name, HugeNativeVsManagedArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"This benchmark does not have a warmup phase but can still take a while (10-15 minutes.)\");\n                                break;\n\n                            case Operation.FILL:\n                                config = config.With(new NameFilter(name => name.Contains(\"Fill\")));\n                                L.Information(\"Starting {num} huge array fill benchmarks for data type {t} with array sizes: {s}\",\n                                    JemBenchmark<T, ulong>.GetBenchmarkMethodCount<HugeNativeVsManagedArrayBenchmark<T>>(),\n                                    typeof(T).Name, HugeNativeVsManagedArrayBenchmark<T>.BenchmarkParameters);\n                                L.Information(\"This benchmark does not have a warmup phase but can still take a while (10-15 minutes.)\");\n                                break;\n\n                            default:\n                                throw new InvalidOperationException($\"Unknown operation: {(Operation)BenchmarkOptions[\"Operation\"]} for category {(Category)BenchmarkOptions[\"Category\"]}.\");\n                        }\n                        BenchmarkSummary = BenchmarkRunner.Run<HugeNativeVsManagedArrayBenchmark<T>>(config);\n                        break;\n\n                    case Category.VECTOR:\n                        VectorBenchmark<T>.BenchmarkParameters = ((IEnumerable<int>)BenchmarkOptions[\"Scales\"]).ToList();\n                        VectorBenchmark<T>.Debug = (bool)BenchmarkOptions[\"Debug\"];\n                        VectorBenchmark<T>.Category = JemBenchmarkAttribute.Category;\n                        VectorBenchmark<T>.Operation = JemBenchmarkAttribute.Operation;\n                        \n                        switch ((Operation)BenchmarkOptions[\"Operation\"])\n                        {\n                            case Operation.MANDELBROT:\n                                config = config.With(BenchmarkStatisticColumn.ThreadCycles);\n                                config = config.With(BenchmarkStatisticColumn.ISPCResult);\n                                config = config.With(BenchmarkStatisticColumn.ISPCResult2);\n                                config = config.With(new NameFilter(name => name.StartsWith(\"Mandelbrot\")));\n                                L.Information(\"Starting vector Mandelbrot benchmarks with scale: {s}\", VectorBenchmark<T>.BenchmarkParameters);\n                                break;\n\n                            case Operation.FILL:\n                                config = config.With(new NameFilter(name => name.StartsWith(\"Fill\")));\n                                L.Information(\"Starting vector fill benchmarks with array sizes: {s}\", VectorBenchmark<T>.BenchmarkParameters);\n                                break;\n\n                            case Operation.TEST:\n                                config = config.With(new NameFilter(name => name.StartsWith(\"Test\")));\n                                L.Information(\"Starting vector logical comparison and test benchmarks with array sizes: {s}\", VectorBenchmark<T>.BenchmarkParameters);\n                                break;\n\n                            default:\n                                throw new InvalidOperationException($\"Unknown operation: {(Operation)BenchmarkOptions[\"Operation\"]} for category {(Category)BenchmarkOptions[\"Category\"]}.\");\n                        }\n                        BenchmarkSummary = BenchmarkRunner.Run<VectorBenchmark<T>>(config);\n                        break;\n\n                    default:\n                        throw new InvalidOperationException($\"Unknown category: {(Category)BenchmarkOptions[\"Category\"]}.\");\n                }\n            }\n            catch (Exception e)\n            {\n                Log.Error(e, \"Exception thrown during benchmark.\");\n                Exit(ExitResult.UNHANDLED_EXCEPTION);\n            }\n        }\n\n        static void Exit(ExitResult result)\n        {\n            Log.CloseAndFlush();\n            \n            Environment.Exit((int)result);\n        }\n\n        static int ExitWithCode(ExitResult result)\n        {\n            Log.CloseAndFlush();\n            return (int)result;\n        }\n\n        static HelpText GetAutoBuiltHelpText(ParserResult<object> result)\n        {\n            return HelpText.AutoBuild(result, h =>\n            {\n                h.AddOptions(result);\n                return h;\n            },\n            e =>\n            {\n                return e;\n            });\n        }\n\n        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)\n        {\n            Exception exception = (Exception)e.ExceptionObject;\n            Log.Error(exception, \"An unhandled exception occurred. The program will now shutdown.\");\n            Log.Error(exception.StackTrace);\n            Exit(ExitResult.UNHANDLED_EXCEPTION);\n        }\n\n    }\n}\n"
  },
  {
    "path": "jemalloc.Cli/Properties/PublishProfiles/ReleaseProfile.pubxml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nThis file is used by the publish/package process of your project. You can customize the behavior of this process\nby editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121. \n-->\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <PublishProtocol>FileSystem</PublishProtocol>\n    <Configuration>Benchmark</Configuration>\n    <TargetFramework>netcoreapp2.0</TargetFramework>\n    <PublishDir>..\\x64\\Publish\\netcoreapp2.0</PublishDir>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "jemalloc.Cli/jemalloc.Cli.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>netcoreapp2.0</TargetFramework>\n    <Platforms>AnyCPU;x64</Platforms>\n    <AssemblyName>jemalloc.Cli</AssemblyName>\n    <AssemblyVersion>0.2.4.0</AssemblyVersion>\n    <FileVersion>0.2.3.0</FileVersion>\n    <Version>0.2.4-alpha</Version>\n    <Authors>Allister Beharry</Authors>\n    <Company />\n    <Product>jemalloc.NET</Product>\n    <PackageId>jemalloc CLI</PackageId>\n    <Description>Native memory manager for .NET</Description>\n    <PackageLicenseUrl>https://github.com/allisterb/jemalloc.NET/LICENSE</PackageLicenseUrl>\n    <PackageProjectUrl>https://github.com/allisterb/jemalloc.NET</PackageProjectUrl>\n    <RepositoryUrl>https://github.com/allisterb/jemalloc.NET</RepositoryUrl>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <OutputPath>..\\x64\\Debug</OutputPath>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutputPath>..\\x64\\Debug</OutputPath>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <OutputPath>..\\x64\\Release</OutputPath>\n    <LangVersion>default</LangVersion>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Compile Remove=\"BenchmarkDotNet.Artifacts\\**\" />\n    <EmbeddedResource Remove=\"BenchmarkDotNet.Artifacts\\**\" />\n    <None Remove=\"BenchmarkDotNet.Artifacts\\**\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"BenchmarkDotNet\" Version=\"0.10.11\" />\n    <PackageReference Include=\"CommandLineParser\" Version=\"2.1.1-beta\" />\n    <PackageReference Include=\"Serilog\" Version=\"2.5.0\" />\n    <PackageReference Include=\"Serilog.Enrichers.Process\" Version=\"2.0.1\" />\n    <PackageReference Include=\"Serilog.Enrichers.Thread\" Version=\"3.0.0\" />\n    <PackageReference Include=\"Serilog.Sinks.Console\" Version=\"3.1.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\jemalloc.Benchmarks\\jemalloc.Benchmarks.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "jemalloc.Examples/TestUDT.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace jemalloc.Examples\n{\n    public struct TestUDT : IEquatable<TestUDT>, IComparable<TestUDT>, IConvertible\n    {\n        public Guid ID { get; set; }               \n        public Utf8Buffer FirstName { get; set; }      \n        public Utf8Buffer LastName { get; set; }       \n        public DateTime? DOB { get; set; }         \n        public decimal Balance { get; set; }       \n        public FixedBuffer<float> Data { get; set; }          \n        public FixedBuffer<byte> Photo { get; set; } \n\n        public static TestUDT MakeTestRecord(Random rng)\n        {\n            Guid _id = Guid.NewGuid();\n            string _ids = _id.ToString(\"N\");\n            byte[] photo = new byte[4096];\n            rng.NextBytes(photo);\n            return new TestUDT()\n            {\n                ID = _id,\n                FirstName = new Utf8Buffer(\"Gavial-\" + _id.ToString(\"D\").Substring(0, 4)),\n                LastName = new Utf8Buffer(\"Buxarinovich-\" + _id.ToString(\"D\").Substring(0, 4)),\n                DOB = _ids.StartsWith(\"7\") ? (DateTime?)null : DateTime.UtcNow,\n                Balance = 2131m,\n                Photo = new FixedBuffer<byte>(photo)\n            };\n        }\n\n        public bool Equals(TestUDT r)\n        {\n            return this.ID == r.ID;\n        }\n\n        #region IConvertible\n\n\n        public TypeCode GetTypeCode()\n        {\n            return TypeCode.Object;\n        }\n\n        bool IConvertible.ToBoolean(IFormatProvider provider)\n        {\n            throw new InvalidCastException();        \n        }\n\n        double GetDoubleValue()\n        {\n            throw new InvalidCastException(); \n        }\n\n        byte IConvertible.ToByte(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        char IConvertible.ToChar(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        DateTime IConvertible.ToDateTime(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        decimal IConvertible.ToDecimal(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        double IConvertible.ToDouble(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        short IConvertible.ToInt16(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        int IConvertible.ToInt32(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        long IConvertible.ToInt64(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        sbyte IConvertible.ToSByte(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        float IConvertible.ToSingle(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        string IConvertible.ToString(IFormatProvider provider)\n        {\n            return String.Format(\"({0}, {1})\", FirstName, LastName);\n        }\n\n        object IConvertible.ToType(Type conversionType, IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        ushort IConvertible.ToUInt16(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        uint IConvertible.ToUInt32(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n\n        ulong IConvertible.ToUInt64(IFormatProvider provider)\n        {\n            throw new InvalidCastException();\n        }\n        #endregion\n\n        #region IComparable\n        public int CompareTo(TestUDT other)\n        {\n            return 0;\n        }\n        #endregion\n\n        //public static ulong size = \n    }\n}\n"
  },
  {
    "path": "jemalloc.Examples/jemalloc.Examples.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netstandard2.0</TargetFramework>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <PlatformTarget>x64</PlatformTarget>\n    <OutputPath>..\\x64\\Debug\\</OutputPath>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\jemalloc.Api\\jemalloc.Api.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "jemalloc.NET.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.27130.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"jemalloc.Bindings\", \"jemalloc.Bindings\\jemalloc.Bindings.csproj\", \"{C24A6949-BA9E-443B-A67E-188AB489057E}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A} = {8D6BB292-9E1C-413D-9F98-4864BDC1514A}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"jemalloc\", \"jemalloc\\msvc\\projects\\vc2017\\jemalloc\\jemalloc.vcxproj\", \"{8D6BB292-9E1C-413D-9F98-4864BDC1514A}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"jemalloc.Api\", \"jemalloc.Api\\jemalloc.Api.csproj\", \"{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A} = {8D6BB292-9E1C-413D-9F98-4864BDC1514A}\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"jemalloc.Cli\", \"jemalloc.Cli\\jemalloc.Cli.csproj\", \"{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"jemalloc.Tests\", \"jemalloc.Tests\\jemalloc.Tests.csproj\", \"{072F89BE-D090-49F5-928F-995AA8C2E87E}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{42D17CA7-794A-4D51-A144-6039B9571E75}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tbuild.cmd = build.cmd\n\t\tjembench.cmd = jembench.cmd\n\t\tREADME.md = README.md\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"jemalloc.Buffers\", \"jemalloc.Buffers\\jemalloc.Buffers.csproj\", \"{C4032FF9-E677-4ABD-9150-F292971959E9}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"jemalloc.Benchmarks\", \"jemalloc.Benchmarks\\jemalloc.Benchmarks.csproj\", \"{E5044104-376A-44A4-A1C0-D4F1C88D1149}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9} = {C4032FF9-E677-4ABD-9150-F292971959E9}\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"jemalloc.StressTests\", \"jemalloc.StressTests\\jemalloc.StressTests.csproj\", \"{F242A777-036C-4AB8-9393-3931A98A92F1}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"jemalloc.Examples\", \"jemalloc.Examples\\jemalloc.Examples.csproj\", \"{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tBenchmark|Any CPU = Benchmark|Any CPU\n\t\tBenchmark|x64 = Benchmark|x64\n\t\tBenchmark|x86 = Benchmark|x86\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tDebug-static|Any CPU = Debug-static|Any CPU\n\t\tDebug-static|x64 = Debug-static|x64\n\t\tDebug-static|x86 = Debug-static|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\t\tRelease-static|Any CPU = Release-static|Any CPU\n\t\tRelease-static|x64 = Release-static|x64\n\t\tRelease-static|x86 = Release-static|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Benchmark|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Benchmark|Any CPU.Build.0 = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Benchmark|x64.ActiveCfg = Release|x64\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Benchmark|x86.ActiveCfg = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Benchmark|x86.Build.0 = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug-static|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug-static|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug-static|x64.ActiveCfg = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug-static|x64.Build.0 = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug-static|x86.ActiveCfg = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Debug-static|x86.Build.0 = Debug|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release|x64.ActiveCfg = Release|x64\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release|x86.Build.0 = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release-static|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release-static|Any CPU.Build.0 = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release-static|x64.ActiveCfg = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release-static|x64.Build.0 = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release-static|x86.ActiveCfg = Release|Any CPU\n\t\t{C24A6949-BA9E-443B-A67E-188AB489057E}.Release-static|x86.Build.0 = Release|Any CPU\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Benchmark|Any CPU.ActiveCfg = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Benchmark|x64.ActiveCfg = Debug|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Benchmark|x64.Build.0 = Debug|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Benchmark|x86.ActiveCfg = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Benchmark|x86.Build.0 = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Benchmark|x86.Deploy.0 = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|Any CPU.ActiveCfg = Debug|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x64.Build.0 = Debug|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x64.Deploy.0 = Debug|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x86.Build.0 = Debug|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug|x86.Deploy.0 = Debug|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|Any CPU.ActiveCfg = Debug-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x64.ActiveCfg = Debug-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x64.Build.0 = Debug-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x64.Deploy.0 = Debug-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x86.ActiveCfg = Debug-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x86.Build.0 = Debug-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Debug-static|x86.Deploy.0 = Debug-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|Any CPU.ActiveCfg = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|x64.ActiveCfg = Debug|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|x64.Build.0 = Debug|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|x86.ActiveCfg = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|x86.Build.0 = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release|x86.Deploy.0 = Release|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|Any CPU.ActiveCfg = Release-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x64.ActiveCfg = Release-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x64.Build.0 = Release-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x64.Deploy.0 = Release-static|x64\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x86.ActiveCfg = Release-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x86.Build.0 = Release-static|Win32\n\t\t{8D6BB292-9E1C-413D-9F98-4864BDC1514A}.Release-static|x86.Deploy.0 = Release-static|Win32\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Benchmark|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Benchmark|Any CPU.Build.0 = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Benchmark|x64.ActiveCfg = Release|x64\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Benchmark|x64.Build.0 = Release|x64\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Benchmark|x86.ActiveCfg = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Benchmark|x86.Build.0 = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug|x64.Build.0 = Debug|x64\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug-static|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug-static|Any CPU.Build.0 = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug-static|x64.ActiveCfg = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug-static|x64.Build.0 = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug-static|x86.ActiveCfg = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Debug-static|x86.Build.0 = Debug|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release|x64.ActiveCfg = Release|x64\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release|x64.Build.0 = Release|x64\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release|x86.Build.0 = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release-static|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release-static|Any CPU.Build.0 = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release-static|x64.ActiveCfg = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release-static|x64.Build.0 = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release-static|x86.ActiveCfg = Release|Any CPU\n\t\t{9CD27E9F-1F2C-4BEC-8019-743FF8D86589}.Release-static|x86.Build.0 = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Benchmark|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Benchmark|Any CPU.Build.0 = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Benchmark|x64.ActiveCfg = Release|x64\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Benchmark|x64.Build.0 = Release|x64\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Benchmark|x86.ActiveCfg = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Benchmark|x86.Build.0 = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug|x64.Build.0 = Debug|x64\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug-static|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug-static|Any CPU.Build.0 = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug-static|x64.ActiveCfg = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug-static|x64.Build.0 = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug-static|x86.ActiveCfg = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Debug-static|x86.Build.0 = Debug|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release|x64.ActiveCfg = Release|x64\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release|x86.Build.0 = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release-static|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release-static|Any CPU.Build.0 = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release-static|x64.ActiveCfg = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release-static|x64.Build.0 = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release-static|x86.ActiveCfg = Release|Any CPU\n\t\t{1FE3EBE7-3922-4CAE-A142-B1C4DF935B0F}.Release-static|x86.Build.0 = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Benchmark|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Benchmark|Any CPU.Build.0 = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Benchmark|x64.ActiveCfg = Release|x64\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Benchmark|x86.ActiveCfg = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Benchmark|x86.Build.0 = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug|x64.Build.0 = Debug|x64\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug-static|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug-static|Any CPU.Build.0 = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug-static|x64.ActiveCfg = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug-static|x64.Build.0 = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug-static|x86.ActiveCfg = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Debug-static|x86.Build.0 = Debug|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release|x64.ActiveCfg = Release|x64\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release|x86.Build.0 = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release-static|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release-static|Any CPU.Build.0 = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release-static|x64.ActiveCfg = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release-static|x64.Build.0 = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release-static|x86.ActiveCfg = Release|Any CPU\n\t\t{072F89BE-D090-49F5-928F-995AA8C2E87E}.Release-static|x86.Build.0 = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Benchmark|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Benchmark|Any CPU.Build.0 = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Benchmark|x64.ActiveCfg = Release|x64\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Benchmark|x64.Build.0 = Release|x64\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Benchmark|x86.ActiveCfg = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Benchmark|x86.Build.0 = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug|x64.Build.0 = Debug|x64\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug-static|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug-static|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug-static|x64.ActiveCfg = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug-static|x64.Build.0 = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug-static|x86.ActiveCfg = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Debug-static|x86.Build.0 = Debug|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release|x64.ActiveCfg = Release|x64\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release|x86.Build.0 = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release-static|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release-static|Any CPU.Build.0 = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release-static|x64.ActiveCfg = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release-static|x64.Build.0 = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release-static|x86.ActiveCfg = Release|Any CPU\n\t\t{C4032FF9-E677-4ABD-9150-F292971959E9}.Release-static|x86.Build.0 = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Benchmark|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Benchmark|Any CPU.Build.0 = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Benchmark|x64.ActiveCfg = Release|x64\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Benchmark|x64.Build.0 = Release|x64\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Benchmark|x86.ActiveCfg = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Benchmark|x86.Build.0 = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug|x64.ActiveCfg = Release|x64\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug-static|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug-static|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug-static|x64.ActiveCfg = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug-static|x64.Build.0 = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug-static|x86.ActiveCfg = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Debug-static|x86.Build.0 = Debug|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release|x64.ActiveCfg = Release|x64\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release|x86.Build.0 = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release-static|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release-static|Any CPU.Build.0 = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release-static|x64.ActiveCfg = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release-static|x64.Build.0 = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release-static|x86.ActiveCfg = Release|Any CPU\n\t\t{E5044104-376A-44A4-A1C0-D4F1C88D1149}.Release-static|x86.Build.0 = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Benchmark|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Benchmark|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Benchmark|x64.ActiveCfg = Debug|x64\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Benchmark|x86.ActiveCfg = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Benchmark|x86.Build.0 = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug|x64.Build.0 = Debug|x64\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug-static|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug-static|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug-static|x64.ActiveCfg = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug-static|x64.Build.0 = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug-static|x86.ActiveCfg = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Debug-static|x86.Build.0 = Debug|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release|x64.Build.0 = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release|x86.Build.0 = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release-static|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release-static|Any CPU.Build.0 = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release-static|x64.ActiveCfg = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release-static|x64.Build.0 = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release-static|x86.ActiveCfg = Release|Any CPU\n\t\t{F242A777-036C-4AB8-9393-3931A98A92F1}.Release-static|x86.Build.0 = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Benchmark|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Benchmark|Any CPU.Build.0 = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Benchmark|x64.ActiveCfg = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Benchmark|x64.Build.0 = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Benchmark|x86.ActiveCfg = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Benchmark|x86.Build.0 = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug-static|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug-static|Any CPU.Build.0 = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug-static|x64.ActiveCfg = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug-static|x64.Build.0 = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug-static|x86.ActiveCfg = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Debug-static|x86.Build.0 = Debug|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release|x64.Build.0 = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release|x86.Build.0 = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release-static|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release-static|Any CPU.Build.0 = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release-static|x64.ActiveCfg = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release-static|x64.Build.0 = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release-static|x86.ActiveCfg = Release|Any CPU\n\t\t{5C4F8F7C-D264-4C59-89C6-F3D701EFA613}.Release-static|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {03EC717B-98F6-4CEE-A5D7-236D8AF7B581}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "jemalloc.StressTests/FixedBufferStressTests.cs",
    "content": "using System;\nusing Xunit;\n\nnamespace jemalloc.StressTests\n{\n    public class FixedBufferStressTests\n    {\n        [Fact(DisplayName =\"Can allocate fixed buffers\")]\n        public void Test1()\n        {\n            int count = 0;\n            while (count < 10)\n            {\n                FixedBuffer<int> b = new FixedBuffer<int>(JemUtil.Rng.Next(100000, 1000000));\n                int r = JemUtil.Rng.Next(0, 64);\n                b.Fill(r);\n                for(int i = 0; i < b.Length; i++)\n                {\n                    Assert.Equal(r, b[i]);\n                }\n                Assert.True(b.Free());\n                count++;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.StressTests/jemalloc.StressTests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.0</TargetFramework>\n\n    <IsPackable>false</IsPackable>\n\n    <Platforms>AnyCPU;x64</Platforms>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutputPath>..\\x64\\Debug\\</OutputPath>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"15.5.0\" />\n    <PackageReference Include=\"xunit\" Version=\"2.3.1\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"2.3.1\" />\n    <DotNetCliToolReference Include=\"dotnet-xunit\" Version=\"2.3.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\jemalloc.Api\\jemalloc.Api.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "jemalloc.Tests/BufferTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing Xunit;\n\nnamespace jemalloc.Tests\n{\n    public class BufferTests : jemallocTest\n    {\n        [Fact]\n        public void CanConstructBuffer()\n        {\n            Buffer<int> buffer = new Buffer<int>(1000000000);\n            buffer[32] = 12;\n            Assert.Equal(12, buffer[32]);\n            \n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/FixedBufferTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing Xunit;\n\nnamespace jemalloc.Tests\n{\n    public class FixedBufferTests : jemallocTest\n    {\n        [Fact(DisplayName = \"Can create a fixed buffer of bytes\")]\n        public void CanCreateFixedArray()\n        {\n            FixedBuffer<byte> buffer = new FixedBuffer<byte>(4096);\n            ref byte z = ref buffer[0];\n            byte[] managedArray = new byte[4096];\n            SafeArray<FixedBuffer<byte>> byteBuffer = new SafeArray<FixedBuffer<byte>>(1000);\n            byteBuffer[0] = new FixedBuffer<byte>(100);\n            byteBuffer[0][16]= 0xff;\n            Assert.Equal(0xff, byteBuffer[0][16]);\n            byteBuffer[0][16] = 4;\n            ref FixedBuffer<byte> a = ref byteBuffer[0];\n            for (int i = 0; i < buffer.Length; i++)\n            {\n                byte v = (byte)Rng.Next(0, 255);\n                managedArray[i] = v;\n                buffer[i] = v;\n            }\n            FixedBuffer<byte> copy = buffer;\n            Assert.True(buffer.EqualTo(managedArray));\n            Assert.True(copy.EqualTo(managedArray));\n            buffer.Free();\n            Assert.Throws<InvalidOperationException>(() => buffer[0] = 1);\n            Assert.Throws<InvalidOperationException>(() => copy[0]);\n        }\n\n        [Fact(DisplayName = \"Can deallocate a fixed buffer of bytes\")]\n        public void CanDeAllocateFixedArray()\n        {\n            SafeArray<FixedBuffer<byte>> byteBuffer = new SafeArray<FixedBuffer<byte>>(100);\n            for (int i = 0; i < 100; i++)\n            {\n                ulong jem_before_alloc = Jem.AllocatedBytes;\n                byteBuffer[i] = new FixedBuffer<byte>((i * 16) + (1024 * 1024));\n                ulong jem_after_alloc = Jem.AllocatedBytes;\n                //Assert.True(jem_after_alloc > jem_before_alloc);\n                byteBuffer.Release();\n                long mem_after_free = JemUtil.ProcessPrivateMemory;\n                //Assert.True(mem_after_free < mem_after_alloc);\n                \n            }\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/HugeArrayTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Numerics;\n\nusing Xunit;\n\nnamespace jemalloc.Tests\n{\n    public class HugeArrayTests : jemallocTest\n    {\n        Random rng = new Random();\n\n        [Fact(DisplayName = \"Can construct huge array\")]\n        public void CanConstructHugeArray()\n        {\n            ulong arraySize = 2L * Int32.MaxValue;\n            ulong point = 1L * Int32.MaxValue;\n            HugeArray<int> array = new HugeArray<int>(arraySize);\n            array[point] = 1;\n            Assert.Equal(1, array[point]);\n            array.Close();\n        }\n\n        [Fact(DisplayName = \"Can correctly assign to HugeArray elements\")]\n        public void CanAssignToHugeArrayElements()\n        {\n            ulong arraySize = 2L * Int32.MaxValue;\n            HugeArray<int> array = new HugeArray<int>(arraySize);\n            ulong[] indices = new ulong[10000];\n            int scale = 0, value = 0;\n            ulong v = 0;\n            for (int i = 0; i < indices.Length; i++)\n            {\n                v = indices[0];\n                while (indices.Contains(v))\n                {\n                    scale = rng.Next(1, 2);\n                    value = rng.Next(0, Int32.MaxValue - 1);\n                    v = (ulong)scale * (ulong)value;\n                }\n                array[v] = i;\n                indices[i] = v;\n            }\n            for (int i = 0; i < indices.Length; i++)\n            {\n                Assert.Equal(i, array[indices[i]]);\n            }\n            array.Close();\n        }\n\n        [Fact(DisplayName = \"Can convert to Vector\")]\n        public void CanConvertToVector()\n        {\n            HugeArray<uint> a = new HugeArray<uint>(8, 1, 11, 94, 5, 0, 0, 0, 8);\n            Vector<uint> v = a.GetAsSingleVector();\n            Assert.Equal(a[0], v[0]);\n            Assert.Equal(a[3], v[3]);\n            Assert.Equal(a[7], v[7]);\n            HugeArray<uint> a2 = new HugeArray<uint>(12, 11, 112, 594, 65, 0, 0, 0, 8, 14, 90, 2, 8);\n            Vector<uint> v2 = a2.GetSliceAsSingleVector(0);\n            Assert.Equal(11u, v2[0]);\n            Assert.Equal(8u, v2[7]);\n            HugeArray<uint> a3 = new HugeArray<uint>((ulong)Int32.MaxValue + 10000);\n            a3.Fill(7u);\n            a3[(ulong)Int32.MaxValue + 100] = 9;\n            a3[(ulong)Int32.MaxValue + 101] = 4;\n            Vector<uint> v3 = a3.GetSliceAsSingleVector((ulong)Int32.MaxValue + 99);\n            Assert.Equal(9u, v3[1]);\n            Assert.Equal(4u, v3[2]);\n            Assert.Equal(a3[(ulong)Int32.MaxValue + 99], v3[0]);\n            Assert.Equal(7u, v3[0]);\n            Assert.Equal(7u, v3[7]);\n            a.Close();\n            a2.Close();\n            a3.Close();\n        }\n\n        [Fact(DisplayName = \"Can correctly fill\")]\n        public void CanFill()\n        {\n            HugeArray<int> array = new HugeArray<int>(1000);\n            array.Fill(33);\n            Assert.Equal(33, array[999]);\n            array.Close();\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/MallCtlTests.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing Xunit;\n\nnamespace jemalloc.Tests\n{\n    public class MallCtlTests : jemallocTest\n    {\n        public MallCtlTests() : base() {}\n        [Fact]\n        public void CanReadMallCtlInt32()\n        {\n            Assert.Equal(3, Jem.GetMallCtlInt32(\"opt.narenas\"));\n        }\n\n        [Fact]\n        public void CanReadMallCtlBool()\n        {\n            Assert.True(Jem.GetMallCtlBool(\"config.debug\"));\n            Assert.False(Jem.GetMallCtlBool(\"config.xmalloc\"));\n        }\n\n        [Fact]\n        public void CanReadMallCtlStr()\n        {\n            Assert.StartsWith(\"5\", Jem.GetMallCtlStr(\"version\"));\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/MallocConfTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing Xunit;\n\nnamespace jemalloc.Tests\n{\n    public class MallocConfTests : jemallocTest\n    {\n        public MallocConfTests() : base() {}\n\n        [Fact]\n        public void CanGetConf()\n        {\n            Assert.Equal(\"tcache:false,narenas:3\", Jem.MallocConf);\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/MallocMessageTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing Xunit;\n\nnamespace jemalloc.Tests\n{\n    public class MallocMessageTests : jemallocTest\n    {\n        [Fact]\n        public void CanPrintMallocStats()\n        {\n            Assert.Contains(\"opt.narenas: 3\", Jem.MallocStats);\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/MallocTests.cs",
    "content": "using System;\nusing System.Diagnostics;\nusing Xunit;\n\nnamespace jemalloc.Tests\n{\n    public class MallocTests\n    {\n        public Process CurrentProcess { get; protected set; } = Process.GetCurrentProcess();\n\n        public MallocTests() : base()\n        {\n            init_privateMemorySize = CurrentProcess.PrivateMemorySize64;\n            init_peakPagedMem = CurrentProcess.PeakPagedMemorySize64;\n            init_peakWorkingSet = CurrentProcess.PeakWorkingSet64;\n            init_peakVirtualMem = CurrentProcess.PeakVirtualMemorySize64;\n            init_allocated = Jem.GetMallCtlUInt64(\"stats.allocated\");\n        }\n\n        [Fact]\n        public void CanMallocandFree()\n        {\n            Jem.Init(\"retain=false\");\n            long size = 100 * 1000 * 1000;\n            Assert.True(init_privateMemorySize < size);\n            Assert.True(init_allocated < (ulong) size);\n            IntPtr p = Jem.Malloc((ulong) size);\n            string stats = Jem.MallocStats;\n            ulong allocated = Jem.GetMallCtlUInt64(\"stats.allocated\");\n            CurrentProcess.Refresh();\n            Assert.True((CurrentProcess.PrivateMemorySize64 - init_privateMemorySize) >= size);\n            Assert.True(allocated > (ulong)size);\n            Jem.Free(p);\n        }\n\n        #region Fields\n        long init_privateMemorySize = 0;\n        long init_peakPagedMem = 0;\n        long init_peakWorkingSet = 0;\n        long init_peakVirtualMem = 0;\n        ulong init_allocated;\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/SafeArrayTests.cs",
    "content": "﻿using System;\nusing System.Numerics;\n\nusing Xunit;\nnamespace jemalloc.Tests\n{\n    public class SafeArrayTests : jemallocTest\n    {\n        [Fact(DisplayName = \"Can construct SafeArray\")]\n        public void CanConstructSafeArray()\n        {\n            SafeArray<int> a = new SafeArray<int>(500);\n            a[1] = 1000;\n            Assert.Equal(1000, a[1]);\n            a.Acquire();\n            Assert.Equal(1000, a[1]);\n            a.Acquire();\n            a.Release();\n            Assert.Equal(1000, a[1]);\n            a.Release();\n            Assert.Equal(1000, a[1]);\n            a.Close();\n            Assert.True(a.IsClosed);\n            Assert.Throws<InvalidOperationException>(() => a[1] == 1000);\n            //int r = a[(2,3)]\n        }\n\n        [Fact(DisplayName = \"Can convert to Vector\")]\n        public void CanConvertToVector()\n        {\n            SafeArray<uint> a = new SafeArray<uint>(8, 1, 11, 94, 5, 0, 0, 0, 8);\n            Vector<uint> v = a.GetVector<uint>();\n            Assert.Equal(a[0], v[0]);\n            Assert.Equal(a[3], v[3]);\n            Assert.Equal(a[7], v[7]);\n            SafeArray<uint> a2 = new SafeArray<uint>(12, 11, 112, 594, 65, 0, 0, 0, 8, 14, 90, 2, 8);\n            Vector<uint> v2 = a2.GetSliceAsVector(2);\n            Assert.Equal(594u, v2[0]);\n        }\n\n        [Fact]\n        public void CanVectorizedMultiply()\n        {\n            SafeArray<uint> a = new SafeArray<uint>(8, 1, 2, 3, 4, 5, 6, 7, 8);\n            SafeArray<int> b = new SafeArray<int>(8, 111, 22, 345, 40888, 3 , 777, 99, 6);\n            a.VectorMultiply(2);\n            Assert.Equal(2u, a[0]);\n            Assert.Equal(8u, a[3]);\n            Assert.Equal(16u, a[7]);\n            b.VectorMultiply(6);\n            Assert.Equal(666, b[0]);\n\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/UDTTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Buffers;\nusing System.Text;\n\nusing jemalloc.Examples;\n\nnamespace jemalloc.Tests\n{\n    public class UDTTests : jemallocTest\n    {\n        public SafeArray<TestUDT> Employees;\n        public UDTTests()\n        {\n            Employees = new SafeArray<TestUDT>(1024 * 1024);\n            for (int i = 0; i < Employees.Length; i++)\n            {\n                Employees[i] = TestUDT.MakeTestRecord(JemUtil.Rng);\n            }\n        }\n\n        public void CanVectorize()\n        {\n            Span<byte> s = Employees.GetSpan<byte>();\n            \n            int size = JemUtil.SizeOfStruct<TestUDT>();\n            /*\n            for (int i = 0; i < Employees.Length; i+= size * Employees[i].)\n            {\n               \n                //s.Slice\n                \n            }\n            */\n        }\n\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/Utf8BufferTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing Xunit;\n\nnamespace jemalloc.Tests\n{\n    public class Utf8BufferTests : jemallocTest\n    {\n        [Fact(DisplayName = \"Can construct Utf8Buffer\")]\n        public void CanConstructUtf8String()\n        {\n            Utf8Buffer s = new Utf8Buffer(\"Hello World\");\n            Assert.Equal(6, s.IndexOf(\"W\"));\n        }\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/VectorTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Numerics;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing Xunit;\n\nusing jemalloc.Buffers;\n\nnamespace jemalloc.Tests\n{\n    public class VectorTests\n    {\n        public const int Mandelbrot_Width = 768, Mandelbrot_Height = 512;\n        public const int Mandelbrot_Size = (int)Mandelbrot_Width * (int)Mandelbrot_Height;\n        public int VectorWidth = Vector<float>.Count;\n        public readonly Vector<double> Limit = new Vector<double>(4f);\n        public readonly Vector<double> Zero = Vector<double>.Zero;\n        public readonly Vector<double> MinusOne = Vector.Negate(Vector<double>.One);\n\n        public VectorTests()\n        {\n           \n        }\n\n        [Fact(DisplayName = \"Buffer elements can be accessed as vector.\")]\n        public void CanConstructVectors()\n        {\n            NativeMemory<uint> memory = new NativeMemory<uint>(1, 11, 94, 5, 0, 0, 0, 8);      \n            Vector<uint> v = memory.AsVector();\n            Assert.True(v[0] == 1);\n            Assert.True(v[1] == 11);\n            Assert.True(v[2] == 94);\n            NativeMemory<Vector<uint>> vectors = new NativeMemory<Vector<uint>>(4);\n            vectors.Retain();\n            \n        }\n\n        [Fact(DisplayName = \"Can correctly run Mandelbrot algorithm using Vector2 and managed arrays.\")]\n        public void CanVectorizeMandelbrotManaged()\n        {\n            byte[] o = _MandelbrotManagedv4();\n            Assert.Equal(0, o[0]);\n            Assert.Equal(2, o[1000]);\n            Assert.Equal(10, o[500]);\n            WriteMandelbrotPPM(o, \"mandelbrot-managed-v4.ppm\");\n        }\n\n        [Fact(DisplayName = \"Can correctly run Mandelbrot algorithm using Vector2 and managed arrays.\")]\n        public void CanVectorizeMandelbrotManaged5()\n        {\n            int[] o = new int[Mandelbrot_Height * Mandelbrot_Width];\n            _MandelbrotManagedv5(ref o);\n            Assert.Equal(0, o[0]);\n            Assert.Equal(2, o[1000]);\n            Assert.Equal(10, o[500]);\n            WriteMandelbrotPPM(o, \"mandelbrot-managed-v5.ppm\");\n        }\n\n        [Fact(DisplayName = \"Can correctly run Mandelbrot algorithm using Vector2 and unmanaged arrays.\")]\n        public void CanVectorizeMandelbrotUnmanaged()\n        {\n            FixedBuffer<byte> output = new FixedBuffer<byte>(Mandelbrot_Height * Mandelbrot_Width);\n            FixedBuffer<byte> o = _Mandelbrotv2Unmanaged(ref output);\n            Assert.Equal(0, o[0]);\n            Assert.Equal(2, o[1000]);\n            Assert.Equal(10, o[500]);\n            WriteMandelbrotPPM(o.CopyToArray(), \"mandelbrot_unmanaged.ppm\");\n            o.Free();\n        }\n\n        #region Mandelbrot algorithms\n        private int[] VectorizeMandelbrotManaged()\n        {\n            \n            int[] output = new int[((int)Mandelbrot_Width * (int)Mandelbrot_Height)];\n            Vector2 B = new Vector2(Mandelbrot_Width, Mandelbrot_Height);\n            Vector2 C0 = new Vector2(-2, -1);\n            Vector2 C1 = new Vector2(1, 1);\n            Vector2 D = (C1 - C0) / B;\n            \n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i++)\n                {\n                    Vector2 P = new Vector2(i, j);\n                    index = unchecked(j * (int)Mandelbrot_Width + i);\n                    Vector2 V = C0 + (P * D);\n                    output[index] = GetByte(ref V, 256);\n                }\n            }\n            return output;\n\n            int GetByte(ref Vector2 c, int count)\n            {\n                Vector2 z = c;\n                int i;\n                for (i = 0; i < count; i++)\n                {\n                    if (z.LengthSquared() > 4f)\n                    {\n                        break;\n                    }\n                    Vector2 w = z * z;\n                    z = c + new Vector2(w.X - w.Y, 2f * z.X * z.Y);\n                }\n                return i;\n            }\n\n        }\n\n        private FixedBuffer<int> Mandelbrotv1Unmanaged()\n        {\n            SafeArray<Vector<float>> Vectors = new SafeArray<Vector<float>>(8); // New unmanaged array of vectors\n            FixedBuffer<int> output = new FixedBuffer<int>(((int)Mandelbrot_Width * (int)Mandelbrot_Height)); //New unmanaged array for bitmap output\n            Span<float> VectorSpan = Vectors.GetSpan<float>(); //Lets us write to individual vector elements\n            Span<Vector2> Vector2Span = Vectors.GetSpan<Vector2>(); //Lets us read to individual vectors\n\n            VectorSpan[0] = -2f;\n            VectorSpan[1] = -1f;\n            VectorSpan[2] = 1f;\n            VectorSpan[3] = 1f;\n            VectorSpan[4] = Mandelbrot_Width;\n            VectorSpan[5] = Mandelbrot_Height;\n\n            ref Vector2 C0 = ref Vector2Span[0];\n            ref Vector2 C1 = ref Vector2Span[1];\n            ref Vector2 B = ref Vector2Span[2];\n            ref Vector2 P = ref Vector2Span[3];\n            Vector2 D = (C1 - C0) / B;\n\n\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i++)\n                {\n                    VectorSpan[6] = i;\n                    VectorSpan[7] = j;\n                    index = unchecked(j * (int)Mandelbrot_Width + i);\n                    Vector2 V = C0 + (P * D);\n                    output[index] = GetByte(ref V, 256);\n                }\n            }\n            Vectors.Close();\n            return output;\n\n            int GetByte(ref Vector2 c, int max_iterations)\n            {\n                Vector2 z = c; //make a copy\n                int i;\n                for (i = 0; i < max_iterations; i++)\n                {\n                    if (z.LengthSquared() > 4f)\n                    {\n                        break;\n                    }\n                    Vector2 w = z * z;\n                    z = c + new Vector2(w.X - w.Y, 2f * z.X * z.Y);\n                }\n                return i;\n            }\n\n        }\n\n        private void WriteMandelbrotPPM(int[] output, string name)\n        {\n\n            using (StreamWriter sw = new StreamWriter(name))\n            {\n                sw.Write(\"P6\\n\");\n                sw.Write(string.Format(\"{0} {1}\\n\", Mandelbrot_Width, Mandelbrot_Height));\n                sw.Write(\"255\\n\");\n                sw.Close();\n            }\n            using (BinaryWriter bw = new BinaryWriter(new FileStream(name, FileMode.Append)))\n            {\n                for (int i = 0; i < Mandelbrot_Width * Mandelbrot_Height; i++)\n                {\n                    byte b = output[i] == 256 ? (byte) 20 : (byte) 240;\n                    bw.Write(b);\n                    bw.Write(b);\n                    bw.Write(b);\n                }\n            }\n            \n        }\n\n        private void WriteMandelbrotPPM(byte[] output, string name)\n        {\n\n            using (StreamWriter sw = new StreamWriter(name))\n            {\n                sw.Write(\"P6\\n\");\n                sw.Write(string.Format(\"{0} {1}\\n\", Mandelbrot_Width, Mandelbrot_Height));\n                sw.Write(\"255\\n\");\n                sw.Close();\n            }\n            using (BinaryWriter bw = new BinaryWriter(new FileStream(name, FileMode.Append)))\n            {\n                for (int i = 0; i < Mandelbrot_Width * Mandelbrot_Height; i++)\n                {\n                    byte b = output[i] == 255 ? (byte)20 : (byte)240;\n                    bw.Write(b);\n                    bw.Write(b);\n                    bw.Write(b);\n                }\n            }\n\n        }\n\n        #region WIP\n        private unsafe FixedBuffer<long> VectorDoubleMandelbrot()\n        {\n            //Allocate heap and stack memory for our Vector constants and variables\n            FixedBuffer<long> output = new FixedBuffer<long>(Mandelbrot_Size); //Output bitmap on unmanaged heap\n            double* ptrC0 = stackalloc double[VectorWidth * 2]; \n            double* ptrC1 = stackalloc double[VectorWidth * 2];\n            double* ptrB = stackalloc double[VectorWidth * 2];\n            double* ptrD = stackalloc double[VectorWidth * 2];\n            double* ptrP = stackalloc double[VectorWidth * 2];\n            double* ptrV = stackalloc double[VectorWidth * 2];\n\n            //Fill memory with the constant values for vectors C0, C1, B\n            for (int i = 0; i < VectorWidth; i++)\n            {\n                ptrC0[i] = -2f; //x0\n                ptrC0[i + VectorWidth] = -1; //y0\n                ptrC1[i] = 1; //x1\n                ptrC1[i + VectorWidth] = 1; //y1\n                ptrB[i] = Mandelbrot_Width; //width\n                ptrB[i + VectorWidth] = Mandelbrot_Height; //height\n            }\n\n            //Declare spans for reading and writing to memory locations of Vector constants and variables\n            Span<Vector<double>> C0 = new Span<Vector<double>>(ptrC0, 2);\n            Span<Vector<double>> C1 = new Span<Vector<double>>(ptrC1, 2);\n            Span<Vector<double>> B = new Span<Vector<double>>(ptrB, 2);\n            Span<Vector<double>> D = new Span<Vector<double>>(ptrD, 2);\n            Span<Vector<double>> P = new Span<Vector<double>>(ptrP, 2);\n            Span<Vector<double>> V = new Span<Vector<double>>(ptrV, 2);\n\n            Span<Vector<long>> O = output.AcquireVectorWriteSpan();\n\n            D[0] = (C1[0] - C0[0]) / B[0];\n            D[1] = (C1[0] - C0[0]) / B[0];\n            \n            int index;\n\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n                {\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        ptrP[h] = i + h;\n                    }\n                    index = unchecked((int)Mandelbrot_Width * j + i);\n                    V[0] = C0[0] + (P[0] * D[0]);\n                    V[1] = C0[1] + (P[1] * D[1]);\n                    Vector<long> G = GetValue(V[0], V[1], 256);\n                    O[index] = G;\n                    \n                }\n            }\n            output.Release();\n\n            return output;\n\n \n        }\n\n        private Vector<double> SquareAbs(Vector<double> Vre, Vector<double> Vim)\n        {\n            return (Vre * Vre) + (Vim * Vim);\n        }\n\n        private unsafe Vector<long> GetValue(Vector<double> Cx, Vector<double> Cy, int maxIterations)\n        {\n            //int* ptrIterations = stackalloc int[VectorWidth];\n            double[] iterationsArr = new double[VectorWidth]; //memory for Iterations vector\n            Span<double> sIterations = new Span<double>(iterationsArr); //write to Iterations vector\n            Vector<double> Iterations = sIterations.NonPortableCast<double, Vector<double>>()[0];\n            Vector<double> MaxIterations = new Vector<double>(256);\n            double[] zArr = new double[VectorWidth * 2];\n            //double* ptrZ = stackalloc double[VectorWidth * 2];\n            Span<double> sZ = new Span<double>(zArr); //Write to individual components of Z\n            Span<Vector<double>> Z = sZ.NonPortableCast<double, Vector<double>>();\n            Z[0] = Cx;\n            Z[1] = Cy;\n            for (int i = 0; i < maxIterations; i++)\n            {\n                sIterations.Fill(i);\n                Vector<double> S = SquareAbs(Z[0], Z[1]);\n                if (Vector.GreaterThanAll(S, Limit))\n                {\n                    break;\n                }\n                else\n                {\n                    Vector<long> increment;\n                    do\n                    {\n                        Z[0] = Cx + (Z[0] * Z[0]) - (Z[0] * Z[1]);\n                        Z[1] = Cy + 2f * Z[0] * Z[1];\n                        S = SquareAbs(Z[0], Z[1]);\n                        Vector<long> greaterThanLimitMask = Vector.GreaterThan(S, Limit);\n                        Vector<long> lessThanOrEqualMaxIterationsMask = Vector.LessThanOrEqual(Iterations, MaxIterations);\n                        increment = greaterThanLimitMask & lessThanOrEqualMaxIterationsMask;\n                        i += 1;\n                    }\n                    while (increment != Vector<long>.Zero);\n\n                }\n            }\n            return Vector.ConvertToInt64(new Vector<double>(iterationsArr));\n        }\n\n        private FixedBuffer<byte> _Mandelbrotv2Unmanaged(ref FixedBuffer<byte> output)\n        {\n            VectorWidth = Vector<Single>.Count;\n            Vector<int> One = Vector<int>.One;\n            Vector<int> Zero = Vector<int>.Zero;\n\n            FixedBuffer<float> Vectors = new FixedBuffer<float>(6);\n            FixedBuffer<float> P = new FixedBuffer<float>(VectorWidth * 2);\n            Span<Vector2> Vector2Span = Vectors.AcquireWriteSpan().NonPortableCast<float, Vector2>(); //Lets us read individual Vector2\n            Span<Vector<float>> PSpan = P.AcquireWriteSpan().NonPortableCast<float, Vector<float>>(); //Lets us read individual Vectors\n            Vectors[0] = -2f;\n            Vectors[1] = -1f;\n            Vectors[2] = 1f;\n            Vectors[3] = 1f;\n            Vectors[4] = Mandelbrot_Width;\n            Vectors[5] = Mandelbrot_Height;\n\n            ref Vector2 C0 = ref Vector2Span[0];\n            ref Vector2 C1 = ref Vector2Span[1];\n            ref Vector2 B = ref Vector2Span[2];\n            Vector2 D = (C1 - C0) / B;\n\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n                {\n\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        P[h] = C0.X + (D.X * (i + h));\n                        P[h + VectorWidth] = C0.Y + (D.Y * j);\n                    }\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector<float> Vre = PSpan[0];\n                    Vector<float> Vim = PSpan[1]; ;\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 256);\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        output[index + h] = outputVector[h] < 255 ? (byte)outputVector[h] : (byte) 255;\n                    }\n                }\n            }\n            Vectors.Release();\n            Vectors.Free();\n            P.Release();\n            P.Free();\n\n            return output;\n\n            Vector<int> GetByte(ref Vector<float> Cre, ref Vector<float> Cim, int max_iterations)\n            {\n                Vector<float> Zre = Cre; //make a copy\n                Vector<float> Zim = Cim; //make a copy\n\n                Vector<float> Limit = new Vector<float>(4);\n                Vector<int> MaxIterations = new Vector<int>(max_iterations);\n                Vector<int> Increment = One;\n                Vector<int> I;\n                for (I = Zero; Increment != Zero; I += Vector.Abs(Increment))\n                {\n                    Vector<float> S = SquareAbs(Zre, Zim);\n                    Increment = Vector.LessThanOrEqual(S, Limit) & Vector.LessThanOrEqual(I, MaxIterations);\n                    if (Increment == Zero)\n                    {\n                        break;\n                    }\n                    else\n                    {\n                        Vector<float> Tre = Zre;\n                        Vector<float> Tim = Zim;\n                        Zre = Cre + (Tre * Tre - Tim * Tim);\n                        Zim = Cim + 2f * Tre * Tim;\n                    }\n                }\n                return I;\n            }\n\n            Vector<float> SquareAbs(Vector<float> Vre, Vector<float> Vim)\n            {\n                return (Vre * Vre) + (Vim * Vim);\n            }\n\n        }\n\n        private byte[] _MandelbrotManagedv4()\n        {\n            byte[] output = new byte[Mandelbrot_Height * Mandelbrot_Width];\n            Vector<int> One = Vector<int>.One;\n            Vector<int> Zero = Vector<int>.Zero;\n            float[] Vectors = new float[6];\n            Span<Vector2> Vector2Span = new Span<float>(Vectors).NonPortableCast<float, Vector2>(); //Lets us read individual Vector2\n\n            Vectors[0] = -2f;\n            Vectors[1] = -1f;\n            Vectors[2] = 1f;\n            Vectors[3] = 1f;\n            Vectors[4] = Mandelbrot_Width;\n            Vectors[5] = Mandelbrot_Height;\n\n            Vector2 C0 = Vector2Span[0];\n            Vector2 C1 = Vector2Span[1];\n            Vector2 B = Vector2Span[2];\n            Vector2 D = (C1 - C0) / B;\n\n            \n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                Parallel.ForEach(MandelbrotBitmapLocation(j), (p) =>\n                {\n                    int i = p.Item1;\n                    float[] Pre = new float[VectorWidth];\n                    float[] Pim = new float[VectorWidth];\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        Pre[h] = C0.X + (D.X * (i + h));\n                        Pim[h] = C0.Y + (D.Y * p.Item2);\n                    }\n                    int index = unchecked(p.Item2 * Mandelbrot_Width + i);\n                    Vector<float> Vre = new Vector<float>(Pre);\n                    Vector<float> Vim = new Vector<float>(Pim);\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 255);\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        output[index + h] = outputVector[h] < 255 ? (byte)outputVector[h] : (byte)255;\n                    }\n                });\n\n            }\n            return output;\n\n            Vector<int> GetByte(ref Vector<float> Cre, ref Vector<float> Cim, int max_iterations)\n            {\n                Vector<float> Limit = new Vector<float>(4);\n                Vector<int> MaxIterations = new Vector<int>(max_iterations);\n                Vector<float> Zre = Cre; //make a copy\n                Vector<float> Zim = Cim; //make a copy\n\n                Vector<int> Increment = One;\n                Vector<int> I;\n                for (I = Zero; Increment != Zero; I += Vector.Abs(Increment))\n                {\n                    Vector<float> S = SquareAbs(Zre, Zim);\n                    Increment = Vector.LessThanOrEqual(S, Limit) & Vector.LessThan(I, MaxIterations);\n                    if (Increment == Zero)\n                    {\n                        break;\n                    }\n                    else\n                    {\n                        Vector<float> Tre = Zre;\n                        Vector<float> Tim = Zim;\n                        Zre = Cre + (Tre * Tre - Tim * Tim);\n                        Zim = Cim + 2f * Tre * Tim;\n                    }\n                }\n                return I;\n            }\n\n            Vector<float> SquareAbs(Vector<float> Vre, Vector<float> Vim)\n            {\n                return (Vre * Vre) + (Vim * Vim);\n            }\n\n            IEnumerable<ValueTuple<int, int>> MandelbrotBitmapLocation(int j)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n                {\n                    yield return (i, j);\n                }\n            }\n        }\n\n        private unsafe int[] _MandelbrotManagedv5(ref int[] output)\n        {\n\n            Vector<int> One = Vector<int>.One;\n            Vector<int> Zero = Vector<int>.Zero;\n            Vector<float> Limit = new Vector<float>(4);\n\n            float[] Vectors = new float[6];\n            float[] P = new float[VectorWidth * 2];\n\n            Span<Vector2> Vector2Span = new Span<float>(Vectors).NonPortableCast<float, Vector2>(); //Lets us read individual Vector2\n            Span<Vector<float>> PSpan = new Span<float>(P).NonPortableCast<float, Vector<float>>(); //Lets us read individual Vectors\n            Vectors[0] = -2f;\n            Vectors[1] = -1f;\n            Vectors[2] = 1f;\n            Vectors[3] = 1f;\n            Vectors[4] = Mandelbrot_Width;\n            Vectors[5] = Mandelbrot_Height;\n\n            ref Vector2 C0 = ref Vector2Span[0];\n            ref Vector2 C1 = ref Vector2Span[1];\n            ref Vector2 B = ref Vector2Span[2];\n            Vector2 D = (C1 - C0) / B;\n\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i += VectorWidth)\n                {\n\n                    for (int h = 0; h < VectorWidth; h++)\n                    {\n                        P[h] = C0.X + (D.X * (i + h));\n                        P[h + VectorWidth] = C0.Y + (D.Y * j);\n                    }\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector<float> Vre = PSpan[0];\n                    Vector<float> Vim = PSpan[1]; ;\n                    Vector<int> outputVector = GetByte(ref Vre, ref Vim, 256);\n                    outputVector.CopyTo(output, index);\n                }\n            }\n            return output;\n\n\n            Vector<int> GetByte(ref Vector<float> Cre, ref Vector<float> Cim, int max_iterations)\n            {\n                Vector<float> Zre = Cre; //make a copy\n                Vector<float> Zim = Cim; //make a copy\n\n                Vector<int> Increment = One;\n                Vector<int> MaxIterations = new Vector<int>(max_iterations);\n                Vector<int> I;\n                for (I = Zero; Increment != Zero; I += Vector.Abs(Increment))\n                {\n                    Vector<float> S = SquareAbs(Zre, Zim);\n                    Increment = Vector.LessThanOrEqual(S, Limit) & Vector.LessThan(I, MaxIterations);\n                    if (Increment == Zero)\n                    {\n                        break;\n                    }\n                    else\n                    {\n                        Vector<float> Tre = Zre;\n                        Vector<float> Tim = Zim;\n                        Zre = Cre + (Tre * Tre - Tim * Tim);\n                        Zim = Cim + 2f * Tre * Tim;\n                    }\n                }\n                return I;\n            }\n\n            Vector<float> SquareAbs(Vector<float> Vre, Vector<float> Vim)\n            {\n                return (Vre * Vre) + (Vim * Vim);\n            }\n        }\n\n        private FixedBuffer<byte> _MandelbrotUnmanagedv1(ref FixedBuffer<byte> output)\n        {\n            FixedBuffer<float> Vectors = new FixedBuffer<float>(10);\n            Span<Vector2> Vector2Span = Vectors.AcquireWriteSpan().NonPortableCast<float, Vector2>(); //Lets us read individual vectors\n\n            Vectors[0] = -2f;\n            Vectors[1] = -1f;\n            Vectors[2] = 1f;\n            Vectors[3] = 1f;\n            Vectors[4] = Mandelbrot_Width;\n            Vectors[5] = Mandelbrot_Height;\n\n            ref Vector2 C0 = ref Vector2Span[0];\n            ref Vector2 C1 = ref Vector2Span[1];\n            ref Vector2 B = ref Vector2Span[2];\n            ref Vector2 P = ref Vector2Span[3];\n            Vector2 D = (C1 - C0) / B;\n\n            int index;\n            for (int j = 0; j < Mandelbrot_Height; j++)\n            {\n                for (int i = 0; i < Mandelbrot_Width; i++)\n                {\n                    Vectors[6] = i;\n                    Vectors[7] = j;\n                    index = unchecked(j * Mandelbrot_Width + i);\n                    Vector2 V = C0 + (P * D);\n                    output[index] = GetByte(ref V, 256);\n                }\n            }\n            Vectors.Release();\n            return output;\n\n            byte GetByte(ref Vector2 c, int max_iterations)\n            {\n                Vector2 z = c; //make a copy\n                int i;\n                for (i = 0; i < max_iterations; i++)\n                {\n                    if (z.LengthSquared() > 4f)\n                    {\n                        return (byte)i;\n                    }\n                    Vector2 w = z * z;\n                    z = c + new Vector2(w.X - w.Y, 2f * z.X * z.Y);\n                }\n                return (byte)(i - 1);\n            }\n\n        }\n\n        #endregion\n\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "jemalloc.Tests/jemalloc.Tests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.0</TargetFramework>\n\n    <IsPackable>false</IsPackable>\n\n    <Platforms>AnyCPU;x64</Platforms>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <OutputPath>..\\x64\\Debug\\</OutputPath>\n    <PlatformTarget>x64</PlatformTarget>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutputPath>..\\x64\\Debug\\</OutputPath>\n    <PlatformTarget>x64</PlatformTarget>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <OutputPath>..\\x64\\Release\\</OutputPath>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"15.3.0-preview-20170628-02\" />\n    <PackageReference Include=\"xunit\" Version=\"2.3.1\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"2.3.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\jemalloc.Api\\jemalloc.Api.csproj\" />\n    <ProjectReference Include=\"..\\jemalloc.Buffers\\jemalloc.Buffers.csproj\" />\n    <ProjectReference Include=\"..\\jemalloc.Examples\\jemalloc.Examples.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "jemalloc.Tests/jemallocTest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Text;\n\nusing Xunit;\n\nnamespace jemalloc.Tests\n{\n    public abstract class jemallocTest\n    {\n        public static Random Rng = new Random();\n        public Process CurrentProcess { get; protected set; } = Process.GetCurrentProcess();\n\n        public jemallocTest()\n        {\n            Jem.Init(\"dirty_decay_ms:1,muzzy_decay_ms:1,tcache:false,narenas:3\");\n            init_privateMemorySize = CurrentProcess.PrivateMemorySize64;\n            init_peakPagedMem = CurrentProcess.PeakPagedMemorySize64;\n            init_peakWorkingSet = CurrentProcess.PeakWorkingSet64;\n            init_peakVirtualMem = CurrentProcess.PeakVirtualMemorySize64;\n            init_allocated = Jem.AllocatedBytes;\n        }\n\n        #region Fields\n        long init_privateMemorySize = 0;\n        long init_peakPagedMem = 0;\n        long init_peakWorkingSet = 0;\n        long init_peakVirtualMem = 0;\n        ulong init_allocated;\n        #endregion\n    }\n}\n"
  },
  {
    "path": "jembench.cmd",
    "content": "@echo off\ndotnet .\\x64\\Release\\netcoreapp2.0\\jemalloc.Cli.dll %*\n:end"
  }
]