Commit Graph

106 Commits

Author SHA1 Message Date
Matthew Parkinson
d900e29424 Improve slow path performance for allocation (#143)
* Remote dealloc refactor.

* Improve remote dealloc

Change remote to count down to 0, so fast path does not need a constant.

Use signed value so that branch does not depend on addition.

* Inline remote_dealloc

The fast path of remote_dealloc is sufficiently compact that it can be
inlined.

* Improve fast path in Slab::alloc

Turn the internal structure into tail calls, to improve fast path.
Should be no algorithmic changes.

* Refactor initialisation to help fast path.

Break lazy initialisation into two functions, so it is easier to codegen
fast paths.

* Minor tidy to statically sized dealloc.

* Refactor semi-slow path for alloc

Make the backup path a bit faster.  Only algorithmic change is to delay
checking for first allocation. Otherwise, should be unchanged.

* Test initial operation of a thread

The first operation a new thread takes is special.  It results in
allocating an allocator, and swinging it into the TLS.  This makes
this a very special path, that is rarely tested.  This test generates
a lot of threads to cover the first alloc and dealloc operations.

* Correctly handle reusing get_noncachable

* Fix large alloc stats

Large alloc stats aren't necessarily balanced on a thread, this changes
to tracking individual pushs and pops, rather than the net effect
(with an unsigned value).

* Fix TLS init on large alloc path

* Add Bump ptrs to allocator

Each allocator has a bump ptr for each size class.  This is no longer
slab local.

Slabs that haven't been fully allocated no longer need to be in the DLL
for this sizeclass.

* Change to a cycle non-empty list

This change reduces the branching in the case of finding a new free
list. Using a non-empty cyclic list enables branch free add, and a
single branch in remove to detect the empty case.

* Update differences

* Rename first allocation

Use needs initialisation as makes more sense for other scenarios.

* Use a ptrdiff to help with zero init.

* Make GlobalPlaceholder zero init

The GlobalPlaceholder allocator is now a zero init block of memory.
This removes various issues for when things are initialised. It is made read-only
to we detect write to it on some platforms.
2020-03-31 09:17:53 +01:00
Matthew Parkinson
77c453600b OE fixes (#157)
* Only compile OE PAL if required.

* OE:reserve: Fix bug in loop.

* Handle out of memory by returning nullptr.
2020-03-25 08:10:39 +00:00
Amaury Chamayou
8e3efcb1dc Assert not going through the PAL (#140)
* Assert not going through the PAL

* Make it more difficult to assert() accidentally
2020-03-11 15:58:44 +00:00
Matthew Parkinson
76eaf1adad Remote dealloc refactor. (#138)
Improve remote dealloc

- Outline the slow path to improve code gen significantly

- Handle message queue only on slow path for remote dealloc.

- Change remote size to count down 0, so fast path does not need a constant.

- Use signed value so that branch does not depend on addition.
2020-03-10 08:12:57 +00:00
Amaury Chamayou
acbcbce597 replace assert with SNMALLOC_ASSERT 2020-03-04 16:57:44 +00:00
Matthew Parkinson
02427f98f0 Clangformat. 2020-02-04 14:12:28 +00:00
Matthew Parkinson
2e289573c8 Move all decommit strategy into LargeAllocator
The code for decommit was distribured in the code base.
Removing Decommit All means that it can logically reside in
lthe arge allocator.
2020-01-29 12:29:32 +00:00
Matthew Parkinson
2e4b289991 Removed DecommitAll strategy
The DecommitAll strategy performs badly.  We are not
functionally testing it, and it does not seem investing in it due to its
performance.
2020-01-29 11:58:57 +00:00
Matthew Parkinson
4212ac8e4e Improve codegen for sized free. (#115)
For languages like Verona or Rust, the deallocation calls know the
size of the object originally requested.  This change optimises that
code path to create a much better fast path.
2020-01-22 17:41:08 +00:00
Matthew Parkinson
e8e0f60ccf Fix GCC 9 error. 2020-01-07 11:06:12 +00:00
Nathaniel Filardo
4d6759aca4 Make "pal_supports" not a function
But rather a template vardecl, as per C++14
2019-12-04 16:54:41 +00:00
Nathaniel Filardo
83c467eb92 ds/address: add pointer diff function
And use it rather than open-coding subtraction of two address_cast-s.
2019-11-26 15:50:22 +00:00
Nathaniel Filardo
eb2d8890de Additional provenance preservation 2019-11-26 15:37:52 +00:00
Nathaniel Filardo
20e804728b Move bits::is_aligned_block to address.h
And chase consequences
2019-11-26 15:33:09 +00:00
Nathaniel Filardo
ad96ba05c1 largealloc: don't zero memory twice
If the decommit strategy is DecommitSuperLazy, then both the constexpr
if and the ordinary if would fire; add an else so we only fall into one.
2019-11-26 14:59:54 +00:00
Nathaniel Filardo
2af4c64698 Improve commentary 2019-11-26 14:58:47 +00:00
Matthew Parkinson
11923154e8 Merge pull request #100 from CTSRD-CHERI/for-upstream-static-pagemap-slabmap
Deconflate "pagemap"
2019-11-25 16:26:55 +00:00
Nathaniel Filardo
d5b478ecb3 Deconflate "Pagemap" objects
There are two things calling themselves pagemaps:

- the src/mem/pagemap.h objects of that name

- the SuperslabMap object gets called a PageMap inside the Allocator

Rename the latter to chunkmap, with appropriate case and snake,
everywhere, and pull it out to its own file (chunkmap.h).

The default implementation of a chunkmap is a purely static object, but
we nevertheless instantiate it per allocator, so that other
implementations can use stateful instances when interposing on the
mutation methods.  Note that the "get" method, however, must remain
static to support the interface required by Allocator objects.
2019-11-21 15:35:56 +00:00
Matthew Parkinson
efd5228da6 Store a full pointer in the Metaslab
This improves the codegen.
2019-11-21 11:39:55 +00:00
Nathaniel Filardo
574700318e debug_is_empty: don't dealloc() free space
We know that these are small objects and that they have already had
their cache friendly offsets applied, so jump in to the dealloc path
futher down, below the stats calls.

Split small_dealloc_offseted into a wrapper around the core to avoid
inlining too much into the debug function.

While here, move the handling of the Remote objects into its own block
so that `p` is out of scope thereafter.

Fixes https://github.com/microsoft/snmalloc/issues/98
2019-11-14 22:59:02 +00:00
Matthew Parkinson
7a3f0eb50b Clang format 2019-11-14 14:23:56 +00:00
Matthew Parkinson
4046417f25 Fix cache friendly offset. 2019-11-14 14:02:50 +00:00
Matthew Parkinson
74cc475787 Code review feedback. 2019-11-14 13:34:57 +00:00
Matthew Parkinson
14383614e0 Clang tidy 2019-11-14 13:04:24 +00:00
Matthew Parkinson
c2799f6ec8 Make debug_check_empty not use statistics
Debug_check_empty now empties the free lists, and checks it empties all the
queues in the allocator.  This does not require statistic tracking to
work anymore.

This additionally can check internal regression that cause leaks that
are not the clients fault.
2019-11-14 12:55:23 +00:00
Matthew Parkinson
23b4230f6a Fixed leak in free list.
If the first call to alloc uses the minimum size class, then we end up
leaking a whole page of allocations. We fill the small_fast_free_list,
in a call to build the message_queue. But this means the
small_fast_free_list[0] is not empty.  But the code was staying on the
slow path, and overwriting it.
2019-11-14 12:50:53 +00:00
Matthew Parkinson
f214abde3f Typo in assertion. 2019-09-30 13:43:32 +01:00
David Chisnall
0b2b4d68a2 Revert "Add type confusion protection to the default memory provider."
This reverts commit d56201e28d.
2019-09-12 17:16:48 +01:00
David Chisnall
d56201e28d Add type confusion protection to the default memory provider. 2019-08-13 17:30:37 +01:00
David Chisnall
bbf016bac8 Merge pull request #84 from microsoft/bug-fix
Bug fix
2019-08-13 16:57:21 +01:00
David Chisnall
d2dc653af2 Make the pagemap global typed.
The pagemap global is now an inline static of a template class, so that
we will see different symbols for the different types.

Issue #84 showed that it's possible to compile two compilation units
with different pagemaps, link them together, and have them attempt to
interpret the global pagemap as two different types.  This change should
make that impossible.

Also make the `pagemap()` function static so that it can be used from
static functions, avoiding other things that directly reference the
global pagemap.
2019-08-13 14:24:50 +01:00
Matthew Parkinson
e6b4efd980 Don't apply changes to GlobalPlaceholder. 2019-08-13 13:04:29 +01:00
Paul Liétar
a5379b24d5 Add remove_cache_friendly_offset calls in a few places that were missing it. 2019-07-17 13:14:59 +01:00
Matthew Parkinson
1b0923e141 Clang-tidy 2019-07-15 19:51:11 +01:00
Matthew Parkinson
33ff935aee Remove infinite loop from adding message queue check
Adding a handle_message_queue here lead to an infinite loop.
2019-07-10 20:11:05 +01:00
Matthew Parkinson
45f47499c5 Improved pal_supports 2019-07-10 20:11:05 +01:00
Matthew Parkinson
23b3e35d6e Add comment about inlining choices. 2019-07-10 20:11:04 +01:00
Matthew Parkinson
9fd238d5fa Move remote dealloc to slow path
It is only ever called in a tail position, so slow path means it is just
a jump, but improves the local deallocation fast path's codegen
considerably.
2019-07-10 20:11:04 +01:00
Matthew Parkinson
e240dd279a Use FlatPageMap on OS with lazy commit
If the operating system will allocate private pages on demand for the
pagemap then use the FlatPageMap by default as it generates better code
for deallocation.
2019-07-10 20:11:03 +01:00
David Chisnall
c35a3941fe Merge pull request #65 from microsoft/queue_of_slabs
Use a queue of slabs for free lists
2019-07-08 20:53:06 +01:00
Matthew Parkinson
d1db6d07ad Use a queue of slabs for free lists
This commit changes the strategy for finding a free list from
a stack to a queue.  This tends to avoid the slow path considerably more.
It has some memory overheads.

TOOD:  We should move the bump allocation data out of the metaslab and
into the allocator.  At the moment, the slab contains the bump allocation
data, we should move this into the allocator, as it only ever has one slab
it is bump allocating from per sizeclass.
2019-07-05 17:04:55 +01:00
David Chisnall
2efcddfc3d Rework free list so that 0 is the placeholder.
This is needed because in some configurations the constructor for the
global placeholder is not called before the first allocation (i.e. when
other globals call the allocator in their constructor) and so we ended
up following a null pointer.
2019-07-05 14:20:24 +01:00
David Chisnall
50695d07f8 Disable an always_inline with GCC in debug mode.
Most compilers are happy if you say always-inline but they can't.  GCC
will complain.  Here, we have two mutually recursive functions that are
marked as always inline.  In an optimised build, one is inlined into the
other and then becomes a tail-recursive function that should inline the
tail call.  Inlining the tail call can be done by simply jumping to the
start of the function and so everything is fine.  In a debug build, the
second transform doesn't happen and so we're left with a call to an
always-inline function.
2019-07-05 11:39:14 +01:00
David Chisnall
eefc9e49c5 Fix some duplicate inline warnings. 2019-07-05 11:39:01 +01:00
David Chisnall
1e65aafa06 Add missing fast-path annotations. 2019-07-05 09:42:07 +01:00
David Chisnall
b8a5d7fca9 Lazily initialise TLS on slow paths.
Copying an idea from mimalloc, initialise the TLS variable to a global
allocator that doesn't own any memory and then lazily check when we hit
a slow path (which we always do when using the global allocator, because
it doesn't own any memory) if we are the global allocator and replace
it.

There is a slight complication compared to mimalloc's version of this
idea.  Snmalloc collects outgoing messages and it's possible for the
first operation in a thread to be a free of memory allocated by a
different thread.  We address this by initialising the queues with a
size value indicating that they are full and then do the lazy check when
about to insert a message that would make a queue full.  This will then
trigger lazy creation of an allocator.

Global initialisation doesn't work for the fake allocator, so skip most
of its constructor.
2019-07-05 09:41:32 +01:00
Matthew Parkinson
4cf19f3a4c Clangformat. 2019-07-02 16:18:03 +01:00
Matthew Parkinson
ea399660ce Fix for zero size allocations. 2019-07-02 15:58:19 +01:00
Matthew Parkinson
8970e70806 Clangformat 2019-07-02 15:44:10 +01:00
Matthew Parkinson
57e94b5824 Ensure id set on dummy deallocation. 2019-07-02 15:38:48 +01:00