summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/scudo/standalone/primary64.h
Commit message (Collapse)AuthorAgeFilesLines
* [scudo][standalone] Fork supportKostya Kortchinsky2020-01-141-4/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: fork() wasn't well (or at all) supported in Scudo. This materialized in deadlocks in children. In order to properly support fork, we will lock the allocator pre-fork and unlock it post-fork in parent and child. This is done via a `pthread_atfork` call installing the necessary handlers. A couple of things suck here: this function allocates - so this has to be done post initialization as our init path is not reentrance, and it doesn't allow for an extra pointer - so we can't pass the allocator we are currently working with. In order to work around this, I added a post-init template parameter that gets executed once the allocator is initialized for the current thread. Its job for the C wrappers is to install the atfork handlers. I reorganized a bit the impacted area and added some tests, courtesy of cferris@ that were deadlocking prior to this fix. Subscribers: jfb, #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D72470
* scudo: Replace a couple of macros with their expansions.Peter Collingbourne2019-11-271-1/+1
| | | | | | | | | The macros INLINE and COMPILER_CHECK always expand to the same thing (inline and static_assert respectively). Both expansions are standards compliant C++ and are used consistently in the rest of LLVM, so let's improve consistency with the rest of LLVM by replacing them with the expansions. Differential Revision: https://reviews.llvm.org/D70793
* [scudo][standalone] Minor optimization & improvementsKostya Kortchinsky2019-11-211-4/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: A few small improvements and optimizations: - when refilling the free list, push back the last batch and return the front one: this allows to keep the allocations towards the front of the region; - instead of using 48 entries in the shuffle array, use a multiple of `MaxNumCached`; - make the maximum number of batches to create on refil a constant; ultimately it should be configurable, but that's for later; - `initCache` doesn't need to zero out the cache, it's already done. - it turns out that when using `||` or `&&`, the compiler is adamant on adding a short circuit for every part of the expression. Which ends up making somewhat annoying asm with lots of test and conditional jump. I am changing that to bitwise `|` or `&` in two place so that the generated code looks better. Added comments since it might feel weird to people. This yields to some small performance gains overall, nothing drastic though. Reviewers: hctim, morehouse, cferris, eugenis Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D70452
* [scudo][standalone] Consolidate listsKostya Kortchinsky2019-10-281-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This is a clean patch using the last diff of D69265, but using git instead of svn, since svn went ro and arc was making my life harded than it needed to be. I was going to introduce a couple more lists and realized that our lists are currently a bit all over the place. While we have a singly linked list type relatively well defined, we are using doubly linked lists defined on the fly for the stats and for the secondary blocks. This CL adds a doubly linked list object, reorganizing the singly list one to extract as much of the common code as possible. We use this new type in the stats and the secondary. We also reorganize the list tests to benefit from this consolidation. There are a few side effect changes such as using for iterator loops that are, in my opinion, cleaner in a couple of places. Reviewers: hctim, morehouse, pcc, cferris Reviewed By: hctim Subscribers: jfb, #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D69516
* [scudo][standalone] Get statistics in a char bufferKostya Kortchinsky2019-10-091-17/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Following up on D68471, this CL introduces some `getStats` APIs to gather statistics in char buffers (`ScopedString` really) instead of printing them out right away. Ultimately `printStats` will just output the buffer, but that allows us to potentially do some work on the intermediate buffer, and can be used for a `mallocz` type of functionality. This allows us to pretty much get rid of all the `Printf` calls around, but I am keeping the function in for debugging purposes. This changes the existing tests to use the new APIs when required. I will add new tests as suggested in D68471 in another CL. Reviewers: morehouse, hctim, vitalybuka, eugenis, cferris Reviewed By: morehouse Subscribers: delcypher, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D68653 llvm-svn: 374173
* [scudo][standalone] Correct releaseToOS behaviorKostya Kortchinsky2019-10-071-16/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: There was an issue in `releaseToOSMaybe`: one of the criteria to decide if we should proceed with the release was wrong. Namely: ``` const uptr N = Sci->Stats.PoppedBlocks - Sci->Stats.PushedBlocks; if (N * BlockSize < PageSize) return; // No chance to release anything. ``` I meant to check if the amount of bytes in the free list was lower than a page, but this actually checks if the amount of **in use** bytes was lower than a page. The correct code is: ``` const uptr BytesInFreeList = Region->AllocatedUser - (Region->Stats.PoppedBlocks - Region->Stats.PushedBlocks) * BlockSize; if (BytesInFreeList < PageSize) return 0; // No chance to release anything. ``` Consequences of the bug: - if a class size has less than a page worth of in-use bytes (allocated or in a cache), reclaiming would not occur, whatever the amount of blocks in the free list; in real world scenarios this is unlikely to happen and be impactful; - if a class size had less than a page worth of free bytes (and enough in-use bytes, etc), then reclaiming would be attempted, with likely no result. This means the reclaiming was overzealous at times. I didn't have a good way to test for this, so I changed the prototype of the function to return the number of bytes released, allowing to get the information needed. The test added fails with the initial criteria. Another issue is that `ReleaseToOsInterval` can actually be 0, meaning we always try to release (side note: it's terrible for performances). so change a `> 0` check to `>= 0`. Additionally, decrease the `CanRelease` threshold to `PageSize / 32`. I still have to make that configurable but I will do it at another time. Finally, rename some variables in `printStats`: I feel like "available" was too ambiguous, so change it to "total". Reviewers: morehouse, hctim, eugenis, vitalybuka, cferris Reviewed By: morehouse Subscribers: delcypher, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D68471 llvm-svn: 373930
* [scudo][standalone] Fix malloc_iterateKostya Kortchinsky2019-08-201-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: cferris's Bionic tests found an issue in Scudo's `malloc_iterate`. We were inclusive of both boundaries, which resulted in a `Block` that was located on said boundary to be possibly accounted for twice, or just being accounted for while iterating on regions that are not ours (usually the unmapped ones in between Primary regions). The fix is to exclude the upper boundary in `iterateOverChunks`, and add a regression test. This additionally corrects a typo in a comment, and change the 64-bit Primary iteration function to not assume that `BatchClassId` is 0. Reviewers: cferris, morehouse, hctim, vitalybuka, eugenis Reviewed By: hctim Subscribers: delcypher, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D66231 llvm-svn: 369400
* [scudo][standalone] Add more stats to mallinfoKostya Kortchinsky2019-08-141-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Android requires additional stats in mallinfo. While we can provide right away the number of bytes mapped (Primary+Secondary), there was no way to get the number of free bytes (only makes sense for the Primary since the Secondary unmaps everything on deallocation). An approximation could be `StatMapped - StatAllocated`, but since we are mapping in `1<<17` increments for the 64-bit Primary, it's fairly inaccurate. So we introduce `StatFree` (note it's `Free`, not `Freed`!), which keeps track of the amount of Primary blocks currently unallocated. Reviewers: cferris, eugenis, vitalybuka, hctim, morehouse Reviewed By: morehouse Subscribers: delcypher, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D66112 llvm-svn: 368866
* [scudo][standalone] Optimization passKostya Kortchinsky2019-07-241-8/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This introduces a bunch of small optimizations with the purpose of making the fastpath tighter: - tag more conditions as `LIKELY`/`UNLIKELY`: as a rule of thumb we consider that every operation related to the secondary is unlikely - attempt to reduce the number of potentially extraneous instructions - reorganize the `Chunk` header to not straddle a word boundary and use more appropriate types Note that some `LIKELY`/`UNLIKELY` impact might be less obvious as they are in slow paths (for example in `secondary.cc`), but at this point I am throwing a pretty wide net, and it's consistant and doesn't hurt. This was mosly done for the benfit of Android, but other platforms benefit from it too. An aarch64 Android benchmark gives: - before: ``` BM_youtube/min_time:15.000/repeats:4/manual_time_mean 445244 us 659385 us 4 BM_youtube/min_time:15.000/repeats:4/manual_time_median 445007 us 658970 us 4 BM_youtube/min_time:15.000/repeats:4/manual_time_stddev 885 us 1332 us 4 ``` - after: ``` BM_youtube/min_time:15.000/repeats:4/manual_time_mean 415697 us 621925 us 4 BM_youtube/min_time:15.000/repeats:4/manual_time_median 415913 us 622061 us 4 BM_youtube/min_time:15.000/repeats:4/manual_time_stddev 990 us 1163 us 4 ``` Additional since `-Werror=conversion` is enabled on some platforms we are built on, enable it upstream to catch things early: a few sign conversions had slept through and needed additional casting. Reviewers: hctim, morehouse, eugenis, vitalybuka Reviewed By: vitalybuka Subscribers: srhines, mgorny, javed.absar, kristof.beyls, delcypher, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D64664 llvm-svn: 366918
* [scudo][standalone] NFC correctionsKostya Kortchinsky2019-07-111-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: A few corrections: - rename `TransferBatch::MaxCached` to `getMaxCached` to conform with the style guide; - move `getBlockBegin` from `Chunk::` to `Allocator::`: I believe it was a fallacy to have this be a `Chunk` method, as chunks' relationship to backend blocks are up to the frontend allocator. It makes more sense now, particularly with regard to the offset. Update the associated chunk test as the method isn't available there anymore; - add a forgotten `\n` to a log string; - for `releaseToOs`, instead of starting at `1`, start at `0` and `continue` on `BatchClassId`: in the end it's identical but doesn't assume a particular class id for batches; - change a `CHECK` to a `reportOutOfMemory`: it's a clearer message Reviewers: hctim, morehouse, eugenis, vitalybuka Reviewed By: hctim Subscribers: delcypher, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D64570 llvm-svn: 365816
* [scudo][standalone] Merge Spin & Blocking mutex into a Hybrid oneKostya Kortchinsky2019-07-111-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: We ran into a problem on Fuchsia where yielding threads would never be deboosted, ultimately resulting in several threads spinning on the same TSD, and no possibility for another thread to be scheduled, dead-locking the process. While this was fixed in Zircon, this lead to discussions about if spinning without a break condition was a good decision, and settled on a new hybrid model that would spin for a while then block. Currently we are using a number of iterations for spinning that is mostly arbitrary (based on sanitizer_common values), but this can be tuned in the future. Since we are touching `common.h`, we also use this change as a vehicle for an Android optimization (the page size is fixed in Bionic, so use a fixed value too). Reviewers: morehouse, hctim, eugenis, dvyukov, vitalybuka Reviewed By: hctim Subscribers: srhines, delcypher, jfb, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D64358 llvm-svn: 365790
* [scudo][standalone] Unmap memory in testsKostya Kortchinsky2019-06-111-0/+6
| | | | | | | | | | | | | | | | | | | | | Summary: The more tests are added, the more we are limited by the size of the address space on 32-bit. Implement `unmapTestOnly` all around (like it is in sanitzer_common) to be able to free up some memory. This is not intended to be a proper "destructor" for an allocator, but allows us to not fail due to having no memory left. Reviewers: morehouse, vitalybuka, eugenis, hctim Reviewed By: morehouse Subscribers: delcypher, jfb, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D63146 llvm-svn: 363095
* [scudo][standalone] Introduce the Primary(s) and LocalCacheKostya Kortchinsky2019-05-201-0/+373
Summary: This CL introduces the 32 & 64-bit primary allocators, and associated Local Cache. While the general idea is mostly similar to what exists in sanitizer_common, it departs from the original code somewhat significantly: - the 64-bit primary no longer uses a free array at the end of a region but uses batches of free blocks in region 0, allowing for a convergence with the 32-bit primary behavior; - as a result, there is only one (templated) local cache type for both primary allocators, and memory reclaiming can be implemented similarly for the 32-bit & 64-bit platforms; - 64-bit primary regions are handled a bit differently: we do not reserve 4TB of memory that we split, but reserve `NumClasses * 2^RegionSizeLog`, each region being offseted by a random number of pages from its computed base. A side effect of this is that the 64-bit primary works on 32-bit platform (I don't think we want to encourage it but it's an interesting side effect); Reviewers: vitalybuka, eugenis, morehouse, hctim Reviewed By: morehouse Subscribers: srhines, mgorny, delcypher, jfb, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D61745 llvm-svn: 361159
OpenPOWER on IntegriCloud