Files
kotlin-fork/kotlin-native/runtime/src/custom_alloc/cpp/PageStore.hpp
T
Troels Bjerre Lund bb1acf729b [K/N] Add custom allocator prototype ^KT-55364
Enable custom allocator with -Xallocator=custom.

If the gc is cms (default):
 * a patched version of the memory manager is used that does not build a
   list of allocated objects.
 * a patched version of the cms is used that defers to the allocator for
   sweeping.

Otherwise, a warning is printed, and the allocator is used using the
standard api.

Design doc:
https://docs.google.com/document/d/15xMp-nE-DWL8OrtOc8DoXB80AHUphFICEGjj5K0aNFc

Co-authored-by: Troels Lund <troels@google.com>

Merge-request: KOTLIN-MR-546
Merged-by: Alexander Shabalin <alexander.shabalin@jetbrains.com>
2022-12-08 17:22:04 +00:00

82 lines
1.9 KiB
C++

/*
* Copyright 2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
#ifndef CUSTOM_ALLOC_CPP_PAGESTORE_HPP_
#define CUSTOM_ALLOC_CPP_PAGESTORE_HPP_
#include <atomic>
#include "AtomicStack.hpp"
namespace kotlin::alloc {
template <class T>
class PageStore {
public:
void PrepareForGC() noexcept {
unswept_.TransferAllFrom(ready_);
unswept_.TransferAllFrom(used_);
T* page;
while ((page = empty_.Pop())) page->Destroy();
}
T* SweepAndFreeEmpty(AtomicStack<T>& from, AtomicStack<T>& to) noexcept {
T* page;
while ((page = from.Pop())) {
if (!page->Sweep()) {
empty_.Push(page);
} else {
to.Push(page);
return page;
}
}
return nullptr;
}
void Sweep() noexcept {
while (SweepAndFreeEmpty(unswept_, ready_)) {}
}
T* GetPage(uint32_t cellCount) noexcept {
T* page;
if ((page = SweepAndFreeEmpty(unswept_, used_))) {
return page;
}
if ((page = ready_.Pop())) {
used_.Push(page);
return page;
}
if ((page = empty_.Pop())) {
used_.Push(page);
return page;
}
return NewPage(cellCount);
}
T* NewPage(uint64_t cellCount) noexcept {
T* page = T::Create(cellCount);
used_.Push(page);
return page;
}
~PageStore() noexcept {
T* page;
while ((page = empty_.Pop())) page->Destroy();
while ((page = ready_.Pop())) page->Destroy();
while ((page = used_.Pop())) page->Destroy();
while ((page = unswept_.Pop())) page->Destroy();
}
private:
AtomicStack<T> empty_;
AtomicStack<T> ready_;
AtomicStack<T> used_;
AtomicStack<T> unswept_;
};
} // namespace kotlin::alloc
#endif