[K/N] Remove usage of legacy allocation stuff ^KT-52130
Merge-request: KT-MR-6182 Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
committed by
Space
parent
cb35e868cc
commit
4a66cd0c69
@@ -96,7 +96,7 @@ gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep(
|
||||
mm::ObjectFactory<ConcurrentMarkAndSweep>& objectFactory, GCScheduler& gcScheduler) noexcept :
|
||||
objectFactory_(objectFactory),
|
||||
gcScheduler_(gcScheduler),
|
||||
finalizerProcessor_(make_unique<FinalizerProcessor>([this](int64_t epoch) { state_.finalized(epoch); })) {
|
||||
finalizerProcessor_(std_support::make_unique<FinalizerProcessor>([this](int64_t epoch) { state_.finalized(epoch); })) {
|
||||
gcScheduler_.SetScheduleGC([this]() NO_INLINE {
|
||||
RuntimeLogDebug({kTagGC}, "Scheduling GC by thread %d", konan::currentThreadId());
|
||||
// This call acquires a lock, so we need to ensure that we're in the safe state.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "GCState.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
|
||||
@@ -105,7 +106,7 @@ private:
|
||||
uint64_t lastGCTimestampUs_ = 0;
|
||||
GCStateHolder state_;
|
||||
ScopedThread gcThread_;
|
||||
KStdUniquePtr<FinalizerProcessor> finalizerProcessor_;
|
||||
std_support::unique_ptr<FinalizerProcessor> finalizerProcessor_;
|
||||
|
||||
MarkQueue markQueue_;
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "SingleThreadExecutor.hpp"
|
||||
#include "TestSupport.hpp"
|
||||
#include "ThreadData.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -187,8 +188,8 @@ test_support::Object<Payload>& AllocateObjectWithFinalizer(mm::ThreadData& threa
|
||||
return test_support::Object<Payload>::FromObjHeader(holder.obj());
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> Alive(mm::ThreadData& threadData) {
|
||||
KStdVector<ObjHeader*> objects;
|
||||
std_support::vector<ObjHeader*> Alive(mm::ThreadData& threadData) {
|
||||
std_support::vector<ObjHeader*> objects;
|
||||
for (auto node : threadData.gc().impl().objectFactoryThreadQueue()) {
|
||||
objects.push_back(node.GetObjHeader());
|
||||
}
|
||||
@@ -657,7 +658,7 @@ public:
|
||||
StackObjectHolder& AddStackRoot() {
|
||||
RuntimeAssert(std::this_thread::get_id() == executor_.threadId(), "AddStackRoot can only be called in the mutator thread");
|
||||
auto& context = executor_.context();
|
||||
auto holder = make_unique<StackObjectHolder>(*context.memory_->memoryState()->GetThreadData());
|
||||
auto holder = std_support::make_unique<StackObjectHolder>(*context.memory_->memoryState()->GetThreadData());
|
||||
auto& holderRef = *holder;
|
||||
context.stackRoots_.push_back(std::move(holder));
|
||||
return holderRef;
|
||||
@@ -666,7 +667,7 @@ public:
|
||||
StackObjectHolder& AddStackRoot(ObjHeader* object) {
|
||||
RuntimeAssert(std::this_thread::get_id() == executor_.threadId(), "AddStackRoot can only be called in the mutator thread");
|
||||
auto& context = executor_.context();
|
||||
auto holder = make_unique<StackObjectHolder>(object);
|
||||
auto holder = std_support::make_unique<StackObjectHolder>(object);
|
||||
auto& holderRef = *holder;
|
||||
context.stackRoots_.push_back(std::move(holder));
|
||||
return holderRef;
|
||||
@@ -675,7 +676,7 @@ public:
|
||||
GlobalObjectHolder& AddGlobalRoot() {
|
||||
RuntimeAssert(std::this_thread::get_id() == executor_.threadId(), "AddGlobalRoot can only be called in the mutator thread");
|
||||
auto& context = executor_.context();
|
||||
auto holder = make_unique<GlobalObjectHolder>(*context.memory_->memoryState()->GetThreadData());
|
||||
auto holder = std_support::make_unique<GlobalObjectHolder>(*context.memory_->memoryState()->GetThreadData());
|
||||
auto& holderRef = *holder;
|
||||
context.globalRoots_.push_back(std::move(holder));
|
||||
return holderRef;
|
||||
@@ -684,21 +685,21 @@ public:
|
||||
GlobalObjectHolder& AddGlobalRoot(ObjHeader* object) {
|
||||
RuntimeAssert(std::this_thread::get_id() == executor_.threadId(), "AddGlobalRoot can only be called in the mutator thread");
|
||||
auto& context = executor_.context();
|
||||
auto holder = make_unique<GlobalObjectHolder>(*context.memory_->memoryState()->GetThreadData(), object);
|
||||
auto holder = std_support::make_unique<GlobalObjectHolder>(*context.memory_->memoryState()->GetThreadData(), object);
|
||||
auto& holderRef = *holder;
|
||||
context.globalRoots_.push_back(std::move(holder));
|
||||
return holderRef;
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> Alive() { return ::Alive(*executor_.context().memory_->memoryState()->GetThreadData()); }
|
||||
std_support::vector<ObjHeader*> Alive() { return ::Alive(*executor_.context().memory_->memoryState()->GetThreadData()); }
|
||||
|
||||
private:
|
||||
struct Context {
|
||||
KStdUniquePtr<ScopedMemoryInit> memory_;
|
||||
KStdVector<KStdUniquePtr<StackObjectHolder>> stackRoots_;
|
||||
KStdVector<KStdUniquePtr<GlobalObjectHolder>> globalRoots_;
|
||||
std_support::unique_ptr<ScopedMemoryInit> memory_;
|
||||
std_support::vector<std_support::unique_ptr<StackObjectHolder>> stackRoots_;
|
||||
std_support::vector<std_support::unique_ptr<GlobalObjectHolder>> globalRoots_;
|
||||
|
||||
Context() : memory_(make_unique<ScopedMemoryInit>()) {
|
||||
Context() : memory_(std_support::make_unique<ScopedMemoryInit>()) {
|
||||
// SingleThreadExecutor must work in the runnable state, so that GC does not collect between tasks.
|
||||
AssertThreadState(memory_->memoryState(), ThreadState::kRunnable);
|
||||
}
|
||||
@@ -710,10 +711,10 @@ private:
|
||||
} // namespace
|
||||
|
||||
TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsCollect) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
|
||||
auto expandRootSet = [&globals, &locals, &reachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = mutator.AddGlobalRoot();
|
||||
@@ -732,7 +733,7 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsCollect) {
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
gcFutures[0] = mutators[0].Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().ScheduleAndWaitFullGC(); });
|
||||
|
||||
@@ -749,7 +750,7 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsCollect) {
|
||||
future.wait();
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (auto& global : globals) {
|
||||
expectedAlive.push_back(global);
|
||||
}
|
||||
@@ -766,10 +767,10 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsCollect) {
|
||||
}
|
||||
|
||||
TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAllCollect) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
|
||||
auto expandRootSet = [&globals, &locals, &reachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = mutator.AddGlobalRoot();
|
||||
@@ -788,7 +789,7 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAllCollect) {
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
for (int i = 0; i < kDefaultThreadCount; ++i) {
|
||||
gcFutures[i] = mutators[i].Execute([](mm::ThreadData& threadData, Mutator& mutator) {
|
||||
@@ -811,7 +812,7 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAllCollect) {
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (auto& global : globals) {
|
||||
expectedAlive.push_back(global);
|
||||
}
|
||||
@@ -828,10 +829,10 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAllCollect) {
|
||||
}
|
||||
|
||||
TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRequested) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
|
||||
auto allocateInHeap = [&globals, &locals, &reachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = AllocateObject(threadData);
|
||||
@@ -865,7 +866,7 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRe
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
gcFutures[0] = mutators[0].Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().ScheduleAndWaitFullGC(); });
|
||||
|
||||
// Spin until thread suspension is requested.
|
||||
@@ -883,7 +884,7 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRe
|
||||
future.wait();
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (auto& global : globals) {
|
||||
expectedAlive.push_back(global);
|
||||
}
|
||||
@@ -900,10 +901,10 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRe
|
||||
}
|
||||
|
||||
TEST_F(ConcurrentMarkAndSweepTest, CrossThreadReference) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(2 * kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(2 * kDefaultThreadCount);
|
||||
|
||||
auto expandRootSet = [&globals, &locals, &reachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = mutator.AddGlobalRoot();
|
||||
@@ -929,7 +930,7 @@ TEST_F(ConcurrentMarkAndSweepTest, CrossThreadReference) {
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
gcFutures[0] = mutators[0].Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().ScheduleAndWaitFullGC(); });
|
||||
|
||||
@@ -946,7 +947,7 @@ TEST_F(ConcurrentMarkAndSweepTest, CrossThreadReference) {
|
||||
future.wait();
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (auto& global : globals) {
|
||||
expectedAlive.push_back(global);
|
||||
}
|
||||
@@ -966,7 +967,7 @@ TEST_F(ConcurrentMarkAndSweepTest, CrossThreadReference) {
|
||||
}
|
||||
|
||||
TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsWeaks) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
ObjHeader* globalRoot = nullptr;
|
||||
WeakCounter* weak = nullptr;
|
||||
|
||||
@@ -990,7 +991,7 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsWeaks) {
|
||||
mutators[i].Execute([](mm::ThreadData& threadData, Mutator& mutator) {}).wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
gcFutures[0] = mutators[0].Execute([weak](mm::ThreadData& threadData, Mutator& mutator) {
|
||||
threadData.gc().ScheduleAndWaitFullGC();
|
||||
@@ -1018,11 +1019,11 @@ TEST_F(ConcurrentMarkAndSweepTest, MultipleMutatorsWeaks) {
|
||||
}
|
||||
|
||||
TEST_F(ConcurrentMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(2 * kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(2 * kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(2 * kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> unreachables(2 * kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(2 * kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(2 * kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(2 * kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> unreachables(2 * kDefaultThreadCount);
|
||||
|
||||
auto expandRootSet = [&globals, &locals, &reachables, &unreachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = mutator.AddGlobalRoot();
|
||||
@@ -1042,7 +1043,7 @@ TEST_F(ConcurrentMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
gcFutures[0] = mutators[0].Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().ScheduleAndWaitFullGC(); });
|
||||
|
||||
@@ -1051,8 +1052,8 @@ TEST_F(ConcurrentMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
}
|
||||
|
||||
// Now start attaching new threads.
|
||||
KStdVector<Mutator> newMutators(kDefaultThreadCount);
|
||||
KStdVector<std::future<void>> attachFutures(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> newMutators(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> attachFutures(kDefaultThreadCount);
|
||||
|
||||
for (int i = 0; i < kDefaultThreadCount; ++i) {
|
||||
attachFutures[i] = newMutators[i].Execute([i, expandRootSet](mm::ThreadData& threadData, Mutator& mutator) { expandRootSet(threadData, mutator, i + kDefaultThreadCount); });
|
||||
@@ -1076,7 +1077,7 @@ TEST_F(ConcurrentMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
|
||||
// Old mutators don't even see alive objects from the new threads yet (as the latter ones have not published anything).
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (int i = 0; i < kDefaultThreadCount; ++i) {
|
||||
expectedAlive.push_back(globals[i]);
|
||||
expectedAlive.push_back(locals[i]);
|
||||
@@ -1088,7 +1089,7 @@ TEST_F(ConcurrentMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
}
|
||||
|
||||
for (int i = 0; i < kDefaultThreadCount; ++i) {
|
||||
KStdVector<ObjHeader*> aliveForThisThread(expectedAlive.begin(), expectedAlive.end());
|
||||
std_support::vector<ObjHeader*> aliveForThisThread(expectedAlive.begin(), expectedAlive.end());
|
||||
aliveForThisThread.push_back(globals[kDefaultThreadCount + i]);
|
||||
aliveForThisThread.push_back(locals[kDefaultThreadCount + i]);
|
||||
aliveForThisThread.push_back(reachables[kDefaultThreadCount + i]);
|
||||
@@ -1100,7 +1101,7 @@ TEST_F(ConcurrentMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
|
||||
|
||||
TEST_F(ConcurrentMarkAndSweepTest, FreeObjectWithFreeWeakReversedOrder) {
|
||||
KStdVector<Mutator> mutators(2);
|
||||
std_support::vector<Mutator> mutators(2);
|
||||
std::atomic<test_support::Object<Payload>*> object1 = nullptr;
|
||||
std::atomic<WeakCounter*> weak = nullptr;
|
||||
std::atomic<bool> done = false;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "GC.hpp"
|
||||
#include "ThreadSuspension.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -19,7 +20,7 @@ ALWAYS_INLINE void SafePointRegular(gc::GC::ThreadData& threadData, size_t weigh
|
||||
|
||||
} // namespace
|
||||
|
||||
gc::GC::ThreadData::ThreadData(GC& gc, mm::ThreadData& threadData) noexcept : impl_(make_unique<Impl>(gc, threadData)) {}
|
||||
gc::GC::ThreadData::ThreadData(GC& gc, mm::ThreadData& threadData) noexcept : impl_(std_support::make_unique<Impl>(gc, threadData)) {}
|
||||
|
||||
gc::GC::ThreadData::~ThreadData() = default;
|
||||
|
||||
@@ -59,7 +60,7 @@ void gc::GC::ThreadData::OnStoppedForGC() noexcept {
|
||||
impl_->gcScheduler().OnStoppedForGC();
|
||||
}
|
||||
|
||||
gc::GC::GC() noexcept : impl_(make_unique<Impl>()) {}
|
||||
gc::GC::GC() noexcept : impl_(std_support::make_unique<Impl>()) {}
|
||||
|
||||
gc::GC::~GC() = default;
|
||||
|
||||
|
||||
@@ -5,15 +5,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Alloc.h"
|
||||
#include <utility>
|
||||
|
||||
#include "std_support/CStdlib.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
namespace gc {
|
||||
|
||||
class AlignedAllocator {
|
||||
public:
|
||||
void* Alloc(size_t size, size_t alignment) noexcept { return konanAllocAlignedMemory(size, alignment); }
|
||||
static void Free(void* instance) noexcept { konanFreeMemory(instance); }
|
||||
void* Alloc(size_t size, size_t alignment) noexcept { return std_support::aligned_calloc(alignment, 1, size); }
|
||||
static void Free(void* instance) noexcept { std_support::free(instance); }
|
||||
};
|
||||
|
||||
template <typename BaseAllocator, typename GCThreadData>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "Types.h"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
void* Alloc(size_t size, size_t alignment) { return mock_->Alloc(size, alignment); }
|
||||
|
||||
private:
|
||||
KStdUniquePtr<testing::StrictMock<MockAllocator>> mock_ = make_unique<testing::StrictMock<MockAllocator>>();
|
||||
std_support::unique_ptr<testing::StrictMock<MockAllocator>> mock_ = std_support::make_unique<testing::StrictMock<MockAllocator>>();
|
||||
};
|
||||
|
||||
class MockGC {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Memory.h"
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
|
||||
@@ -46,7 +47,7 @@ public:
|
||||
void OnStoppedForGC() noexcept;
|
||||
|
||||
private:
|
||||
KStdUniquePtr<Impl> impl_;
|
||||
std_support::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
GC() noexcept;
|
||||
@@ -65,7 +66,7 @@ public:
|
||||
bool FinalizersThreadIsRunning() noexcept;
|
||||
|
||||
private:
|
||||
KStdUniquePtr<Impl> impl_;
|
||||
std_support::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
inline constexpr bool kSupportsMultipleMutators = true;
|
||||
|
||||
@@ -19,25 +19,25 @@ using namespace kotlin;
|
||||
|
||||
namespace {
|
||||
|
||||
KStdUniquePtr<gc::GCSchedulerData> MakeGCSchedulerData(
|
||||
std_support::unique_ptr<gc::GCSchedulerData> MakeGCSchedulerData(
|
||||
gc::SchedulerType type, gc::GCSchedulerConfig& config, std::function<void()> scheduleGC) noexcept {
|
||||
switch (type) {
|
||||
case gc::SchedulerType::kDisabled:
|
||||
RuntimeLogDebug({kTagGC}, "GC scheduler disabled");
|
||||
return ::make_unique<gc::internal::GCEmptySchedulerData>();
|
||||
return std_support::make_unique<gc::internal::GCEmptySchedulerData>();
|
||||
case gc::SchedulerType::kWithTimer:
|
||||
#ifndef KONAN_NO_THREADS
|
||||
RuntimeLogDebug({kTagGC}, "Initializing timer-based GC scheduler");
|
||||
return ::make_unique<gc::internal::GCSchedulerDataWithTimer<steady_clock>>(config, std::move(scheduleGC));
|
||||
return std_support::make_unique<gc::internal::GCSchedulerDataWithTimer<steady_clock>>(config, std::move(scheduleGC));
|
||||
#else
|
||||
RuntimeFail("GC scheduler with timer is not supported on this platform");
|
||||
#endif
|
||||
case gc::SchedulerType::kOnSafepoints:
|
||||
RuntimeLogDebug({kTagGC}, "Initializing safe-point-based GC scheduler");
|
||||
return ::make_unique<gc::internal::GCSchedulerDataOnSafepoints<steady_clock>>(config, std::move(scheduleGC));
|
||||
return std_support::make_unique<gc::internal::GCSchedulerDataOnSafepoints<steady_clock>>(config, std::move(scheduleGC));
|
||||
case gc::SchedulerType::kAggressive:
|
||||
RuntimeLogDebug({kTagGC}, "Initializing aggressive GC scheduler");
|
||||
return ::make_unique<gc::internal::GCSchedulerDataAggressive>(config, std::move(scheduleGC));
|
||||
return std_support::make_unique<gc::internal::GCSchedulerDataAggressive>(config, std::move(scheduleGC));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "Logging.hpp"
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
namespace gc {
|
||||
@@ -159,7 +160,7 @@ public:
|
||||
|
||||
private:
|
||||
GCSchedulerConfig config_;
|
||||
KStdUniquePtr<GCSchedulerData> gcData_;
|
||||
std_support::unique_ptr<GCSchedulerData> gcData_;
|
||||
std::function<void()> scheduleGC_;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "GCSchedulerImpl.hpp"
|
||||
#include "SingleThreadExecutor.hpp"
|
||||
#include "TestSupport.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -315,7 +316,7 @@ public:
|
||||
explicit GCSchedulerDataTestApi(GCSchedulerConfig& config) : scheduler_(config, scheduleGC_.AsStdFunction()) {
|
||||
mutators_.reserve(MutatorCount);
|
||||
for (int i = 0; i < MutatorCount; ++i) {
|
||||
mutators_.emplace_back(make_unique<MutatorThread>(
|
||||
mutators_.emplace_back(std_support::make_unique<MutatorThread>(
|
||||
config, [this](GCSchedulerThreadData& threadData) { scheduler_.UpdateFromThreadData(threadData); }));
|
||||
}
|
||||
}
|
||||
@@ -334,7 +335,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
KStdVector<KStdUniquePtr<MutatorThread>> mutators_;
|
||||
std_support::vector<std_support::unique_ptr<MutatorThread>> mutators_;
|
||||
testing::MockFunction<void()> scheduleGC_;
|
||||
GCScheduler scheduler_;
|
||||
};
|
||||
@@ -367,7 +368,7 @@ TEST_F(GCSchedulerDataOnSafePointsTest, CollectOnTargetHeapReached) {
|
||||
GCSchedulerDataOnSafepointsTestApi<mutatorsCount> schedulerTestApi(config);
|
||||
|
||||
EXPECT_CALL(schedulerTestApi.scheduleGC(), Call()).Times(0);
|
||||
KStdVector<std::future<void>> futures;
|
||||
std_support::vector<std::future<void>> futures;
|
||||
for (int i = 0; i < mutatorsCount; ++i) {
|
||||
futures.push_back(schedulerTestApi.Allocate(i, 10));
|
||||
}
|
||||
@@ -405,7 +406,7 @@ TEST_F(GCSchedulerDataOnSafePointsTest, CollectOnTimeoutReached) {
|
||||
|
||||
EXPECT_CALL(schedulerTestApi.scheduleGC(), Call()).Times(0);
|
||||
schedulerTestApi.advance_time(microseconds(5));
|
||||
KStdVector<std::future<void>> futures;
|
||||
std_support::vector<std::future<void>> futures;
|
||||
for (int i = 0; i < mutatorsCount; ++i) {
|
||||
futures.push_back(schedulerTestApi.Allocate(i, 0));
|
||||
}
|
||||
@@ -550,7 +551,7 @@ TEST_F(GCSchedulerDataWithTimerTest, CollectOnTargetHeapReached) {
|
||||
GCSchedulerDataWithTimerTestApi<mutatorsCount> schedulerTestApi(config);
|
||||
|
||||
EXPECT_CALL(schedulerTestApi.scheduleGC(), Call()).Times(0);
|
||||
KStdVector<std::future<void>> futures;
|
||||
std_support::vector<std::future<void>> futures;
|
||||
for (int i = 0; i < mutatorsCount; ++i) {
|
||||
futures.push_back(schedulerTestApi.Allocate(i, 10));
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "FinalizerHooks.hpp"
|
||||
#include "ObjectTestSupport.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/UnorderedSet.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -108,7 +110,7 @@ public:
|
||||
|
||||
class ScopedMarkTraits : private Pinned {
|
||||
public:
|
||||
using MarkQueue = KStdVector<ObjHeader*>;
|
||||
using MarkQueue = std_support::vector<ObjHeader*>;
|
||||
|
||||
ScopedMarkTraits() {
|
||||
RuntimeAssert(instance_ == nullptr, "Only one ScopedMarkTraits is allowed");
|
||||
@@ -120,7 +122,7 @@ public:
|
||||
instance_ = nullptr;
|
||||
}
|
||||
|
||||
const KStdUnorderedSet<ObjHeader*>& marked() const { return marked_; }
|
||||
const std_support::unordered_set<ObjHeader*>& marked() const { return marked_; }
|
||||
|
||||
static bool isEmpty(const MarkQueue& queue) noexcept {
|
||||
return queue.empty();
|
||||
@@ -146,7 +148,7 @@ public:
|
||||
private:
|
||||
static ScopedMarkTraits* instance_;
|
||||
|
||||
KStdUnorderedSet<ObjHeader*> marked_;
|
||||
std_support::unordered_set<ObjHeader*> marked_;
|
||||
};
|
||||
|
||||
// static
|
||||
@@ -154,10 +156,10 @@ ScopedMarkTraits* ScopedMarkTraits::instance_ = nullptr;
|
||||
|
||||
class MarkAndSweepUtilsMarkTest : public ::testing::Test {
|
||||
public:
|
||||
const KStdUnorderedSet<ObjHeader*>& marked() const { return markTraits_.marked(); }
|
||||
const std_support::unordered_set<ObjHeader*>& marked() const { return markTraits_.marked(); }
|
||||
|
||||
auto MarkedMatcher(std::initializer_list<std::reference_wrapper<BaseObject>> expected) {
|
||||
KStdVector<ObjHeader*> objects;
|
||||
std_support::vector<ObjHeader*> objects;
|
||||
for (auto& object : expected) {
|
||||
objects.push_back(object.get().GetObjHeader());
|
||||
}
|
||||
@@ -165,7 +167,7 @@ public:
|
||||
}
|
||||
|
||||
gc::MarkStats Mark(std::initializer_list<std::reference_wrapper<BaseObject>> graySet) {
|
||||
KStdVector<ObjHeader*> objects;
|
||||
std_support::vector<ObjHeader*> objects;
|
||||
for (auto& object : graySet) ScopedMarkTraits::enqueue(objects, object.get().GetObjHeader());
|
||||
return gc::Mark<ScopedMarkTraits>(objects);
|
||||
}
|
||||
|
||||
@@ -198,10 +198,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> Sweep() {
|
||||
std_support::vector<ObjHeader*> Sweep() {
|
||||
gc::SweepExtraObjects<SweepTraits>(extraObjectFactory_);
|
||||
auto finalizers = gc::Sweep<SweepTraits>(objectFactory_);
|
||||
KStdVector<ObjHeader*> objects;
|
||||
std_support::vector<ObjHeader*> objects;
|
||||
for (auto node : finalizers.IterForTests()) {
|
||||
objects.push_back(node.GetObjHeader());
|
||||
}
|
||||
@@ -209,16 +209,16 @@ public:
|
||||
return objects;
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> Alive() {
|
||||
KStdVector<ObjHeader*> objects;
|
||||
std_support::vector<ObjHeader*> Alive() {
|
||||
std_support::vector<ObjHeader*> objects;
|
||||
for (auto node : objectFactory_.LockForIter()) {
|
||||
objects.push_back(node.GetObjHeader());
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
KStdVector<mm::ExtraObjectData*> AliveExtraObjects() {
|
||||
KStdVector<mm::ExtraObjectData*> objects;
|
||||
std_support::vector<mm::ExtraObjectData*> AliveExtraObjects() {
|
||||
std_support::vector<mm::ExtraObjectData*> objects;
|
||||
for (auto &node : extraObjectFactory_.LockForIter()) {
|
||||
objects.push_back(&node);
|
||||
}
|
||||
@@ -271,7 +271,7 @@ private:
|
||||
ObjectFactory::ThreadQueue objectFactoryThreadQueue_{objectFactory_, gc::AlignedAllocator()};
|
||||
ExtraObjectsDataFactory extraObjectFactory_;
|
||||
ExtraObjectsDataFactory::ThreadQueue extraObjectFactoryThreadQueue_{extraObjectFactory_};
|
||||
KStdVector<ObjectFactory::FinalizerQueue> finalizers_;
|
||||
std_support::vector<ObjectFactory::FinalizerQueue> finalizers_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
#include "GCImpl.hpp"
|
||||
|
||||
#include "GC.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
gc::GC::ThreadData::ThreadData(GC& gc, mm::ThreadData& threadData) noexcept : impl_(make_unique<Impl>(gc, threadData)) {}
|
||||
gc::GC::ThreadData::ThreadData(GC& gc, mm::ThreadData& threadData) noexcept : impl_(std_support::make_unique<Impl>(gc, threadData)) {}
|
||||
|
||||
gc::GC::ThreadData::~ThreadData() = default;
|
||||
|
||||
@@ -49,7 +50,7 @@ void gc::GC::ThreadData::OnStoppedForGC() noexcept {
|
||||
impl_->gcScheduler().OnStoppedForGC();
|
||||
}
|
||||
|
||||
gc::GC::GC() noexcept : impl_(make_unique<Impl>()) {}
|
||||
gc::GC::GC() noexcept : impl_(std_support::make_unique<Impl>()) {}
|
||||
|
||||
gc::GC::~GC() = default;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "GCImpl.hpp"
|
||||
|
||||
#include "GC.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -21,7 +22,7 @@ ALWAYS_INLINE void SafePointRegular(gc::GC::ThreadData& threadData, size_t weigh
|
||||
|
||||
} // namespace
|
||||
|
||||
gc::GC::ThreadData::ThreadData(GC& gc, mm::ThreadData& threadData) noexcept : impl_(make_unique<Impl>(gc, threadData)) {}
|
||||
gc::GC::ThreadData::ThreadData(GC& gc, mm::ThreadData& threadData) noexcept : impl_(std_support::make_unique<Impl>(gc, threadData)) {}
|
||||
|
||||
gc::GC::ThreadData::~ThreadData() = default;
|
||||
|
||||
@@ -61,7 +62,7 @@ void gc::GC::ThreadData::OnStoppedForGC() noexcept {
|
||||
impl_->gcScheduler().OnStoppedForGC();
|
||||
}
|
||||
|
||||
gc::GC::GC() noexcept : impl_(make_unique<Impl>()) {}
|
||||
gc::GC::GC() noexcept : impl_(std_support::make_unique<Impl>()) {}
|
||||
|
||||
gc::GC::~GC() = default;
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "SingleThreadExecutor.hpp"
|
||||
#include "TestSupport.hpp"
|
||||
#include "ThreadData.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -187,8 +189,8 @@ test_support::Object<Payload>& AllocateObjectWithFinalizer(mm::ThreadData& threa
|
||||
return test_support::Object<Payload>::FromObjHeader(holder.obj());
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> Alive(mm::ThreadData& threadData) {
|
||||
KStdVector<ObjHeader*> objects;
|
||||
std_support::vector<ObjHeader*> Alive(mm::ThreadData& threadData) {
|
||||
std_support::vector<ObjHeader*> objects;
|
||||
for (auto node : threadData.gc().impl().objectFactoryThreadQueue()) {
|
||||
objects.push_back(node.GetObjHeader());
|
||||
}
|
||||
@@ -656,7 +658,7 @@ public:
|
||||
StackObjectHolder& AddStackRoot() {
|
||||
RuntimeAssert(std::this_thread::get_id() == executor_.threadId(), "AddStackRoot can only be called in the mutator thread");
|
||||
auto& context = executor_.context();
|
||||
auto holder = make_unique<StackObjectHolder>(*context.memory_->memoryState()->GetThreadData());
|
||||
auto holder = std_support::make_unique<StackObjectHolder>(*context.memory_->memoryState()->GetThreadData());
|
||||
auto& holderRef = *holder;
|
||||
context.stackRoots_.push_back(std::move(holder));
|
||||
return holderRef;
|
||||
@@ -665,7 +667,7 @@ public:
|
||||
StackObjectHolder& AddStackRoot(ObjHeader* object) {
|
||||
RuntimeAssert(std::this_thread::get_id() == executor_.threadId(), "AddStackRoot can only be called in the mutator thread");
|
||||
auto& context = executor_.context();
|
||||
auto holder = make_unique<StackObjectHolder>(object);
|
||||
auto holder = std_support::make_unique<StackObjectHolder>(object);
|
||||
auto& holderRef = *holder;
|
||||
context.stackRoots_.push_back(std::move(holder));
|
||||
return holderRef;
|
||||
@@ -674,7 +676,7 @@ public:
|
||||
GlobalObjectHolder& AddGlobalRoot() {
|
||||
RuntimeAssert(std::this_thread::get_id() == executor_.threadId(), "AddGlobalRoot can only be called in the mutator thread");
|
||||
auto& context = executor_.context();
|
||||
auto holder = make_unique<GlobalObjectHolder>(*context.memory_->memoryState()->GetThreadData());
|
||||
auto holder = std_support::make_unique<GlobalObjectHolder>(*context.memory_->memoryState()->GetThreadData());
|
||||
auto& holderRef = *holder;
|
||||
context.globalRoots_.push_back(std::move(holder));
|
||||
return holderRef;
|
||||
@@ -683,21 +685,21 @@ public:
|
||||
GlobalObjectHolder& AddGlobalRoot(ObjHeader* object) {
|
||||
RuntimeAssert(std::this_thread::get_id() == executor_.threadId(), "AddGlobalRoot can only be called in the mutator thread");
|
||||
auto& context = executor_.context();
|
||||
auto holder = make_unique<GlobalObjectHolder>(*context.memory_->memoryState()->GetThreadData(), object);
|
||||
auto holder = std_support::make_unique<GlobalObjectHolder>(*context.memory_->memoryState()->GetThreadData(), object);
|
||||
auto& holderRef = *holder;
|
||||
context.globalRoots_.push_back(std::move(holder));
|
||||
return holderRef;
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> Alive() { return ::Alive(*executor_.context().memory_->memoryState()->GetThreadData()); }
|
||||
std_support::vector<ObjHeader*> Alive() { return ::Alive(*executor_.context().memory_->memoryState()->GetThreadData()); }
|
||||
|
||||
private:
|
||||
struct Context {
|
||||
KStdUniquePtr<ScopedMemoryInit> memory_;
|
||||
KStdVector<KStdUniquePtr<StackObjectHolder>> stackRoots_;
|
||||
KStdVector<KStdUniquePtr<GlobalObjectHolder>> globalRoots_;
|
||||
std_support::unique_ptr<ScopedMemoryInit> memory_;
|
||||
std_support::vector<std_support::unique_ptr<StackObjectHolder>> stackRoots_;
|
||||
std_support::vector<std_support::unique_ptr<GlobalObjectHolder>> globalRoots_;
|
||||
|
||||
Context() : memory_(make_unique<ScopedMemoryInit>()) {
|
||||
Context() : memory_(std_support::make_unique<ScopedMemoryInit>()) {
|
||||
// SingleThreadExecutor must work in the runnable state, so that GC does not collect between tasks.
|
||||
AssertThreadState(memory_->memoryState(), ThreadState::kRunnable);
|
||||
}
|
||||
@@ -709,10 +711,10 @@ private:
|
||||
} // namespace
|
||||
|
||||
TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsCollect) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
|
||||
auto expandRootSet = [&globals, &locals, &reachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = mutator.AddGlobalRoot();
|
||||
@@ -731,7 +733,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsCollect) {
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
gcFutures[0] = mutators[0].Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().ScheduleAndWaitFullGC(); });
|
||||
|
||||
@@ -748,7 +750,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsCollect) {
|
||||
future.wait();
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (auto& global : globals) {
|
||||
expectedAlive.push_back(global);
|
||||
}
|
||||
@@ -765,10 +767,10 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsCollect) {
|
||||
}
|
||||
|
||||
TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAllCollect) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
|
||||
auto expandRootSet = [&globals, &locals, &reachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = mutator.AddGlobalRoot();
|
||||
@@ -787,7 +789,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAllCollect) {
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
// TODO: Maybe check that only one GC is performed.
|
||||
for (int i = 0; i < kDefaultThreadCount; ++i) {
|
||||
@@ -798,7 +800,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAllCollect) {
|
||||
future.wait();
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (auto& global : globals) {
|
||||
expectedAlive.push_back(global);
|
||||
}
|
||||
@@ -815,10 +817,10 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAllCollect) {
|
||||
}
|
||||
|
||||
TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRequested) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(kDefaultThreadCount);
|
||||
|
||||
auto allocateInHeap = [&globals, &locals, &reachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = AllocateObject(threadData);
|
||||
@@ -852,7 +854,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRe
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
gcFutures[0] = mutators[0].Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().ScheduleAndWaitFullGC(); });
|
||||
|
||||
// Spin until thread suspension is requested.
|
||||
@@ -870,7 +872,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRe
|
||||
future.wait();
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (auto& global : globals) {
|
||||
expectedAlive.push_back(global);
|
||||
}
|
||||
@@ -887,10 +889,10 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsAddToRootSetAfterCollectionRe
|
||||
}
|
||||
|
||||
TEST_F(SameThreadMarkAndSweepTest, CrossThreadReference) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(2 * kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(2 * kDefaultThreadCount);
|
||||
|
||||
auto expandRootSet = [&globals, &locals, &reachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = mutator.AddGlobalRoot();
|
||||
@@ -916,7 +918,7 @@ TEST_F(SameThreadMarkAndSweepTest, CrossThreadReference) {
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
gcFutures[0] = mutators[0].Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().ScheduleAndWaitFullGC(); });
|
||||
|
||||
@@ -933,7 +935,7 @@ TEST_F(SameThreadMarkAndSweepTest, CrossThreadReference) {
|
||||
future.wait();
|
||||
}
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (auto& global : globals) {
|
||||
expectedAlive.push_back(global);
|
||||
}
|
||||
@@ -953,7 +955,7 @@ TEST_F(SameThreadMarkAndSweepTest, CrossThreadReference) {
|
||||
}
|
||||
|
||||
TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsWeaks) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
ObjHeader* globalRoot = nullptr;
|
||||
WeakCounter* weak = nullptr;
|
||||
|
||||
@@ -977,7 +979,7 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsWeaks) {
|
||||
mutators[i].Execute([](mm::ThreadData& threadData, Mutator& mutator) {}).wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
gcFutures[0] = mutators[0].Execute([weak](mm::ThreadData& threadData, Mutator& mutator) {
|
||||
threadData.gc().ScheduleAndWaitFullGC();
|
||||
@@ -1005,11 +1007,11 @@ TEST_F(SameThreadMarkAndSweepTest, MultipleMutatorsWeaks) {
|
||||
}
|
||||
|
||||
TEST_F(SameThreadMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
KStdVector<Mutator> mutators(kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> globals(2 * kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> locals(2 * kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> reachables(2 * kDefaultThreadCount);
|
||||
KStdVector<ObjHeader*> unreachables(2 * kDefaultThreadCount);
|
||||
std_support::vector<Mutator> mutators(kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> globals(2 * kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> locals(2 * kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> reachables(2 * kDefaultThreadCount);
|
||||
std_support::vector<ObjHeader*> unreachables(2 * kDefaultThreadCount);
|
||||
|
||||
auto expandRootSet = [&globals, &locals, &reachables, &unreachables](mm::ThreadData& threadData, Mutator& mutator, int i) {
|
||||
auto& global = mutator.AddGlobalRoot();
|
||||
@@ -1029,7 +1031,7 @@ TEST_F(SameThreadMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
.wait();
|
||||
}
|
||||
|
||||
KStdVector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> gcFutures(kDefaultThreadCount);
|
||||
|
||||
gcFutures[0] = mutators[0].Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().ScheduleAndWaitFullGC(); });
|
||||
|
||||
@@ -1038,8 +1040,8 @@ TEST_F(SameThreadMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
}
|
||||
|
||||
// Now start attaching new threads.
|
||||
KStdVector<Mutator> newMutators(kDefaultThreadCount);
|
||||
KStdVector<std::future<void>> attachFutures(kDefaultThreadCount);
|
||||
std_support::vector<Mutator> newMutators(kDefaultThreadCount);
|
||||
std_support::vector<std::future<void>> attachFutures(kDefaultThreadCount);
|
||||
|
||||
for (int i = 0; i < kDefaultThreadCount; ++i) {
|
||||
attachFutures[i] = newMutators[i].Execute([i, expandRootSet](mm::ThreadData& threadData, Mutator& mutator) { expandRootSet(threadData, mutator, i + kDefaultThreadCount); });
|
||||
@@ -1063,7 +1065,7 @@ TEST_F(SameThreadMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
|
||||
// Old mutators don't even see alive objects from the new threads yet (as the latter ones have not published anything).
|
||||
|
||||
KStdVector<ObjHeader*> expectedAlive;
|
||||
std_support::vector<ObjHeader*> expectedAlive;
|
||||
for (int i = 0; i < kDefaultThreadCount; ++i) {
|
||||
expectedAlive.push_back(globals[i]);
|
||||
expectedAlive.push_back(locals[i]);
|
||||
@@ -1075,7 +1077,7 @@ TEST_F(SameThreadMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
}
|
||||
|
||||
for (int i = 0; i < kDefaultThreadCount; ++i) {
|
||||
KStdVector<ObjHeader*> aliveForThisThread(expectedAlive.begin(), expectedAlive.end());
|
||||
std_support::vector<ObjHeader*> aliveForThisThread(expectedAlive.begin(), expectedAlive.end());
|
||||
aliveForThisThread.push_back(globals[kDefaultThreadCount + i]);
|
||||
aliveForThisThread.push_back(locals[kDefaultThreadCount + i]);
|
||||
aliveForThisThread.push_back(reachables[kDefaultThreadCount + i]);
|
||||
@@ -1087,7 +1089,7 @@ TEST_F(SameThreadMarkAndSweepTest, NewThreadsWhileRequestingCollection) {
|
||||
|
||||
|
||||
TEST_F(SameThreadMarkAndSweepTest, FreeObjectWithFreeWeakReversedOrder) {
|
||||
KStdVector<Mutator> mutators(2);
|
||||
std_support::vector<Mutator> mutators(2);
|
||||
std::atomic<test_support::Object<Payload>*> object1 = nullptr;
|
||||
std::atomic<WeakCounter*> weak = nullptr;
|
||||
std::atomic<bool> done = false;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Porting.h"
|
||||
#include "Runtime.h"
|
||||
#include "Types.h"
|
||||
#include "std_support/CStdlib.hpp"
|
||||
|
||||
#ifdef KONAN_ANDROID
|
||||
|
||||
@@ -44,6 +45,8 @@
|
||||
# define LOGV(...) ((void)0)
|
||||
#endif
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
//--- main --------------------------------------------------------------------//
|
||||
namespace {
|
||||
|
||||
@@ -215,7 +218,7 @@ extern "C" void RUNTIME_USED Konan_main(
|
||||
ANativeActivity* activity, void* savedState, size_t savedStateSize) {
|
||||
bool launchThread = activity->instance == nullptr;
|
||||
if (launchThread) {
|
||||
launcherState = (LauncherState*)konan::calloc(sizeof(LauncherState), 1);
|
||||
launcherState = (LauncherState*)std_support::calloc(sizeof(LauncherState), 1);
|
||||
launcherState->nativeActivityState = {activity, savedState, savedStateSize, nullptr};
|
||||
activity->instance = launcherState;
|
||||
activity->callbacks->onDestroy = onDestroy;
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
#include "KString.h"
|
||||
#include "Types.h"
|
||||
#include "Worker.h"
|
||||
#include "std_support/CStdlib.hpp"
|
||||
|
||||
#include "launcher.h"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
//--- Setup args --------------------------------------------------------------//
|
||||
|
||||
OBJ_GETTER(setupArgs, int argc, const char** argv) {
|
||||
@@ -77,9 +80,9 @@ extern "C" int Konan_js_arg_size(int index);
|
||||
extern "C" int Konan_js_fetch_arg(int index, char* ptr);
|
||||
|
||||
extern "C" RUNTIME_USED int Konan_js_main(int argc, int memoryDeInit) {
|
||||
char** argv = (char**)konan::calloc(1, argc);
|
||||
char** argv = (char**)std_support::calloc(1, argc);
|
||||
for (int i = 0; i< argc; ++i) {
|
||||
argv[i] = (char*)konan::calloc(1, Konan_js_arg_size(i));
|
||||
argv[i] = (char*)std_support::calloc(1, Konan_js_arg_size(i));
|
||||
Konan_js_fetch_arg(i, argv[i]);
|
||||
}
|
||||
return Init_and_run_start(argc, (const char**)argv, memoryDeInit);
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#define WITH_WORKERS 1
|
||||
#endif
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "Atomic.h"
|
||||
#include "KAssert.h"
|
||||
#include "Memory.h"
|
||||
@@ -25,6 +24,11 @@
|
||||
#include "Natives.h"
|
||||
#include "Porting.h"
|
||||
#include "Types.h"
|
||||
#include "std_support/Deque.hpp"
|
||||
#include "std_support/New.hpp"
|
||||
#include "std_support/UnorderedMap.hpp"
|
||||
#include "std_support/UnorderedSet.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
#if WITH_WORKERS
|
||||
#include <pthread.h>
|
||||
@@ -42,6 +46,8 @@
|
||||
#define COLLECTOR_LOG(...)
|
||||
#endif
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
/**
|
||||
* Theory of operations:
|
||||
*
|
||||
@@ -124,8 +130,8 @@ class CyclicCollector {
|
||||
int32_t lastTick_;
|
||||
int64_t lastTimestampUs_;
|
||||
void* mainWorker_;
|
||||
KStdUnorderedSet<ObjHeader*> rootset_;
|
||||
KStdUnorderedSet<ObjHeader*> toRelease_;
|
||||
std_support::unordered_set<ObjHeader*> rootset_;
|
||||
std_support::unordered_set<ObjHeader*> toRelease_;
|
||||
|
||||
public:
|
||||
CyclicCollector() {
|
||||
@@ -168,9 +174,9 @@ class CyclicCollector {
|
||||
void gcProcessor() {
|
||||
{
|
||||
Locker locker(&lock_);
|
||||
KStdDeque<ObjHeader*> toVisit;
|
||||
KStdUnorderedSet<ObjHeader*> visited;
|
||||
KStdUnorderedMap<ObjHeader*, int> sideRefCounts;
|
||||
std_support::deque<ObjHeader*> toVisit;
|
||||
std_support::unordered_set<ObjHeader*> visited;
|
||||
std_support::unordered_map<ObjHeader*, int> sideRefCounts;
|
||||
int restartCount = 0;
|
||||
while (!terminateCollector_) {
|
||||
CHECK_CALL(pthread_cond_wait(&cond_, &lock_), "Cannot wait collector condition");
|
||||
@@ -382,7 +388,7 @@ class CyclicCollector {
|
||||
// We are not doing that on the UI thread, as taking lock is slow, unless
|
||||
// it happens on deinit of the collector or if there are no other workers.
|
||||
if ((atomicGet(&pendingRelease_) != 0) && ((worker != mainWorker_) || (currentAliveWorkers_ == 1))) {
|
||||
KStdVector<ObjHeader*> heapRefsToRelease;
|
||||
std_support::vector<ObjHeader*> heapRefsToRelease;
|
||||
|
||||
{
|
||||
suggestLockRelease();
|
||||
@@ -445,7 +451,7 @@ CyclicCollector* cyclicCollector = nullptr;
|
||||
void cyclicInit() {
|
||||
#if WITH_WORKERS
|
||||
RuntimeAssert(cyclicCollector == nullptr, "Must be not yet inited");
|
||||
cyclicCollector = konanConstructInstance<CyclicCollector>();
|
||||
cyclicCollector = new (std_support::kalloc) CyclicCollector();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -456,7 +462,7 @@ void cyclicDeinit(bool enabled) {
|
||||
local->terminate(enabled);
|
||||
cyclicCollector = nullptr;
|
||||
// Workaround data race with threads non-atomically reading and then using [cyclicCollector].
|
||||
// konanDestructInstance(local);
|
||||
// std_support::kdelete(local);
|
||||
// Note: memory leaks here indeed, but usually it happens once per application.
|
||||
// Make best effort to clean some memory:
|
||||
local->clear();
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#define USE_CYCLE_DETECTOR 1
|
||||
#endif
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "KAssert.h"
|
||||
#include "Atomic.h"
|
||||
#include "Cleaner.h"
|
||||
@@ -53,7 +52,13 @@
|
||||
#include "Utils.hpp"
|
||||
#include "WorkerBoundReference.h"
|
||||
#include "Weak.h"
|
||||
#include "std_support/CStdlib.hpp"
|
||||
#include "std_support/Deque.hpp"
|
||||
#include "std_support/List.hpp"
|
||||
#include "std_support/New.hpp"
|
||||
#include "std_support/UnorderedMap.hpp"
|
||||
#include "std_support/UnorderedSet.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
#ifdef KONAN_OBJC_INTEROP
|
||||
#include "ObjCMMAPI.h"
|
||||
@@ -134,15 +139,15 @@ constexpr size_t kGcCollectCyclesMinimumDuration = 200;
|
||||
|
||||
#endif // USE_GC
|
||||
|
||||
typedef KStdUnorderedSet<ContainerHeader*> ContainerHeaderSet;
|
||||
typedef KStdVector<ContainerHeader*> ContainerHeaderList;
|
||||
typedef KStdDeque<ContainerHeader*> ContainerHeaderDeque;
|
||||
typedef KStdVector<KRef> KRefList;
|
||||
typedef KStdVector<KRef*> KRefPtrList;
|
||||
typedef KStdUnorderedSet<KRef> KRefSet;
|
||||
typedef KStdUnorderedMap<KRef, KInt> KRefIntMap;
|
||||
typedef KStdDeque<KRef> KRefDeque;
|
||||
typedef KStdDeque<KRefList> KRefListDeque;
|
||||
typedef std_support::unordered_set<ContainerHeader*> ContainerHeaderSet;
|
||||
typedef std_support::vector<ContainerHeader*> ContainerHeaderList;
|
||||
typedef std_support::deque<ContainerHeader*> ContainerHeaderDeque;
|
||||
typedef std_support::vector<KRef> KRefList;
|
||||
typedef std_support::vector<KRef*> KRefPtrList;
|
||||
typedef std_support::unordered_set<KRef> KRefSet;
|
||||
typedef std_support::unordered_map<KRef, KInt> KRefIntMap;
|
||||
typedef std_support::deque<KRef> KRefDeque;
|
||||
typedef std_support::deque<KRefList> KRefListDeque;
|
||||
|
||||
// A little hack that allows to enable -O2 optimizations
|
||||
// Prevents clang from replacing FrameOverlay struct
|
||||
@@ -192,11 +197,11 @@ class ScopedRefHolder : private kotlin::MoveOnly {
|
||||
|
||||
struct CycleDetectorRootset {
|
||||
// Orders roots.
|
||||
KStdVector<KRef> roots;
|
||||
std_support::vector<KRef> roots;
|
||||
// Pins a state of each root.
|
||||
KStdUnorderedMap<KRef, KStdVector<KRef>> rootToFields;
|
||||
std_support::unordered_map<KRef, std_support::vector<KRef>> rootToFields;
|
||||
// Holding roots and their fields to avoid GC-ing them.
|
||||
KStdVector<ScopedRefHolder> heldRefs;
|
||||
std_support::vector<ScopedRefHolder> heldRefs;
|
||||
};
|
||||
|
||||
class CycleDetector : private kotlin::Pinned {
|
||||
@@ -247,9 +252,9 @@ class CycleDetector : private kotlin::Pinned {
|
||||
}
|
||||
|
||||
kotlin::SpinLock<kotlin::MutexThreadStateHandling::kIgnore> lock_;
|
||||
using CandidateList = KStdList<KRef>;
|
||||
using CandidateList = std_support::list<KRef>;
|
||||
CandidateList candidateList_;
|
||||
KStdUnorderedMap<KRef, CandidateList::iterator> candidateInList_;
|
||||
std_support::unordered_map<KRef, CandidateList::iterator> candidateInList_;
|
||||
};
|
||||
|
||||
#endif // USE_CYCLE_DETECTOR
|
||||
@@ -268,7 +273,7 @@ public:
|
||||
// Free per container type counters.
|
||||
uint64_t objectAllocs[6];
|
||||
// Histogram of allocation size distribution.
|
||||
KStdUnorderedMap<int, int>* allocationHistogram;
|
||||
std_support::unordered_map<int, int>* allocationHistogram;
|
||||
// Number of allocation cache hits.
|
||||
int allocCacheHit;
|
||||
// Number of allocation cache misses.
|
||||
@@ -292,13 +297,13 @@ public:
|
||||
memset(containerAllocs, 0, sizeof(containerAllocs));
|
||||
memset(objectAllocs, 0, sizeof(objectAllocs));
|
||||
memset(updateCounters, 0, sizeof(updateCounters));
|
||||
allocationHistogram = konanConstructInstance<KStdUnorderedMap<int, int>>();
|
||||
allocationHistogram = new (std_support::kalloc) std_support::unordered_map<int, int>();
|
||||
allocCacheHit = 0;
|
||||
allocCacheMiss = 0;
|
||||
}
|
||||
|
||||
void deinit() {
|
||||
konanDestructInstance(allocationHistogram);
|
||||
std_support::kdelete(allocationHistogram);
|
||||
allocationHistogram = nullptr;
|
||||
}
|
||||
|
||||
@@ -402,7 +407,7 @@ public:
|
||||
konan::consolePrintf("\n");
|
||||
|
||||
konan::consolePrintf("Allocation histogram:\n");
|
||||
KStdVector<int> keys(allocationHistogram->size());
|
||||
std_support::vector<int> keys(allocationHistogram->size());
|
||||
int index = 0;
|
||||
for (auto& it : *allocationHistogram) {
|
||||
keys[index++] = it.first;
|
||||
@@ -511,7 +516,7 @@ void ObjHeader::SetAssociatedObject(void* obj) {
|
||||
class ForeignRefManager {
|
||||
public:
|
||||
static ForeignRefManager* create() {
|
||||
ForeignRefManager* result = konanConstructInstance<ForeignRefManager>();
|
||||
ForeignRefManager* result = new (std_support::kalloc) ForeignRefManager();
|
||||
result->addRef();
|
||||
return result;
|
||||
}
|
||||
@@ -528,7 +533,7 @@ class ForeignRefManager {
|
||||
// so it can process the queue pretending like it takes ownership of all its objects:
|
||||
this->processAbandoned();
|
||||
|
||||
konanDestructInstance(this);
|
||||
std_support::kdelete(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,14 +546,14 @@ class ForeignRefManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
konanDestructInstance(this);
|
||||
std_support::kdelete(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void enqueueReleaseRef(ObjHeader* obj) {
|
||||
ListNode* newListNode = konanConstructInstance<ListNode>();
|
||||
ListNode* newListNode = new (std_support::kalloc) ListNode();
|
||||
newListNode->obj = obj;
|
||||
while (true) {
|
||||
ListNode* next = this->releaseList;
|
||||
@@ -571,7 +576,7 @@ class ForeignRefManager {
|
||||
while (toProcess != nullptr) {
|
||||
process(toProcess->obj);
|
||||
ListNode* next = toProcess->next;
|
||||
konanDestructInstance(toProcess);
|
||||
std_support::kdelete(toProcess);
|
||||
toProcess = next;
|
||||
}
|
||||
}
|
||||
@@ -616,11 +621,11 @@ class ThreadLocalStorage {
|
||||
public:
|
||||
using Key = void**;
|
||||
|
||||
void Init() noexcept { map_ = konanConstructInstance<Map>(); }
|
||||
void Init() noexcept { map_ = new (std_support::kalloc) Map(); }
|
||||
|
||||
void Deinit() noexcept {
|
||||
RuntimeAssert(map_->size() == 0, "Must be already cleared");
|
||||
konanDestructInstance(map_);
|
||||
std_support::kdelete(map_);
|
||||
}
|
||||
|
||||
void Add(Key key, int size) noexcept {
|
||||
@@ -636,7 +641,7 @@ public:
|
||||
|
||||
void Commit() noexcept {
|
||||
RuntimeAssert(storage_ == nullptr, "Cannot commit storage twice");
|
||||
storage_ = reinterpret_cast<KRef*>(konanAllocMemory(size_ * sizeof(KRef)));
|
||||
storage_ = reinterpret_cast<KRef*>(std_support::calloc(size_, sizeof(KRef)));
|
||||
}
|
||||
|
||||
void Clear() noexcept {
|
||||
@@ -644,7 +649,7 @@ public:
|
||||
for (int i = 0; i < size_; ++i) {
|
||||
UpdateHeapRef(storage_ + i, nullptr);
|
||||
}
|
||||
konanFreeMemory(storage_);
|
||||
std_support::free(storage_);
|
||||
map_->clear();
|
||||
}
|
||||
|
||||
@@ -669,7 +674,7 @@ private:
|
||||
int size;
|
||||
};
|
||||
|
||||
using Map = KStdUnorderedMap<Key, Entry>;
|
||||
using Map = std_support::unordered_map<Key, Entry>;
|
||||
|
||||
Map* map_ = nullptr;
|
||||
KRef* storage_ = nullptr;
|
||||
@@ -726,7 +731,7 @@ struct MemoryState {
|
||||
#endif // USE_GC
|
||||
|
||||
// A stack of initializing singletons.
|
||||
KStdVector<std::pair<ObjHeader**, ObjHeader*>> initializingSingletons;
|
||||
std_support::vector<std::pair<ObjHeader**, ObjHeader*>> initializingSingletons;
|
||||
|
||||
bool isMainThread = false;
|
||||
|
||||
@@ -767,9 +772,9 @@ namespace {
|
||||
|
||||
#if TRACE_MEMORY
|
||||
#define INIT_TRACE(state) \
|
||||
memoryState->containers = konanConstructInstance<ContainerHeaderSet>();
|
||||
memoryState->containers = new (std_support::kalloc) ContainerHeaderSet();
|
||||
#define DEINIT_TRACE(state) \
|
||||
konanDestructInstance(memoryState->containers); \
|
||||
std_support::kdelete(memoryState->containers); \
|
||||
memoryState->containers = nullptr;
|
||||
#else
|
||||
#define INIT_TRACE(state)
|
||||
@@ -1069,7 +1074,7 @@ ContainerHeader* allocContainer(MemoryState* state, size_t size) {
|
||||
if (state != nullptr)
|
||||
state->allocSinceLastGc += size;
|
||||
#endif
|
||||
result = konanConstructSizedInstance<ContainerHeader>(alignUp(size, kObjectAlignment));
|
||||
result = new (std_support::calloc(1, alignUp(size, kObjectAlignment))) ContainerHeader();
|
||||
atomicAdd(&allocCount, 1);
|
||||
}
|
||||
if (state != nullptr) {
|
||||
@@ -1081,7 +1086,7 @@ ContainerHeader* allocContainer(MemoryState* state, size_t size) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ContainerHeader* allocAggregatingFrozenContainer(KStdVector<ContainerHeader*>& containers) {
|
||||
ContainerHeader* allocAggregatingFrozenContainer(std_support::vector<ContainerHeader*>& containers) {
|
||||
auto componentSize = containers.size();
|
||||
auto* superContainer = allocContainer(memoryState, sizeof(ContainerHeader) + sizeof(void*) * componentSize);
|
||||
auto* place = reinterpret_cast<ContainerHeader**>(superContainer + 1);
|
||||
@@ -1110,7 +1115,7 @@ void processFinalizerQueue(MemoryState* state) {
|
||||
state->containers->erase(container);
|
||||
#endif
|
||||
CONTAINER_DESTROY_EVENT(state, container)
|
||||
konanFreeMemory(container);
|
||||
std_support::free(container);
|
||||
atomicAdd(&allocCount, -1);
|
||||
}
|
||||
RuntimeAssert(state->finalizerQueueSize == 0, "Queue must be empty here");
|
||||
@@ -1151,7 +1156,7 @@ void scheduleDestroyContainer(MemoryState* state, ContainerHeader* container) {
|
||||
processFinalizerQueue(state);
|
||||
}
|
||||
#else
|
||||
konanFreeMemory(container);
|
||||
std_support::free(container);
|
||||
atomicAdd(&allocCount, -1);
|
||||
CONTAINER_DESTROY_EVENT(state, container);
|
||||
#endif
|
||||
@@ -1229,7 +1234,7 @@ void freeContainer(ContainerHeader* container) {
|
||||
* When we see GREY during DFS, it means we see cycle.
|
||||
*/
|
||||
void depthFirstTraversal(ContainerHeader* start, bool* hasCycles,
|
||||
KRef* firstBlocker, KStdVector<ContainerHeader*>* order) {
|
||||
KRef* firstBlocker, std_support::vector<ContainerHeader*>* order) {
|
||||
ContainerHeaderDeque toVisit;
|
||||
toVisit.push_back(start);
|
||||
start->setSeen();
|
||||
@@ -1277,9 +1282,9 @@ void depthFirstTraversal(ContainerHeader* start, bool* hasCycles,
|
||||
}
|
||||
|
||||
void traverseStronglyConnectedComponent(ContainerHeader* start,
|
||||
KStdUnorderedMap<ContainerHeader*,
|
||||
KStdVector<ContainerHeader*>> const* reversedEdges,
|
||||
KStdVector<ContainerHeader*>* component) {
|
||||
std_support::unordered_map<ContainerHeader*,
|
||||
std_support::vector<ContainerHeader*>> const* reversedEdges,
|
||||
std_support::vector<ContainerHeader*>* component) {
|
||||
ContainerHeaderDeque toVisit;
|
||||
toVisit.push_back(start);
|
||||
start->mark();
|
||||
@@ -1447,8 +1452,8 @@ void dumpObject(ObjHeader* ref, int indent) {
|
||||
typeInfo->relativeName_ != nullptr ? CreateCStringFromString(typeInfo->relativeName_) : nullptr;
|
||||
MEMORY_LOG("%p %s.%s\n", ref,
|
||||
packageName ? packageName : "<unknown>", relativeName ? relativeName : "<unknown>");
|
||||
if (packageName) konan::free(packageName);
|
||||
if (relativeName) konan::free(relativeName);
|
||||
if (packageName) std_support::free(packageName);
|
||||
if (relativeName) std_support::free(relativeName);
|
||||
}
|
||||
|
||||
void dumpContainerContent(ContainerHeader* container) {
|
||||
@@ -1762,7 +1767,7 @@ inline ArenaContainer* initedArena(ObjHeader** auxSlot) {
|
||||
auto frame = asFrameOverlay(auxSlot);
|
||||
auto arena = reinterpret_cast<ArenaContainer*>(frame->arena);
|
||||
if (!arena) {
|
||||
arena = konanConstructInstance<ArenaContainer>();
|
||||
arena = new (std_support::kalloc) ArenaContainer();
|
||||
MEMORY_LOG("Initializing arena in %p\n", frame)
|
||||
arena->Init();
|
||||
frame->arena = arena;
|
||||
@@ -2055,14 +2060,14 @@ MemoryState* initMemory(bool firstRuntime) {
|
||||
"Layout mismatch");
|
||||
RuntimeAssert(sizeof(FrameOverlay) % sizeof(ObjHeader**) == 0, "Frame overlay should contain only pointers");
|
||||
RuntimeAssert(memoryState == nullptr, "memory state must be clear");
|
||||
memoryState = konanConstructInstance<MemoryState>();
|
||||
memoryState = new (std_support::kalloc) MemoryState();
|
||||
INIT_EVENT(memoryState)
|
||||
#if USE_GC
|
||||
memoryState->toFree = konanConstructInstance<ContainerHeaderList>();
|
||||
memoryState->roots = konanConstructInstance<ContainerHeaderList>();
|
||||
memoryState->toFree = new (std_support::kalloc) ContainerHeaderList();
|
||||
memoryState->roots = new (std_support::kalloc) ContainerHeaderList();
|
||||
memoryState->gcInProgress = false;
|
||||
memoryState->gcSuspendCount = 0;
|
||||
memoryState->toRelease = konanConstructInstance<ContainerHeaderList>();
|
||||
memoryState->toRelease = new (std_support::kalloc) ContainerHeaderList();
|
||||
initGcThreshold(memoryState, kGcThreshold);
|
||||
initGcCollectCyclesThreshold(memoryState, kMaxToFreeSizeThreshold);
|
||||
memoryState->allocSinceLastGcThreshold = kMaxGcAllocThreshold;
|
||||
@@ -2121,9 +2126,9 @@ void deinitMemory(MemoryState* memoryState, bool destroyRuntime) {
|
||||
} while (memoryState->toRelease->size() > 0 || !memoryState->foreignRefManager->tryReleaseRefOwned());
|
||||
RuntimeAssert(memoryState->toFree->size() == 0, "Some memory have not been released after GC");
|
||||
RuntimeAssert(memoryState->toRelease->size() == 0, "Some memory have not been released after GC");
|
||||
konanDestructInstance(memoryState->toFree);
|
||||
konanDestructInstance(memoryState->roots);
|
||||
konanDestructInstance(memoryState->toRelease);
|
||||
std_support::kdelete(memoryState->toFree);
|
||||
std_support::kdelete(memoryState->roots);
|
||||
std_support::kdelete(memoryState->toRelease);
|
||||
memoryState->tls.Deinit();
|
||||
RuntimeAssert(memoryState->finalizerQueue == nullptr, "Finalizer queue must be empty");
|
||||
RuntimeAssert(memoryState->finalizerQueueSize == 0, "Finalizer queue must be empty");
|
||||
@@ -2151,7 +2156,7 @@ void deinitMemory(MemoryState* memoryState, bool destroyRuntime) {
|
||||
PRINT_EVENT(memoryState)
|
||||
DEINIT_EVENT(memoryState)
|
||||
|
||||
konanFreeMemory(memoryState);
|
||||
std_support::free(memoryState);
|
||||
::memoryState = nullptr;
|
||||
}
|
||||
|
||||
@@ -2618,9 +2623,9 @@ void stopGC() {
|
||||
if (memoryState->toRelease != nullptr) {
|
||||
memoryState->gcSuspendCount = 0;
|
||||
garbageCollect(memoryState, true);
|
||||
konanDestructInstance(memoryState->toRelease);
|
||||
konanDestructInstance(memoryState->toFree);
|
||||
konanDestructInstance(memoryState->roots);
|
||||
std_support::kdelete(memoryState->toRelease);
|
||||
std_support::kdelete(memoryState->toFree);
|
||||
std_support::kdelete(memoryState->roots);
|
||||
memoryState->toRelease = nullptr;
|
||||
memoryState->toFree = nullptr;
|
||||
memoryState->roots = nullptr;
|
||||
@@ -2630,9 +2635,9 @@ void stopGC() {
|
||||
void startGC() {
|
||||
GC_LOG("startGC\n")
|
||||
if (memoryState->toFree == nullptr) {
|
||||
memoryState->toFree = konanConstructInstance<ContainerHeaderList>();
|
||||
memoryState->toRelease = konanConstructInstance<ContainerHeaderList>();
|
||||
memoryState->roots = konanConstructInstance<ContainerHeaderList>();
|
||||
memoryState->toFree = new (std_support::kalloc) ContainerHeaderList();
|
||||
memoryState->toRelease = new (std_support::kalloc) ContainerHeaderList();
|
||||
memoryState->roots = new (std_support::kalloc) ContainerHeaderList();
|
||||
memoryState->gcSuspendCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -2786,7 +2791,7 @@ bool clearSubgraphReferences(ObjHeader* root, bool checked) {
|
||||
}
|
||||
|
||||
void freezeAcyclic(ContainerHeader* rootContainer, ContainerHeaderSet* newlyFrozen) {
|
||||
KStdDeque<ContainerHeader*> queue;
|
||||
std_support::deque<ContainerHeader*> queue;
|
||||
queue.push_back(rootContainer);
|
||||
while (!queue.empty()) {
|
||||
ContainerHeader* current = queue.front();
|
||||
@@ -2811,17 +2816,17 @@ void freezeAcyclic(ContainerHeader* rootContainer, ContainerHeaderSet* newlyFroz
|
||||
}
|
||||
|
||||
void freezeCyclic(ObjHeader* root,
|
||||
const KStdVector<ContainerHeader*>& order,
|
||||
const std_support::vector<ContainerHeader*>& order,
|
||||
ContainerHeaderSet* newlyFrozen) {
|
||||
KStdUnorderedMap<ContainerHeader*, KStdVector<ContainerHeader*>> reversedEdges;
|
||||
KStdDeque<ObjHeader*> queue;
|
||||
std_support::unordered_map<ContainerHeader*, std_support::vector<ContainerHeader*>> reversedEdges;
|
||||
std_support::deque<ObjHeader*> queue;
|
||||
queue.push_back(root);
|
||||
while (!queue.empty()) {
|
||||
ObjHeader* current = queue.front();
|
||||
queue.pop_front();
|
||||
ContainerHeader* currentContainer = containerFor(current);
|
||||
currentContainer->unMark();
|
||||
reversedEdges.emplace(currentContainer, KStdVector<ContainerHeader*>(0));
|
||||
reversedEdges.emplace(currentContainer, std_support::vector<ContainerHeader*>(0));
|
||||
traverseContainerReferredObjects(currentContainer, [current, currentContainer, &queue, &reversedEdges](ObjHeader* obj) {
|
||||
ContainerHeader* objContainer = containerFor(obj);
|
||||
if (canFreeze(objContainer)) {
|
||||
@@ -2829,19 +2834,19 @@ void freezeCyclic(ObjHeader* root,
|
||||
queue.push_back(obj);
|
||||
// We ignore references from FreezableAtomicsReference during condensation, to avoid KT-33824.
|
||||
if (!isFreezableAtomic(current))
|
||||
reversedEdges.emplace(objContainer, KStdVector<ContainerHeader*>(0)).
|
||||
reversedEdges.emplace(objContainer, std_support::vector<ContainerHeader*>(0)).
|
||||
first->second.push_back(currentContainer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
KStdVector<KStdVector<ContainerHeader*>> components;
|
||||
std_support::vector<std_support::vector<ContainerHeader*>> components;
|
||||
MEMORY_LOG("Condensation:\n");
|
||||
// Enumerate in the topological order.
|
||||
for (auto it = order.rbegin(); it != order.rend(); ++it) {
|
||||
auto* container = *it;
|
||||
if (container->marked()) continue;
|
||||
KStdVector<ContainerHeader*> component;
|
||||
std_support::vector<ContainerHeader*> component;
|
||||
traverseStronglyConnectedComponent(container, &reversedEdges, &component);
|
||||
MEMORY_LOG("SCC:\n");
|
||||
#if TRACE_MEMORY
|
||||
@@ -2896,8 +2901,8 @@ void freezeCyclic(ObjHeader* root,
|
||||
}
|
||||
|
||||
void runFreezeHooksRecursive(ObjHeader* root) {
|
||||
KStdUnorderedSet<KRef> seen;
|
||||
KStdVector<KRef> toVisit;
|
||||
std_support::unordered_set<KRef> seen;
|
||||
std_support::vector<KRef> toVisit;
|
||||
seen.insert(root);
|
||||
toVisit.push_back(root);
|
||||
while (!toVisit.empty()) {
|
||||
@@ -2964,7 +2969,7 @@ void freezeSubgraph(ObjHeader* root) {
|
||||
bool hasCycles = false;
|
||||
KRef firstBlocker = root->has_meta_object() && ((root->meta_object()->flags_ & MF_NEVER_FROZEN) != 0) ?
|
||||
root : nullptr;
|
||||
KStdVector<ContainerHeader*> order;
|
||||
std_support::vector<ContainerHeader*> order;
|
||||
depthFirstTraversal(rootContainer, &hasCycles, &firstBlocker, &order);
|
||||
if (firstBlocker != nullptr) {
|
||||
MEMORY_LOG("See freeze blocker for %p: %p\n", root, firstBlocker)
|
||||
@@ -3044,7 +3049,7 @@ CycleDetectorRootset CycleDetector::collectRootset() {
|
||||
return rootset;
|
||||
}
|
||||
|
||||
KStdVector<KRef> findCycleWithDFS(KRef root, const CycleDetectorRootset& rootset) {
|
||||
std_support::vector<KRef> findCycleWithDFS(KRef root, const CycleDetectorRootset& rootset) {
|
||||
auto traverseFields = [&rootset](KRef obj, auto process) {
|
||||
auto it = rootset.rootToFields.find(obj);
|
||||
// If obj is in the rootset, use it's pinned state.
|
||||
@@ -3061,8 +3066,8 @@ KStdVector<KRef> findCycleWithDFS(KRef root, const CycleDetectorRootset& rootset
|
||||
kotlin::traverseReferredObjects(obj, process);
|
||||
};
|
||||
|
||||
KStdVector<KStdVector<KRef>> toVisit;
|
||||
auto appendFieldsToVisit = [&toVisit, &traverseFields](KRef obj, const KStdVector<KRef>& currentPath) {
|
||||
std_support::vector<std_support::vector<KRef>> toVisit;
|
||||
auto appendFieldsToVisit = [&toVisit, &traverseFields](KRef obj, const std_support::vector<KRef>& currentPath) {
|
||||
traverseFields(obj, [&toVisit, ¤tPath](KRef field) {
|
||||
auto path = currentPath;
|
||||
path.push_back(field);
|
||||
@@ -3072,10 +3077,10 @@ KStdVector<KRef> findCycleWithDFS(KRef root, const CycleDetectorRootset& rootset
|
||||
|
||||
appendFieldsToVisit(root, KRefList(1, root));
|
||||
|
||||
KStdUnorderedSet<KRef> seen;
|
||||
std_support::unordered_set<KRef> seen;
|
||||
seen.insert(root);
|
||||
while (!toVisit.empty()) {
|
||||
KStdVector<KRef> currentPath = std::move(toVisit.back());
|
||||
std_support::vector<KRef> currentPath = std::move(toVisit.back());
|
||||
toVisit.pop_back();
|
||||
KRef node = currentPath[currentPath.size() - 1];
|
||||
|
||||
@@ -3108,7 +3113,7 @@ OBJ_GETTER(createAndFillArray, const C& container) {
|
||||
OBJ_GETTER0(detectCyclicReferences) {
|
||||
auto rootset = CycleDetector::collectRootset();
|
||||
|
||||
KStdVector<KRef> cyclic;
|
||||
std_support::vector<KRef> cyclic;
|
||||
|
||||
for (KRef root: rootset.roots) {
|
||||
if (!findCycleWithDFS(root, rootset).empty()) {
|
||||
@@ -3145,7 +3150,7 @@ MetaObjHeader* ObjHeader::createMetaObject(ObjHeader* object) {
|
||||
}
|
||||
#endif
|
||||
|
||||
MetaObjHeader* meta = konanConstructInstance<MetaObjHeader>();
|
||||
MetaObjHeader* meta = new (std_support::kalloc) MetaObjHeader();
|
||||
meta->typeInfo_ = typeInfo;
|
||||
#if KONAN_NO_THREADS
|
||||
*location = reinterpret_cast<TypeInfo*>(meta);
|
||||
@@ -3153,7 +3158,7 @@ MetaObjHeader* ObjHeader::createMetaObject(ObjHeader* object) {
|
||||
TypeInfo* old = __sync_val_compare_and_swap(location, typeInfo, reinterpret_cast<TypeInfo*>(meta));
|
||||
if (old != typeInfo) {
|
||||
// Someone installed a new meta-object since the check.
|
||||
konanFreeMemory(meta);
|
||||
std_support::free(meta);
|
||||
meta = reinterpret_cast<MetaObjHeader*>(old);
|
||||
}
|
||||
#endif
|
||||
@@ -3173,7 +3178,7 @@ void ObjHeader::destroyMetaObject(ObjHeader* object) {
|
||||
Kotlin_ObjCExport_detachAndReleaseAssociatedObject(meta->associatedObject_);
|
||||
#endif
|
||||
|
||||
konanFreeMemory(meta);
|
||||
std_support::free(meta);
|
||||
}
|
||||
|
||||
void ObjectContainer::Init(MemoryState* state, const TypeInfo* typeInfo) {
|
||||
@@ -3223,7 +3228,7 @@ void ArenaContainer::Deinit() {
|
||||
while (chunk != nullptr) {
|
||||
auto toRemove = chunk;
|
||||
chunk = chunk->next;
|
||||
konanFreeMemory(toRemove);
|
||||
std_support::free(toRemove);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3231,7 +3236,7 @@ bool ArenaContainer::allocContainer(container_size_t minSize) {
|
||||
auto size = minSize + sizeof(ContainerHeader) + sizeof(ContainerChunk);
|
||||
size = alignUp(size, kContainerAlignment);
|
||||
// TODO: keep simple cache of container chunks.
|
||||
ContainerChunk* result = konanConstructSizedInstance<ContainerChunk>(size);
|
||||
ContainerChunk* result = new (std_support::calloc(1, size)) ContainerChunk();
|
||||
RuntimeCheck(result != nullptr, "Cannot alloc memory");
|
||||
if (result == nullptr) return false;
|
||||
result->next = currentChunk_;
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
|
||||
#include "std_support/CStdlib.hpp"
|
||||
#include "std_support/New.hpp"
|
||||
|
||||
namespace konan {
|
||||
|
||||
inline void* calloc(size_t count, size_t size) {
|
||||
return kotlin::std_support::calloc(count, size);
|
||||
}
|
||||
|
||||
inline void* calloc_aligned(size_t count, size_t size, size_t alignment) {
|
||||
return kotlin::std_support::aligned_calloc(alignment, count, size);
|
||||
}
|
||||
|
||||
inline void free(void* ptr) {
|
||||
kotlin::std_support::free(ptr);
|
||||
}
|
||||
|
||||
} // namespace konan
|
||||
|
||||
inline void* konanAllocMemory(size_t size) {
|
||||
return konan::calloc(1, size);
|
||||
}
|
||||
|
||||
inline void* konanAllocAlignedMemory(size_t size, size_t alignment) {
|
||||
return konan::calloc_aligned(1, size, alignment);
|
||||
}
|
||||
|
||||
inline void konanFreeMemory(void* memory) {
|
||||
konan::free(memory);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T* konanAllocArray(size_t length) {
|
||||
return reinterpret_cast<T*>(konanAllocMemory(length * sizeof(T)));
|
||||
}
|
||||
|
||||
template <typename T, typename ...A>
|
||||
inline T* konanConstructInstance(A&& ...args) {
|
||||
return new (kotlin::std_support::kalloc) T(std::forward<A>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, typename ...A>
|
||||
inline T* konanConstructSizedInstance(size_t size, A&& ...args) {
|
||||
return new (konanAllocMemory(size)) T(::std::forward<A>(args)...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void konanDestructInstance(T* instance) {
|
||||
kotlin::std_support::kdelete(instance);
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "TestSupport.hpp"
|
||||
#include "TestSupportCompilerGenerated.hpp"
|
||||
#include "Types.h"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
using namespace kotlin::test_support;
|
||||
@@ -39,7 +40,7 @@ TEST_F(CleanerTest, ConcurrentCreation) {
|
||||
|
||||
int startedThreads = 0;
|
||||
bool allowRunning = false;
|
||||
KStdVector<std::future<KInt>> futures;
|
||||
std_support::vector<std::future<KInt>> futures;
|
||||
for (int i = 0; i < threadCount; ++i) {
|
||||
auto future = std::async(std::launch::async, [&startedThreads, &allowRunning]() {
|
||||
// Thread state switching requires initilized memory subsystem.
|
||||
@@ -54,7 +55,7 @@ TEST_F(CleanerTest, ConcurrentCreation) {
|
||||
while (atomicGet(&startedThreads) != threadCount) {
|
||||
}
|
||||
atomicSet(&allowRunning, true);
|
||||
KStdVector<KInt> values;
|
||||
std_support::vector<KInt> values;
|
||||
for (auto& future : futures) {
|
||||
values.push_back(future.get());
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "ClockTestSupport.hpp"
|
||||
#include "ScopedThread.hpp"
|
||||
#include "TestSupport.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -1035,7 +1036,7 @@ TEST(ManualClockTest, ConcurrentSleepUntil) {
|
||||
test_support::manual_clock::reset();
|
||||
|
||||
constexpr auto threadCount = kDefaultThreadCount;
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
std::atomic<bool> run = false;
|
||||
std::atomic<int> ready = 0;
|
||||
for (int i = 0; i < threadCount; ++i) {
|
||||
@@ -1060,7 +1061,7 @@ TEST(ManualClockTest, ConcurrentWaits) {
|
||||
test_support::manual_clock::reset();
|
||||
|
||||
constexpr auto threadCount = kDefaultThreadCount;
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
std::condition_variable_any cvAny;
|
||||
|
||||
@@ -14,4 +14,4 @@ std::atomic<test_support::manual_clock::time_point> test_support::manual_clock::
|
||||
std::mutex test_support::manual_clock::pendingWaitsMutex_;
|
||||
|
||||
// static
|
||||
KStdOrderedMultiset<test_support::manual_clock::time_point> test_support::manual_clock::pendingWaits_;
|
||||
std_support::multiset<test_support::manual_clock::time_point> test_support::manual_clock::pendingWaits_;
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "Types.h"
|
||||
#include "KAssert.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/Set.hpp"
|
||||
|
||||
namespace kotlin::test_support {
|
||||
|
||||
@@ -88,9 +89,9 @@ private:
|
||||
private:
|
||||
friend class manual_clock;
|
||||
|
||||
explicit PendingWaitRegistration(KStdOrderedMultiset<time_point>::iterator it) noexcept : it_(it) {}
|
||||
explicit PendingWaitRegistration(std_support::multiset<time_point>::iterator it) noexcept : it_(it) {}
|
||||
|
||||
KStdOrderedMultiset<time_point>::iterator it_;
|
||||
std_support::multiset<time_point>::iterator it_;
|
||||
};
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
@@ -103,7 +104,7 @@ private:
|
||||
|
||||
static std::atomic<time_point> now_;
|
||||
static std::mutex pendingWaitsMutex_;
|
||||
static KStdOrderedMultiset<time_point> pendingWaits_;
|
||||
static std_support::multiset<time_point> pendingWaits_;
|
||||
};
|
||||
|
||||
} // namespace kotlin::test_support
|
||||
|
||||
@@ -25,9 +25,13 @@
|
||||
#ifdef KONAN_ANDROID
|
||||
#include "CompilerConstants.hpp"
|
||||
#endif
|
||||
#include "std_support/String.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
#include "utf8.h"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
extern "C" {
|
||||
|
||||
// io/Console.kt
|
||||
@@ -37,7 +41,7 @@ void Kotlin_io_Console_print(KString message) {
|
||||
}
|
||||
// TODO: system stdout must be aware about UTF-8.
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(message, 0);
|
||||
KStdString utf8;
|
||||
std_support::string utf8;
|
||||
utf8.reserve(message->count_);
|
||||
// Replace incorrect sequences with a default codepoint (see utf8::with_replacement::default_replacement)
|
||||
utf8::with_replacement::utf16to8(utf16, utf16 + message->count_, back_inserter(utf8));
|
||||
@@ -77,7 +81,7 @@ OBJ_GETTER0(Kotlin_io_Console_readLine) {
|
||||
}
|
||||
|
||||
OBJ_GETTER0(Kotlin_io_Console_readlnOrNull) {
|
||||
KStdVector<char> data;
|
||||
std_support::vector<char> data;
|
||||
data.reserve(16);
|
||||
bool isEOF = false;
|
||||
bool isError = false;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "ScopedThread.hpp"
|
||||
#include "TestSupportCompilerGenerated.hpp"
|
||||
#include "TestSupport.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
using namespace testing;
|
||||
@@ -305,8 +306,8 @@ namespace {
|
||||
using NativeHandlerMock = NiceMock<MockFunction<void(void)>>;
|
||||
using OnUnhandledExceptionMock = NiceMock<MockFunction<void(KRef)>>;
|
||||
|
||||
KStdUniquePtr<NativeHandlerMock> gNativeHandlerMock = nullptr;
|
||||
KStdUniquePtr<test_support::ScopedMockFunction<void(KRef), /* Strict = */ false>> gOnUnhandledExceptionMock = nullptr;
|
||||
std_support::unique_ptr<NativeHandlerMock> gNativeHandlerMock = nullptr;
|
||||
std_support::unique_ptr<test_support::ScopedMockFunction<void(KRef), /* Strict = */ false>> gOnUnhandledExceptionMock = nullptr;
|
||||
|
||||
// Google Test's death tests do not fail in case of a failed EXPECT_*/ASSERT_* check in a death statement.
|
||||
// To workaround it, manually check the conditions to be asserted, log all failed conditions and then
|
||||
@@ -322,7 +323,7 @@ void log(const char* message) noexcept {
|
||||
}
|
||||
|
||||
NativeHandlerMock& setNativeTerminateHandler() noexcept {
|
||||
gNativeHandlerMock = make_unique<NativeHandlerMock>();
|
||||
gNativeHandlerMock = std_support::make_unique<NativeHandlerMock>();
|
||||
std::set_terminate([]() {
|
||||
gNativeHandlerMock->Call();
|
||||
std::abort();
|
||||
@@ -331,8 +332,8 @@ NativeHandlerMock& setNativeTerminateHandler() noexcept {
|
||||
}
|
||||
|
||||
OnUnhandledExceptionMock& setKotlinTerminationHandler() noexcept {
|
||||
gOnUnhandledExceptionMock =
|
||||
make_unique<test_support::ScopedMockFunction<void(KRef), /* Strict = */ false>>(ScopedKotlin_runUnhandledExceptionHookMock</* Strict = */ false>());
|
||||
gOnUnhandledExceptionMock = std_support::make_unique<test_support::ScopedMockFunction<void(KRef), /* Strict = */ false>>(
|
||||
ScopedKotlin_runUnhandledExceptionHookMock</* Strict = */ false>());
|
||||
SetKonanTerminateHandler();
|
||||
return gOnUnhandledExceptionMock->get();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
|
||||
#include "ExecFormat.h"
|
||||
#include "Porting.h"
|
||||
#include "Types.h"
|
||||
#include "std_support/CStdlib.hpp"
|
||||
#include "std_support/New.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
#if USE_ELF_SYMBOLS
|
||||
|
||||
@@ -58,7 +62,7 @@ struct SymRecord {
|
||||
char* strtab;
|
||||
};
|
||||
|
||||
typedef KStdVector<SymRecord> SymRecordList;
|
||||
typedef std_support::vector<SymRecord> SymRecordList;
|
||||
|
||||
SymRecordList* symbols = nullptr;
|
||||
|
||||
@@ -76,7 +80,7 @@ Elf_Ehdr* findElfHeader() {
|
||||
|
||||
void initSymbols() {
|
||||
RuntimeAssert(symbols == nullptr, "Init twice");
|
||||
symbols = konanConstructInstance<SymRecordList>();
|
||||
symbols = new (std_support::kalloc) SymRecordList();
|
||||
Elf_Ehdr* ehdr = findElfHeader();
|
||||
if (ehdr == nullptr) return;
|
||||
RuntimeAssert(strncmp((const char*)ehdr->e_ident, ELFMAG, SELFMAG) == 0, "Must be an ELF");
|
||||
@@ -159,10 +163,10 @@ static void* mapModuleFile(HMODULE hModule) {
|
||||
DWORD bufferLength = 64;
|
||||
wchar_t* buffer = nullptr;
|
||||
for (;;) {
|
||||
auto newBuffer = (wchar_t*)konanAllocMemory(sizeof(wchar_t) * bufferLength);
|
||||
auto newBuffer = (wchar_t*)std_support::calloc(bufferLength, sizeof(wchar_t));
|
||||
RuntimeAssert(newBuffer != nullptr, "Out of memory");
|
||||
if (buffer != nullptr) {
|
||||
konanFreeMemory(buffer);
|
||||
std_support::free(buffer);
|
||||
}
|
||||
buffer = newBuffer;
|
||||
|
||||
@@ -178,7 +182,7 @@ static void* mapModuleFile(HMODULE hModule) {
|
||||
}
|
||||
|
||||
// Invalid result.
|
||||
konanFreeMemory(buffer);
|
||||
std_support::free(buffer);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -191,7 +195,7 @@ static void* mapModuleFile(HMODULE hModule) {
|
||||
/* dwFlagsAndAttributes = */ FILE_ATTRIBUTE_NORMAL,
|
||||
/* hTemplateFile = */ nullptr
|
||||
);
|
||||
konanFreeMemory(buffer);
|
||||
std_support::free(buffer);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
// Can't open module file.
|
||||
return nullptr;
|
||||
@@ -323,7 +327,7 @@ extern "C" bool AddressToSymbol(const void* address, char* resultBuffer, size_t
|
||||
int rv = GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
reinterpret_cast<LPCWSTR>(&AddressToSymbol), &hModule);
|
||||
RuntimeAssert(rv != 0, "GetModuleHandleExW fails");
|
||||
theExeSymbolTable = konanConstructInstance<SymbolTable>(hModule);
|
||||
theExeSymbolTable = new (std_support::kalloc) SymbolTable(hModule);
|
||||
}
|
||||
return theExeSymbolTable->functionAddressToSymbol(address, resultBuffer, resultBufferSize, resultOffset);
|
||||
}
|
||||
|
||||
@@ -19,24 +19,26 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "KString.h"
|
||||
#include "Memory.h"
|
||||
#include "MemorySharedRefs.hpp"
|
||||
#include "Types.h"
|
||||
#include "std_support/New.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
extern "C" {
|
||||
|
||||
KNativePtr Kotlin_Interop_createStablePointer(KRef any) {
|
||||
KRefSharedHolder* holder = konanConstructInstance<KRefSharedHolder>();
|
||||
holder->init(any);
|
||||
return holder;
|
||||
KRefSharedHolder* holder = new (std_support::kalloc) KRefSharedHolder();
|
||||
holder->init(any);
|
||||
return holder;
|
||||
}
|
||||
|
||||
void Kotlin_Interop_disposeStablePointer(KNativePtr pointer) {
|
||||
KRefSharedHolder* holder = reinterpret_cast<KRefSharedHolder*>(pointer);
|
||||
holder->dispose();
|
||||
konanDestructInstance(holder);
|
||||
std_support::kdelete(holder);
|
||||
}
|
||||
|
||||
OBJ_GETTER(Kotlin_Interop_derefStablePointer, KNativePtr pointer) {
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/List.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -54,8 +54,8 @@ private:
|
||||
};
|
||||
|
||||
template <typename List>
|
||||
KStdList<typename List::value_type> create(std::initializer_list<int> list) {
|
||||
KStdList<typename List::value_type> result;
|
||||
std_support::list<typename List::value_type> create(std::initializer_list<int> list) {
|
||||
std_support::list<typename List::value_type> result;
|
||||
for (auto x : list) {
|
||||
result.emplace_back(x);
|
||||
}
|
||||
|
||||
@@ -24,14 +24,18 @@
|
||||
#include "KString.h"
|
||||
#include "Porting.h"
|
||||
#include "Types.h"
|
||||
#include "std_support/CStdlib.hpp"
|
||||
#include "std_support/String.hpp"
|
||||
|
||||
#include "utf8.h"
|
||||
|
||||
#include "polyhash/PolyHash.h"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
namespace {
|
||||
|
||||
typedef std::back_insert_iterator<KStdString> KStdStringInserter;
|
||||
typedef std::back_insert_iterator<std_support::string> KStdStringInserter;
|
||||
typedef KChar* utf8to16(const char*, const char*, KChar*);
|
||||
typedef KStdStringInserter utf16to8(const KChar*,const KChar*, KStdStringInserter);
|
||||
|
||||
@@ -55,7 +59,7 @@ template<utf16to8 conversion>
|
||||
OBJ_GETTER(unsafeUtf16ToUtf8Impl, KString thiz, KInt start, KInt size) {
|
||||
RuntimeAssert(thiz->type_info() == theStringTypeInfo, "Must use String");
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(thiz, start);
|
||||
KStdString utf8;
|
||||
std_support::string utf8;
|
||||
utf8.reserve(size);
|
||||
conversion(utf16, utf16 + size, back_inserter(utf8));
|
||||
ArrayHeader* result = AllocArrayInstance(theByteArrayTypeInfo, utf8.size(), OBJ_RESULT)->array();
|
||||
@@ -118,16 +122,16 @@ char* CreateCStringFromString(KConstRef kref) {
|
||||
if (kref == nullptr) return nullptr;
|
||||
KString kstring = kref->array();
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(kstring, 0);
|
||||
KStdString utf8;
|
||||
std_support::string utf8;
|
||||
utf8.reserve(kstring->count_);
|
||||
utf8::unchecked::utf16to8(utf16, utf16 + kstring->count_, back_inserter(utf8));
|
||||
char* result = reinterpret_cast<char*>(konan::calloc(1, utf8.size() + 1));
|
||||
char* result = reinterpret_cast<char*>(std_support::calloc(1, utf8.size() + 1));
|
||||
::memcpy(result, utf8.c_str(), utf8.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
void DisposeCString(char* cstring) {
|
||||
if (cstring) konan::free(cstring);
|
||||
if (cstring) std_support::free(cstring);
|
||||
}
|
||||
|
||||
// String.kt
|
||||
|
||||
@@ -23,6 +23,8 @@ inline constexpr auto nullopt = std::experimental::nullopt;
|
||||
#include "Format.h"
|
||||
#include "KAssert.h"
|
||||
#include "Porting.h"
|
||||
#include "std_support/Map.hpp"
|
||||
#include "std_support/String.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -61,9 +63,9 @@ std::optional<logging::Level> ParseLevel(std::string_view levelString) noexcept
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
KStdOrderedMap<KStdString, logging::Level> ParseTagsFilter(std::string_view tagsFilter) noexcept {
|
||||
std_support::map<std_support::string, logging::Level> ParseTagsFilter(std::string_view tagsFilter) noexcept {
|
||||
if (tagsFilter.empty()) return {};
|
||||
KStdOrderedMap<KStdString, logging::Level> result;
|
||||
std_support::map<std_support::string, logging::Level> result;
|
||||
std::string_view rest = tagsFilter;
|
||||
while (!rest.empty()) {
|
||||
auto tag = ParseTag(rest);
|
||||
@@ -83,7 +85,7 @@ KStdOrderedMap<KStdString, logging::Level> ParseTagsFilter(std::string_view tags
|
||||
konan::consoleErrorf("'. No logging will be performed\n");
|
||||
return {};
|
||||
}
|
||||
result.emplace(KStdString(tag.value->data(), tag.value->size()), *level);
|
||||
result.emplace(std_support::string(tag.value->data(), tag.value->size()), *level);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -108,7 +110,7 @@ public:
|
||||
|
||||
private:
|
||||
// TODO: Make it more efficient.
|
||||
KStdOrderedMap<KStdString, logging::Level> tagLevelMap_;
|
||||
std_support::map<std_support::string, logging::Level> tagLevelMap_;
|
||||
};
|
||||
|
||||
class StderrLogger : public logging::internal::Logger {
|
||||
@@ -143,12 +145,12 @@ std_support::span<char> FormatTags(std_support::span<char> buffer, std_support::
|
||||
|
||||
} // namespace
|
||||
|
||||
KStdUniquePtr<logging::internal::LogFilter> logging::internal::CreateLogFilter(std::string_view tagsFilter) noexcept {
|
||||
return ::make_unique<::LogFilter>(tagsFilter);
|
||||
std_support::unique_ptr<logging::internal::LogFilter> logging::internal::CreateLogFilter(std::string_view tagsFilter) noexcept {
|
||||
return std_support::make_unique<::LogFilter>(tagsFilter);
|
||||
}
|
||||
|
||||
KStdUniquePtr<logging::internal::Logger> logging::internal::CreateStderrLogger() noexcept {
|
||||
return ::make_unique<StderrLogger>();
|
||||
std_support::unique_ptr<logging::internal::Logger> logging::internal::CreateStderrLogger() noexcept {
|
||||
return std_support::make_unique<StderrLogger>();
|
||||
}
|
||||
|
||||
std_support::span<char> logging::internal::FormatLogEntry(
|
||||
|
||||
@@ -22,8 +22,8 @@ using string_view = std::experimental::string_view;
|
||||
#endif
|
||||
|
||||
#include "CompilerConstants.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
#include "std_support/Span.hpp"
|
||||
#include "Types.h"
|
||||
|
||||
namespace kotlin {
|
||||
namespace logging {
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
virtual bool Enabled(Level level, std_support::span<const char* const> tags) const noexcept = 0;
|
||||
};
|
||||
|
||||
KStdUniquePtr<LogFilter> CreateLogFilter(std::string_view tagsFilter) noexcept;
|
||||
std_support::unique_ptr<LogFilter> CreateLogFilter(std::string_view tagsFilter) noexcept;
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
virtual void Log(Level level, std_support::span<const char* const> tags, std::string_view message) const noexcept = 0;
|
||||
};
|
||||
|
||||
KStdUniquePtr<Logger> CreateStderrLogger() noexcept;
|
||||
std_support::unique_ptr<Logger> CreateStderrLogger() noexcept;
|
||||
|
||||
std_support::span<char> FormatLogEntry(
|
||||
std_support::span<char> buffer,
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
using ::testing::_;
|
||||
@@ -36,7 +38,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
KStdUniquePtr<logging::internal::LogFilter> logFilter_;
|
||||
std_support::unique_ptr<logging::internal::LogFilter> logFilter_;
|
||||
};
|
||||
|
||||
class MockLogFilter : public logging::internal::LogFilter {
|
||||
@@ -202,7 +204,7 @@ private:
|
||||
};
|
||||
|
||||
MATCHER_P(TagsAre, tags, "") {
|
||||
KStdVector<std::string_view> actualTags;
|
||||
std_support::vector<std::string_view> actualTags;
|
||||
for (auto tag : arg) {
|
||||
actualTags.push_back(tag);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <mutex>
|
||||
|
||||
#include "Mutex.hpp"
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/List.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
@@ -29,7 +28,7 @@ class MultiSourceQueue {
|
||||
public:
|
||||
class Producer;
|
||||
|
||||
// TODO: Consider switching from `KStdList` to `SingleLockList` to hide the constructor
|
||||
// TODO: Consider switching from `std_support::list` to `SingleLockList` to hide the constructor
|
||||
// and to not store the iterator.
|
||||
class Node : private Pinned {
|
||||
public:
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "AllocatorTestSupport.hpp"
|
||||
#include "ScopedThread.hpp"
|
||||
#include "TestSupport.hpp"
|
||||
#include "Types.h"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -22,8 +22,8 @@ using ::testing::_;
|
||||
namespace {
|
||||
|
||||
template <typename T, typename Mutex>
|
||||
KStdVector<T> Collect(MultiSourceQueue<T, Mutex>& queue) {
|
||||
KStdVector<T> result;
|
||||
std_support::vector<T> Collect(MultiSourceQueue<T, Mutex>& queue) {
|
||||
std_support::vector<T> result;
|
||||
for (const auto& element : queue.LockForIter()) {
|
||||
result.push_back(element);
|
||||
}
|
||||
@@ -196,8 +196,8 @@ TEST(MultiSourceQueueTest, ConcurrentPublish) {
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> readyCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
KStdVector<int> expected;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
std_support::vector<int> expected;
|
||||
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
expected.push_back(i);
|
||||
@@ -225,8 +225,8 @@ TEST(MultiSourceQueueTest, IterWhileConcurrentPublish) {
|
||||
constexpr int kStartCount = 50;
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
|
||||
KStdVector<int> expectedBefore;
|
||||
KStdVector<int> expectedAfter;
|
||||
std_support::vector<int> expectedBefore;
|
||||
std_support::vector<int> expectedAfter;
|
||||
IntQueue::Producer producer(queue);
|
||||
for (int i = 0; i < kStartCount; ++i) {
|
||||
expectedBefore.push_back(i);
|
||||
@@ -238,7 +238,7 @@ TEST(MultiSourceQueueTest, IterWhileConcurrentPublish) {
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> readyCount(0);
|
||||
std::atomic<int> startedCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
int j = i + kStartCount;
|
||||
expectedAfter.push_back(j);
|
||||
@@ -253,7 +253,7 @@ TEST(MultiSourceQueueTest, IterWhileConcurrentPublish) {
|
||||
});
|
||||
}
|
||||
|
||||
KStdVector<int> actualBefore;
|
||||
std_support::vector<int> actualBefore;
|
||||
{
|
||||
auto iter = queue.LockForIter();
|
||||
while (readyCount < kThreadCount) {
|
||||
@@ -282,7 +282,7 @@ TEST(MultiSourceQueueTest, ConcurrentPublishAndApplyDeletions) {
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> readyCount(0);
|
||||
std::atomic<int> startedCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
threads.emplace_back([&queue, i, &canStart, &readyCount, &startedCount]() {
|
||||
IntQueue::Producer producer(queue);
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#include "Porting.h"
|
||||
#include "Natives.h"
|
||||
#include "Types.h"
|
||||
#include "std_support/CStdlib.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -87,7 +90,7 @@ void* Kotlin_interop_malloc(KLong size, KInt align) {
|
||||
RuntimeAssert(align > 0, "Unsupported alignment");
|
||||
RuntimeAssert((align & (align - 1)) == 0, "Alignment must be power of two");
|
||||
|
||||
void* result = konan::calloc_aligned(1, size, align);
|
||||
void* result = std_support::aligned_calloc(align, 1, size);
|
||||
if ((reinterpret_cast<uintptr_t>(result) & (align - 1)) != 0) {
|
||||
// Unaligned!
|
||||
RuntimeAssert(false, "unsupported alignment");
|
||||
@@ -97,7 +100,7 @@ void* Kotlin_interop_malloc(KLong size, KInt align) {
|
||||
}
|
||||
|
||||
void Kotlin_interop_free(void* ptr) {
|
||||
konan::free(ptr);
|
||||
std_support::free(ptr);
|
||||
}
|
||||
|
||||
void Kotlin_system_exitProcess(KInt status) {
|
||||
|
||||
@@ -43,6 +43,22 @@
|
||||
#import "Runtime.h"
|
||||
#import "Mutex.hpp"
|
||||
#import "Exceptions.h"
|
||||
#include "std_support/CStdlib.hpp"
|
||||
#include "std_support/Map.hpp"
|
||||
#include "std_support/String.hpp"
|
||||
#include "std_support/UnorderedSet.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
inline T* konanAllocArray(size_t length) {
|
||||
return reinterpret_cast<T*>(std_support::calloc(length, sizeof(T)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct ObjCToKotlinMethodAdapter {
|
||||
const char* selector;
|
||||
@@ -653,7 +669,7 @@ static id Kotlin_ObjCExport_refToRetainedObjC_slowpath(ObjHeader* obj) {
|
||||
return convertToRetained(obj);
|
||||
}
|
||||
|
||||
static void buildITable(TypeInfo* result, const KStdOrderedMap<ClassId, KStdVector<VTableElement>>& interfaceVTables) {
|
||||
static void buildITable(TypeInfo* result, const std_support::map<ClassId, std_support::vector<VTableElement>>& interfaceVTables) {
|
||||
// Check if can use fast optimistic version - check if the size of the itable could be 2^k and <= 32.
|
||||
bool useFastITable;
|
||||
int itableSize = 1;
|
||||
@@ -687,7 +703,7 @@ static void buildITable(TypeInfo* result, const KStdOrderedMap<ClassId, KStdVect
|
||||
}
|
||||
} else {
|
||||
// Otherwise: conservative version.
|
||||
// The table will be sorted since we're using KStdOrderedMap.
|
||||
// The table will be sorted since we're using std_support::map.
|
||||
int index = 0;
|
||||
for (auto& pair : interfaceVTables) {
|
||||
auto interfaceId = pair.first;
|
||||
@@ -712,15 +728,15 @@ static void buildITable(TypeInfo* result, const KStdOrderedMap<ClassId, KStdVect
|
||||
|
||||
static const TypeInfo* createTypeInfo(
|
||||
const TypeInfo* superType,
|
||||
const KStdVector<const TypeInfo*>& superInterfaces,
|
||||
const KStdVector<VTableElement>& vtable,
|
||||
const KStdOrderedMap<ClassId, KStdVector<VTableElement>>& interfaceVTables,
|
||||
const std_support::vector<const TypeInfo*>& superInterfaces,
|
||||
const std_support::vector<VTableElement>& vtable,
|
||||
const std_support::map<ClassId, std_support::vector<VTableElement>>& interfaceVTables,
|
||||
const InterfaceTableRecord* superItable,
|
||||
int superItableSize,
|
||||
bool itableEqualsSuper,
|
||||
const TypeInfo* fieldsInfo
|
||||
) {
|
||||
TypeInfo* result = (TypeInfo*)konanAllocMemory(sizeof(TypeInfo) + vtable.size() * sizeof(void*));
|
||||
TypeInfo* result = (TypeInfo*)std_support::calloc(1, sizeof(TypeInfo) + vtable.size() * sizeof(void*));
|
||||
result->typeInfo_ = result;
|
||||
|
||||
result->flags_ = TF_OBJC_DYNAMIC;
|
||||
@@ -741,10 +757,10 @@ static const TypeInfo* createTypeInfo(
|
||||
|
||||
result->classId_ = superType->classId_;
|
||||
|
||||
KStdVector<const TypeInfo*> implementedInterfaces(
|
||||
std_support::vector<const TypeInfo*> implementedInterfaces(
|
||||
superType->implementedInterfaces_, superType->implementedInterfaces_ + superType->implementedInterfacesCount_
|
||||
);
|
||||
KStdUnorderedSet<const TypeInfo*> usedInterfaces(implementedInterfaces.begin(), implementedInterfaces.end());
|
||||
std_support::unordered_set<const TypeInfo*> usedInterfaces(implementedInterfaces.begin(), implementedInterfaces.end());
|
||||
|
||||
for (const TypeInfo* interface : superInterfaces) {
|
||||
if (usedInterfaces.insert(interface).second) {
|
||||
@@ -770,14 +786,14 @@ static const TypeInfo* createTypeInfo(
|
||||
|
||||
result->packageName_ = nullptr;
|
||||
result->relativeName_ = nullptr; // TODO: add some info.
|
||||
result->writableInfo_ = (WritableTypeInfo*)konanAllocMemory(sizeof(WritableTypeInfo));
|
||||
result->writableInfo_ = (WritableTypeInfo*)std_support::calloc(1, sizeof(WritableTypeInfo));
|
||||
|
||||
for (size_t i = 0; i < vtable.size(); ++i) result->vtable()[i] = vtable[i];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void addDefinedSelectors(Class clazz, KStdUnorderedSet<SEL>& result) {
|
||||
static void addDefinedSelectors(Class clazz, std_support::unordered_set<SEL>& result) {
|
||||
unsigned int objcMethodCount;
|
||||
Method* objcMethods = class_copyMethodList(clazz, &objcMethodCount);
|
||||
|
||||
@@ -788,10 +804,10 @@ static void addDefinedSelectors(Class clazz, KStdUnorderedSet<SEL>& result) {
|
||||
if (objcMethods != nullptr) free(objcMethods);
|
||||
}
|
||||
|
||||
static KStdVector<const TypeInfo*> getProtocolsAsInterfaces(Class clazz) {
|
||||
KStdVector<const TypeInfo*> result;
|
||||
KStdUnorderedSet<Protocol*> handledProtocols;
|
||||
KStdVector<Protocol*> protocolsToHandle;
|
||||
static std_support::vector<const TypeInfo*> getProtocolsAsInterfaces(Class clazz) {
|
||||
std_support::vector<const TypeInfo*> result;
|
||||
std_support::unordered_set<Protocol*> handledProtocols;
|
||||
std_support::vector<Protocol*> protocolsToHandle;
|
||||
|
||||
{
|
||||
unsigned int protocolCount;
|
||||
@@ -847,7 +863,7 @@ static void throwIfCantBeOverridden(Class clazz, const KotlinToObjCMethodAdapter
|
||||
}
|
||||
|
||||
static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, const TypeInfo* fieldsInfo) {
|
||||
KStdUnorderedSet<SEL> definedSelectors;
|
||||
std_support::unordered_set<SEL> definedSelectors;
|
||||
addDefinedSelectors(clazz, definedSelectors);
|
||||
|
||||
const ObjCTypeAdapter* superTypeAdapter = getTypeAdapter(superType);
|
||||
@@ -870,7 +886,7 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
|
||||
if (superVtable == nullptr) superVtable = superType->vtable();
|
||||
|
||||
KStdVector<const void*> vtable(
|
||||
std_support::vector<const void*> vtable(
|
||||
superVtable,
|
||||
superVtable + superVtableSize
|
||||
);
|
||||
@@ -879,7 +895,7 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
superITable = superType->interfaceTable_;
|
||||
superITableSize = superType->interfaceTableSize_;
|
||||
}
|
||||
KStdOrderedMap<ClassId, KStdVector<VTableElement>> interfaceVTables;
|
||||
std_support::map<ClassId, std_support::vector<VTableElement>> interfaceVTables;
|
||||
if (superITable != nullptr) {
|
||||
int actualItableSize = superITableSize >= 0 ? superITableSize + 1 : -superITableSize;
|
||||
for (int i = 0; i < actualItableSize; ++i) {
|
||||
@@ -887,16 +903,16 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
auto interfaceId = record.id;
|
||||
if (interfaceId == kInvalidInterfaceId) continue;
|
||||
int vtableSize = record.vtableSize;
|
||||
KStdVector<VTableElement> interfaceVTable(vtableSize);
|
||||
std_support::vector<VTableElement> interfaceVTable(vtableSize);
|
||||
for (int j = 0; j < vtableSize; ++j)
|
||||
interfaceVTable[j] = record.vtable[j];
|
||||
interfaceVTables.emplace(interfaceId, std::move(interfaceVTable));
|
||||
}
|
||||
}
|
||||
|
||||
KStdVector<const TypeInfo*> addedInterfaces = getProtocolsAsInterfaces(clazz);
|
||||
std_support::vector<const TypeInfo*> addedInterfaces = getProtocolsAsInterfaces(clazz);
|
||||
|
||||
KStdVector<const TypeInfo*> supers(
|
||||
std_support::vector<const TypeInfo*> supers(
|
||||
superType->implementedInterfaces_,
|
||||
superType->implementedInterfaces_ + superType->implementedInterfacesCount_
|
||||
);
|
||||
@@ -921,7 +937,7 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
auto interfaceVTablesIt = interfaceVTables.find(interfaceId);
|
||||
if (interfaceVTablesIt == interfaceVTables.end()) {
|
||||
itableEqualsSuper = false;
|
||||
interfaceVTables.emplace(interfaceId, KStdVector<VTableElement>(itableSize));
|
||||
interfaceVTables.emplace(interfaceId, std_support::vector<VTableElement>(itableSize));
|
||||
} else {
|
||||
auto const& interfaceVTable = interfaceVTablesIt->second;
|
||||
RuntimeAssert(interfaceVTable.size() == static_cast<size_t>(itableSize), "");
|
||||
@@ -1036,7 +1052,7 @@ static Class createClass(const TypeInfo* typeInfo, Class superClass) {
|
||||
RuntimeAssert(typeInfo->superType_ != nullptr, "");
|
||||
|
||||
int classIndex = (anonymousClassNextId++);
|
||||
KStdString className = Kotlin_ObjCInterop_getUniquePrefix();
|
||||
std_support::string className = Kotlin_ObjCInterop_getUniquePrefix();
|
||||
className += "_kobjcc";
|
||||
className += std::to_string(classIndex);
|
||||
|
||||
@@ -1056,7 +1072,7 @@ static Class createClass(const TypeInfo* typeInfo, Class superClass) {
|
||||
}
|
||||
}
|
||||
|
||||
KStdUnorderedSet<const TypeInfo*> superImplementedInterfaces(
|
||||
std_support::unordered_set<const TypeInfo*> superImplementedInterfaces(
|
||||
typeInfo->superType_->implementedInterfaces_,
|
||||
typeInfo->superType_->implementedInterfaces_ + typeInfo->superType_->implementedInterfacesCount_
|
||||
);
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
#include "StackTrace.hpp"
|
||||
#include "Types.h"
|
||||
#include "Mutex.hpp"
|
||||
#include "std_support/String.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
// Replaced in ObjCExportCodeGenerator.
|
||||
__attribute__((weak)) const char* Kotlin_ObjCInterop_uniquePrefix = nullptr;
|
||||
@@ -267,7 +270,7 @@ NO_EXTERNAL_CALLS_CHECK static Class allocateClass(const KotlinObjCClassInfo* in
|
||||
fprintf(stderr, "Class %s has multiple implementations. Which one will be used is undefined.\n", info->name);
|
||||
}
|
||||
|
||||
KStdString className = Kotlin_ObjCInterop_getUniquePrefix();
|
||||
std_support::string className = Kotlin_ObjCInterop_getUniquePrefix();
|
||||
|
||||
if (info->name != nullptr) {
|
||||
className += info->name;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "TypeInfo.h"
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
namespace test_support {
|
||||
@@ -26,7 +27,7 @@ private:
|
||||
virtual ~Builder() = default;
|
||||
|
||||
int32_t instanceSize_ = 0;
|
||||
KStdVector<int32_t> objOffsets_;
|
||||
std_support::vector<int32_t> objOffsets_;
|
||||
int32_t flags_ = 0;
|
||||
const TypeInfo* superType_ = nullptr;
|
||||
};
|
||||
@@ -88,7 +89,7 @@ public:
|
||||
|
||||
private:
|
||||
TypeInfo typeInfo_{};
|
||||
KStdVector<int32_t> objOffsets_;
|
||||
std_support::vector<int32_t> objOffsets_;
|
||||
};
|
||||
|
||||
template <typename Payload>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "Natives.h"
|
||||
#include "TestSupport.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -68,8 +69,8 @@ using ObjectTestCases = testing::Types<RegularObjectTestCase, IrregularObjectTes
|
||||
TYPED_TEST_SUITE(ObjectTestSupportObjectTest, ObjectTestCases, ObjectTestCaseNames);
|
||||
|
||||
template <typename Payload>
|
||||
KStdVector<ObjHeader**> Collect(test_support::Object<Payload>& object) {
|
||||
KStdVector<ObjHeader**> result;
|
||||
std_support::vector<ObjHeader**> Collect(test_support::Object<Payload>& object) {
|
||||
std_support::vector<ObjHeader**> result;
|
||||
for (auto& field : object.fields()) {
|
||||
result.push_back(&field);
|
||||
}
|
||||
@@ -307,8 +308,8 @@ using ArrayTestCases = testing::Types<
|
||||
TYPED_TEST_SUITE(ObjectTestSupportArrayTest, ArrayTestCases, ArrayTestCaseNames);
|
||||
|
||||
template <typename Payload, size_t ElementCount>
|
||||
KStdVector<Payload*> Collect(test_support::internal::Array<Payload, ElementCount>& array) {
|
||||
KStdVector<Payload*> result;
|
||||
std_support::vector<Payload*> Collect(test_support::internal::Array<Payload, ElementCount>& array) {
|
||||
std_support::vector<Payload*> result;
|
||||
for (auto& element : array.elements()) {
|
||||
result.push_back(&element);
|
||||
}
|
||||
@@ -329,7 +330,7 @@ TYPED_TEST(ObjectTestSupportArrayTest, Local) {
|
||||
EXPECT_THAT(array.arrayHeader()->count_, size);
|
||||
EXPECT_THAT(array.elements().size(), size);
|
||||
|
||||
KStdVector<Payload*> expected;
|
||||
std_support::vector<Payload*> expected;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
auto* element = AddressOfElementAt<Payload>(array.arrayHeader(), i);
|
||||
EXPECT_THAT(&array.elements()[i], element);
|
||||
@@ -360,7 +361,7 @@ TYPED_TEST(ObjectTestSupportArrayTest, Heap) {
|
||||
EXPECT_THAT(array.arrayHeader()->count_, size);
|
||||
EXPECT_THAT(array.elements().size(), size);
|
||||
|
||||
KStdVector<Payload*> expected;
|
||||
std_support::vector<Payload*> expected;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
auto* element = AddressOfElementAt<Payload>(array.arrayHeader(), i);
|
||||
EXPECT_THAT(&array.elements()[i], element);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "Atomic.h"
|
||||
#include "Cleaner.h"
|
||||
#include "CompilerConstants.hpp"
|
||||
@@ -27,11 +26,14 @@
|
||||
#include "RuntimePrivate.hpp"
|
||||
#include "Worker.h"
|
||||
#include "KString.h"
|
||||
#include "std_support/New.hpp"
|
||||
|
||||
#ifndef KONAN_NO_THREADS
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
using kotlin::internal::FILE_NOT_INITIALIZED;
|
||||
using kotlin::internal::FILE_BEING_INITIALIZED;
|
||||
using kotlin::internal::FILE_INITIALIZED;
|
||||
@@ -100,7 +102,7 @@ volatile GlobalRuntimeStatus globalRuntimeStatus = kGlobalRuntimeUninitialized;
|
||||
|
||||
RuntimeState* initRuntime() {
|
||||
SetKonanTerminateHandler();
|
||||
RuntimeState* result = konanConstructInstance<RuntimeState>();
|
||||
RuntimeState* result = new (std_support::kalloc) RuntimeState();
|
||||
if (!result) return kInvalidRuntime;
|
||||
RuntimeCheck(!isValidRuntime(), "No active runtimes allowed");
|
||||
::runtimeState = result;
|
||||
@@ -188,7 +190,7 @@ void deinitRuntime(RuntimeState* state, bool destroyRuntime) {
|
||||
// Do not use ThreadStateGuard because memoryState will be destroyed during DeinitMemory.
|
||||
kotlin::SwitchThreadState(state->memoryState, kotlin::ThreadState::kNative);
|
||||
DeinitMemory(state->memoryState, destroyRuntime);
|
||||
konanDestructInstance(state);
|
||||
std_support::kdelete(state);
|
||||
WorkerDestroyThreadDataIfNeeded(workerId);
|
||||
::runtimeState = kInvalidRuntime;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/String.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
namespace internal {
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
|
||||
private:
|
||||
friend class ScopedThread;
|
||||
std::optional<KStdString> name_;
|
||||
std::optional<std_support::string> name_;
|
||||
};
|
||||
|
||||
ScopedThread() noexcept = default;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include "Mutex.hpp"
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
#include "AllocatorTestSupport.hpp"
|
||||
#include "ScopedThread.hpp"
|
||||
#include "TestSupport.hpp"
|
||||
#include "Types.h"
|
||||
#include "std_support/Deque.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -51,7 +52,7 @@ TEST(SingleLockListTest, EmplaceAndIter) {
|
||||
list.Emplace(kSecond);
|
||||
list.Emplace(kThird);
|
||||
|
||||
KStdVector<int> actual;
|
||||
std_support::vector<int> actual;
|
||||
for (int element : list.LockForIter()) {
|
||||
actual.push_back(element);
|
||||
}
|
||||
@@ -69,7 +70,7 @@ TEST(SingleLockListTest, EmplaceEraseAndIter) {
|
||||
list.Emplace(kThird);
|
||||
list.Erase(secondNode);
|
||||
|
||||
KStdVector<int> actual;
|
||||
std_support::vector<int> actual;
|
||||
for (int element : list.LockForIter()) {
|
||||
actual.push_back(element);
|
||||
}
|
||||
@@ -80,7 +81,7 @@ TEST(SingleLockListTest, EmplaceEraseAndIter) {
|
||||
TEST(SingleLockListTest, IterEmpty) {
|
||||
IntList list;
|
||||
|
||||
KStdVector<int> actual;
|
||||
std_support::vector<int> actual;
|
||||
for (int element : list.LockForIter()) {
|
||||
actual.push_back(element);
|
||||
}
|
||||
@@ -101,7 +102,7 @@ TEST(SingleLockListTest, EraseToEmptyEmplaceAndIter) {
|
||||
list.Emplace(kThird);
|
||||
list.Emplace(kFourth);
|
||||
|
||||
KStdVector<int> actual;
|
||||
std_support::vector<int> actual;
|
||||
for (int element : list.LockForIter()) {
|
||||
actual.push_back(element);
|
||||
}
|
||||
@@ -114,8 +115,8 @@ TEST(SingleLockListTest, ConcurrentEmplace) {
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> readyCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
KStdVector<int> expected;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
std_support::vector<int> expected;
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
expected.push_back(i);
|
||||
threads.emplace_back([i, &list, &canStart, &readyCount]() {
|
||||
@@ -131,7 +132,7 @@ TEST(SingleLockListTest, ConcurrentEmplace) {
|
||||
canStart = true;
|
||||
threads.clear();
|
||||
|
||||
KStdVector<int> actual;
|
||||
std_support::vector<int> actual;
|
||||
for (int element : list.LockForIter()) {
|
||||
actual.push_back(element);
|
||||
}
|
||||
@@ -142,14 +143,14 @@ TEST(SingleLockListTest, ConcurrentEmplace) {
|
||||
TEST(SingleLockListTest, ConcurrentErase) {
|
||||
IntList list;
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
KStdVector<IntList::Node*> items;
|
||||
std_support::vector<IntList::Node*> items;
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
items.push_back(list.Emplace(i));
|
||||
}
|
||||
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> readyCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
for (auto* item : items) {
|
||||
threads.emplace_back([item, &list, &canStart, &readyCount]() {
|
||||
++readyCount;
|
||||
@@ -164,7 +165,7 @@ TEST(SingleLockListTest, ConcurrentErase) {
|
||||
canStart = true;
|
||||
threads.clear();
|
||||
|
||||
KStdVector<int> actual;
|
||||
std_support::vector<int> actual;
|
||||
for (int element : list.LockForIter()) {
|
||||
actual.push_back(element);
|
||||
}
|
||||
@@ -177,8 +178,8 @@ TEST(SingleLockListTest, IterWhileConcurrentEmplace) {
|
||||
constexpr int kStartCount = 50;
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
|
||||
KStdDeque<int> expectedBefore;
|
||||
KStdVector<int> expectedAfter;
|
||||
std_support::deque<int> expectedBefore;
|
||||
std_support::vector<int> expectedAfter;
|
||||
for (int i = 0; i < kStartCount; ++i) {
|
||||
expectedBefore.push_front(i);
|
||||
expectedAfter.push_back(i);
|
||||
@@ -187,7 +188,7 @@ TEST(SingleLockListTest, IterWhileConcurrentEmplace) {
|
||||
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> startedCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
int j = i + kStartCount;
|
||||
expectedAfter.push_back(j);
|
||||
@@ -199,7 +200,7 @@ TEST(SingleLockListTest, IterWhileConcurrentEmplace) {
|
||||
});
|
||||
}
|
||||
|
||||
KStdVector<int> actualBefore;
|
||||
std_support::vector<int> actualBefore;
|
||||
{
|
||||
auto iter = list.LockForIter();
|
||||
canStart = true;
|
||||
@@ -215,7 +216,7 @@ TEST(SingleLockListTest, IterWhileConcurrentEmplace) {
|
||||
|
||||
EXPECT_THAT(actualBefore, testing::ElementsAreArray(expectedBefore));
|
||||
|
||||
KStdVector<int> actualAfter;
|
||||
std_support::vector<int> actualAfter;
|
||||
for (int element : list.LockForIter()) {
|
||||
actualAfter.push_back(element);
|
||||
}
|
||||
@@ -227,8 +228,8 @@ TEST(SingleLockListTest, IterWhileConcurrentErase) {
|
||||
IntList list;
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
|
||||
KStdDeque<int> expectedBefore;
|
||||
KStdVector<IntList::Node*> items;
|
||||
std_support::deque<int> expectedBefore;
|
||||
std_support::vector<IntList::Node*> items;
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
expectedBefore.push_front(i);
|
||||
items.push_back(list.Emplace(i));
|
||||
@@ -236,7 +237,7 @@ TEST(SingleLockListTest, IterWhileConcurrentErase) {
|
||||
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> startedCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
for (auto* item : items) {
|
||||
threads.emplace_back([item, &list, &canStart, &startedCount]() {
|
||||
while (!canStart) {
|
||||
@@ -246,7 +247,7 @@ TEST(SingleLockListTest, IterWhileConcurrentErase) {
|
||||
});
|
||||
}
|
||||
|
||||
KStdVector<int> actualBefore;
|
||||
std_support::vector<int> actualBefore;
|
||||
{
|
||||
auto iter = list.LockForIter();
|
||||
canStart = true;
|
||||
@@ -262,7 +263,7 @@ TEST(SingleLockListTest, IterWhileConcurrentErase) {
|
||||
|
||||
EXPECT_THAT(actualBefore, testing::ElementsAreArray(expectedBefore));
|
||||
|
||||
KStdVector<int> actualAfter;
|
||||
std_support::vector<int> actualAfter;
|
||||
for (int element : list.LockForIter()) {
|
||||
actualAfter.push_back(element);
|
||||
}
|
||||
@@ -274,10 +275,10 @@ TEST(SingleLockListTest, LockAndEmplace) {
|
||||
SingleLockList<int, std::recursive_mutex> list;
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
|
||||
KStdVector<ScopedThread> threads;
|
||||
KStdVector<int> actualLocked;
|
||||
KStdVector<int> actualUnlocked;
|
||||
KStdVector<int> expectedUnlocked;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
std_support::vector<int> actualLocked;
|
||||
std_support::vector<int> actualUnlocked;
|
||||
std_support::vector<int> expectedUnlocked;
|
||||
for (int i = 0; i < kThreadCount; i++) {
|
||||
expectedUnlocked.push_back(i);
|
||||
}
|
||||
@@ -313,11 +314,11 @@ TEST(SingleLockListTest, LockAndErase) {
|
||||
SingleLockList<int, std::recursive_mutex> list;
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
|
||||
KStdVector<SingleLockList<int, std::recursive_mutex>::Node*> items;
|
||||
KStdVector<int> expectedLocked;
|
||||
KStdVector<ScopedThread> threads;
|
||||
KStdVector<int> actualLocked;
|
||||
KStdVector<int> actualUnlocked;
|
||||
std_support::vector<SingleLockList<int, std::recursive_mutex>::Node*> items;
|
||||
std_support::vector<int> expectedLocked;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
std_support::vector<int> actualLocked;
|
||||
std_support::vector<int> actualUnlocked;
|
||||
std::atomic<int> startedCount(0);
|
||||
|
||||
for (int i = 0; i < kThreadCount; i++) {
|
||||
@@ -376,7 +377,7 @@ TEST(SingleLockListTest, PinnedType) {
|
||||
|
||||
list.Erase(itemNode);
|
||||
|
||||
KStdVector<PinnedType*> actualAfter;
|
||||
std_support::vector<PinnedType*> actualAfter;
|
||||
for (auto& element : list.LockForIter()) {
|
||||
actualAfter.push_back(&element);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "ScopedThread.hpp"
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/Deque.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
|
||||
@@ -101,7 +101,7 @@ private:
|
||||
|
||||
std::condition_variable workCV_;
|
||||
std::mutex workMutex_;
|
||||
KStdDeque<std::packaged_task<void()>> queue_;
|
||||
std_support::deque<std::packaged_task<void()>> queue_;
|
||||
bool shutdownRequested_ = false;
|
||||
|
||||
ScopedThread thread_;
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
#include "KAssert.h"
|
||||
#include "TestSupport.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -60,7 +62,7 @@ TEST(SingleThreadExecutorTest, ContextThreadBound) {
|
||||
createdContext = &context;
|
||||
createdThread = std::this_thread::get_id();
|
||||
});
|
||||
auto executor = ::make_unique<SingleThreadExecutor<PinnedContext>>();
|
||||
auto executor = std_support::make_unique<SingleThreadExecutor<PinnedContext>>();
|
||||
// Make sure context is created.
|
||||
executor->context();
|
||||
testing::Mock::VerifyAndClearExpectations(&mocks.ctorMock);
|
||||
@@ -127,7 +129,7 @@ TEST(SingleThreadExecutorTest, execute) {
|
||||
|
||||
TEST(SingleThreadExecutorTest, DropExecutorWithTasks) {
|
||||
struct Context {};
|
||||
auto executor = make_unique<SingleThreadExecutor<Context>>();
|
||||
auto executor = std_support::make_unique<SingleThreadExecutor<Context>>();
|
||||
|
||||
std::mutex taskMutex;
|
||||
testing::StrictMock<testing::MockFunction<void()>> task;
|
||||
@@ -141,7 +143,7 @@ TEST(SingleThreadExecutorTest, DropExecutorWithTasks) {
|
||||
auto future = executor->execute(task.AsStdFunction());
|
||||
while (!taskStarted) {}
|
||||
|
||||
KStdVector<std::pair<std::future<void>, bool>> newTasks;
|
||||
std_support::vector<std::pair<std::future<void>, bool>> newTasks;
|
||||
constexpr size_t tasksCount = 100;
|
||||
for (size_t i = 0; i < tasksCount; ++i) {
|
||||
newTasks.push_back(std::make_pair(executor->execute([&newTasks, i] { newTasks[i].second = true; }), false));
|
||||
@@ -165,14 +167,14 @@ TEST(SingleThreadExecutorTest, DropExecutorWithTasks) {
|
||||
|
||||
TEST(SingleThreadExecutorTest, ExecuteFromManyThreads) {
|
||||
struct Context {
|
||||
KStdVector<int> result;
|
||||
std_support::vector<int> result;
|
||||
};
|
||||
SingleThreadExecutor<Context> executor;
|
||||
|
||||
std::atomic_bool canStart = false;
|
||||
|
||||
KStdVector<int> expected;
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<int> expected;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
for (int i = 0; i < kDefaultThreadCount; ++i) {
|
||||
expected.push_back(i);
|
||||
threads.emplace_back([&, i] {
|
||||
|
||||
@@ -90,7 +90,7 @@ int getSourceInfo(void* symbol, SourceInfo *result, int result_len) {
|
||||
|
||||
// TODO: this implementation is just a hack, e.g. the result is inexact;
|
||||
// however it is better to have an inexact stacktrace than not to have any.
|
||||
NO_INLINE KStdVector<void*> kotlin::internal::GetCurrentStackTrace(size_t skipFrames) noexcept {
|
||||
NO_INLINE std_support::vector<void*> kotlin::internal::GetCurrentStackTrace(size_t skipFrames) noexcept {
|
||||
NativeOrUnregisteredThreadGuard guard(true);
|
||||
#if KONAN_NO_BACKTRACE
|
||||
return {};
|
||||
@@ -104,7 +104,7 @@ NO_INLINE KStdVector<void*> kotlin::internal::GetCurrentStackTrace(size_t skipFr
|
||||
const size_t kSkipFrames = 1 + skipFrames;
|
||||
#endif
|
||||
|
||||
KStdVector<void*> result;
|
||||
std_support::vector<void*> result;
|
||||
#if USE_GCC_UNWIND
|
||||
size_t depth = 0;
|
||||
_Unwind_Backtrace(depthCountCallback, static_cast<void*>(&depth));
|
||||
@@ -238,15 +238,15 @@ KNativePtr adjustAddressForSourceInfo(KNativePtr address) {
|
||||
KNativePtr adjustAddressForSourceInfo(KNativePtr address) { return address; }
|
||||
#endif
|
||||
|
||||
KStdVector<KStdString> kotlin::GetStackTraceStrings(std_support::span<void* const> stackTrace) noexcept {
|
||||
std_support::vector<std_support::string> kotlin::GetStackTraceStrings(std_support::span<void* const> stackTrace) noexcept {
|
||||
NativeOrUnregisteredThreadGuard guard(true);
|
||||
#if KONAN_NO_BACKTRACE
|
||||
KStdVector<KStdString> strings;
|
||||
std_support::vector<std_support::string> strings;
|
||||
strings.push_back("<UNIMPLEMENTED>");
|
||||
return strings;
|
||||
#else
|
||||
size_t size = stackTrace.size();
|
||||
KStdVector<KStdString> strings;
|
||||
std_support::vector<std_support::string> strings;
|
||||
strings.reserve(size);
|
||||
if (size > 0) {
|
||||
SourceInfo buffer[10]; // outside of the loop to avoid calling constructors and destructors each time
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
|
||||
#include "std_support/Span.hpp"
|
||||
#include "Memory.h"
|
||||
#include "Types.h"
|
||||
#include "std_support/String.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
|
||||
namespace internal {
|
||||
|
||||
NO_INLINE KStdVector<void*> GetCurrentStackTrace(size_t skipFrames) noexcept;
|
||||
NO_INLINE std_support::vector<void*> GetCurrentStackTrace(size_t skipFrames) noexcept;
|
||||
NO_INLINE size_t GetCurrentStackTrace(size_t skipFrames, std_support::span<void*> buffer) noexcept;
|
||||
|
||||
enum class StackTraceCapacityKind {
|
||||
@@ -181,19 +182,18 @@ public:
|
||||
|
||||
struct TestSupport : private Pinned {
|
||||
static StackTrace constructFrom(std::initializer_list<void*> values) {
|
||||
KStdVector<void*> traceElements(values);
|
||||
std_support::vector<void*> traceElements(values);
|
||||
return StackTrace(std::move(traceElements));
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
explicit StackTrace(KStdVector<void*>&& buffer) noexcept : buffer_(buffer) {}
|
||||
explicit StackTrace(std_support::vector<void*>&& buffer) noexcept : buffer_(buffer) {}
|
||||
|
||||
KStdVector<void*> buffer_;
|
||||
std_support::vector<void*> buffer_;
|
||||
};
|
||||
|
||||
|
||||
KStdVector<KStdString> GetStackTraceStrings(std_support::span<void* const> stackTrace) noexcept;
|
||||
std_support::vector<std_support::string> GetStackTraceStrings(std_support::span<void* const> stackTrace) noexcept;
|
||||
|
||||
// It's not always safe to extract SourceInfo during unhandled exception termination.
|
||||
void DisallowSourceInfo();
|
||||
@@ -214,4 +214,4 @@ struct std::hash<kotlin::StackTrace<Capacity>> {
|
||||
}
|
||||
};
|
||||
|
||||
#endif // RUNTIME_STACK_TRACE_H
|
||||
#endif // RUNTIME_STACK_TRACE_H
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Common.h"
|
||||
#include "Porting.h"
|
||||
#include "TestSupport.hpp"
|
||||
#include "std_support/UnorderedSet.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -187,7 +188,7 @@ TEST(StackTraceTest, StackAllocatedDeepTraceWithEnoughCapacity) {
|
||||
TEST(StackTraceTest, Iteration) {
|
||||
auto stackTrace = GetStackTrace2();
|
||||
|
||||
KStdVector<void*> actualAddresses;
|
||||
std_support::vector<void*> actualAddresses;
|
||||
for (auto addr : stackTrace) {
|
||||
actualAddresses.push_back(addr);
|
||||
}
|
||||
@@ -203,7 +204,7 @@ TEST(StackTraceTest, Iteration) {
|
||||
TEST(StackTraceTest, StackAllocatedIteration) {
|
||||
auto stackTrace = GetStackTrace2<2>();
|
||||
|
||||
KStdVector<void*> actualAddresses;
|
||||
std_support::vector<void*> actualAddresses;
|
||||
for (auto addr : stackTrace) {
|
||||
actualAddresses.push_back(addr);
|
||||
}
|
||||
@@ -219,7 +220,7 @@ TEST(StackTraceTest, StackAllocatedIteration) {
|
||||
TEST(StackTraceTest, IndexedAccess) {
|
||||
auto stackTrace = GetStackTrace2();
|
||||
|
||||
KStdVector<void*> actualAddresses;
|
||||
std_support::vector<void*> actualAddresses;
|
||||
for (size_t i = 0; i < stackTrace.size(); i++) {
|
||||
actualAddresses.push_back(stackTrace[i]);
|
||||
}
|
||||
@@ -233,7 +234,7 @@ TEST(StackTraceTest, IndexedAccess) {
|
||||
TEST(StackTraceTest, StackAllocatedIndexedAccess) {
|
||||
auto stackTrace = GetStackTrace2<2>();
|
||||
|
||||
KStdVector<void*> actualAddresses;
|
||||
std_support::vector<void*> actualAddresses;
|
||||
for (size_t i = 0; i < stackTrace.size(); i++) {
|
||||
actualAddresses.push_back(stackTrace[i]);
|
||||
}
|
||||
@@ -334,7 +335,7 @@ TEST(StackTraceTest, StackAllocatedEqualsAndHash) {
|
||||
|
||||
TEST(StackTraceTest, StoreInHashSet) {
|
||||
constexpr size_t capacity = 10;
|
||||
KStdUnorderedSet<StackTrace<capacity>> set;
|
||||
std_support::unordered_set<StackTrace<capacity>> set;
|
||||
StackTrace<capacity> empty;
|
||||
StackTrace<capacity> trace1 = GetStackTrace1<capacity>();
|
||||
StackTrace<capacity> trace2 = GetStackTrace2<capacity>();
|
||||
@@ -359,7 +360,7 @@ TEST(StackTraceTest, StoreInHashSet) {
|
||||
}
|
||||
|
||||
TEST(StackTraceTest, StackAllocatedStoreInHashSet) {
|
||||
KStdUnorderedSet<StackTrace<>> set;
|
||||
std_support::unordered_set<StackTrace<>> set;
|
||||
StackTrace<> empty;
|
||||
StackTrace<> trace1 = GetStackTrace1();
|
||||
StackTrace<> trace2 = GetStackTrace2();
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
namespace test_support {
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
explicit ScopedMockFunction(testing::MockFunction<F>** globalMockLocation) : globalMockLocation_(globalMockLocation) {
|
||||
RuntimeCheck(globalMockLocation != nullptr, "ScopedMockFunction needs non-null global mock location");
|
||||
RuntimeCheck(*globalMockLocation == nullptr, "ScopedMockFunction needs null global mock");
|
||||
mock_ = make_unique<Mock>();
|
||||
mock_ = std_support::make_unique<Mock>();
|
||||
*globalMockLocation_ = mock_.get();
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ public:
|
||||
private:
|
||||
// Can be null if moved-out of.
|
||||
testing::MockFunction<F>** globalMockLocation_;
|
||||
KStdUniquePtr<Mock> mock_;
|
||||
std_support::unique_ptr<Mock> mock_;
|
||||
};
|
||||
|
||||
template<bool Strict = true>
|
||||
@@ -93,4 +94,4 @@ ScopedMockFunction<void(KRef), Strict> ScopedKotlin_runUnhandledExceptionHookMoc
|
||||
}
|
||||
|
||||
} // namespace test_support
|
||||
} // namespace kotlin
|
||||
} // namespace kotlin
|
||||
|
||||
@@ -19,19 +19,9 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "Common.h"
|
||||
#include "Memory.h"
|
||||
#include "TypeInfo.h"
|
||||
#include "std_support/Deque.hpp"
|
||||
#include "std_support/List.hpp"
|
||||
#include "std_support/Map.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
#include "std_support/Set.hpp"
|
||||
#include "std_support/String.hpp"
|
||||
#include "std_support/UnorderedMap.hpp"
|
||||
#include "std_support/UnorderedSet.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
// Note that almost all types are signed.
|
||||
typedef bool KBoolean;
|
||||
@@ -55,26 +45,6 @@ typedef ObjHeader* KRef;
|
||||
typedef const ObjHeader* KConstRef;
|
||||
typedef const ArrayHeader* KString;
|
||||
|
||||
// TODO: Remove these typedefs. Use std_support directly everywhere.
|
||||
using KStdString = kotlin::std_support::string;
|
||||
template <typename Value>
|
||||
using KStdDeque = kotlin::std_support::deque<Value>;
|
||||
template <typename Key, typename Value>
|
||||
using KStdUnorderedMap = kotlin::std_support::unordered_map<Key, Value>;
|
||||
template <typename Value>
|
||||
using KStdUnorderedSet = kotlin::std_support::unordered_set<Value>;
|
||||
template <typename Value, typename Compare = std::less<Value>>
|
||||
using KStdOrderedMultiset = kotlin::std_support::multiset<Value, Compare>;
|
||||
template <typename Key, typename Value>
|
||||
using KStdOrderedMap = kotlin::std_support::map<Key, Value>;
|
||||
template <typename Value>
|
||||
using KStdVector = kotlin::std_support::vector<Value>;
|
||||
template <typename Value>
|
||||
using KStdList = kotlin::std_support::list<Value>;
|
||||
template <typename Value>
|
||||
using KStdUniquePtr = kotlin::std_support::unique_ptr<Value>;
|
||||
using kotlin::std_support::make_unique;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "PthreadUtils.h"
|
||||
#endif
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "Exceptions.h"
|
||||
#include "KAssert.h"
|
||||
#include "Memory.h"
|
||||
@@ -35,6 +34,11 @@
|
||||
#include "Runtime.h"
|
||||
#include "Types.h"
|
||||
#include "Worker.h"
|
||||
#include "std_support/Deque.hpp"
|
||||
#include "std_support/New.hpp"
|
||||
#include "std_support/Set.hpp"
|
||||
#include "std_support/UnorderedMap.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -133,7 +137,7 @@ struct JobCompare {
|
||||
// Using multiset instead of regular set, because we compare the jobs only by `whenExecute`.
|
||||
// So if `whenExecute` of two different jobs is the same, the jobs are considered equivalent,
|
||||
// and set would simply drop one of them.
|
||||
typedef KStdOrderedMultiset<Job, JobCompare> DelayedJobSet;
|
||||
typedef std_support::multiset<Job, JobCompare> DelayedJobSet;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -200,7 +204,7 @@ class Worker {
|
||||
|
||||
KInt id_;
|
||||
WorkerKind kind_;
|
||||
KStdDeque<Job> queue_;
|
||||
std_support::deque<Job> queue_;
|
||||
DelayedJobSet delayed_;
|
||||
// Stable pointer with worker's name.
|
||||
KNativePtr name_;
|
||||
@@ -359,7 +363,7 @@ class State {
|
||||
Worker* worker = nullptr;
|
||||
{
|
||||
Locker locker(&lock_);
|
||||
worker = konanConstructInstance<Worker>(nextWorkerId(), exceptionHandling, customName, kind);
|
||||
worker = new (std_support::kalloc) Worker(nextWorkerId(), exceptionHandling, customName, kind);
|
||||
if (worker == nullptr) return nullptr;
|
||||
workers_[worker->id()] = worker;
|
||||
}
|
||||
@@ -392,7 +396,7 @@ class State {
|
||||
}
|
||||
}
|
||||
GC_UnregisterWorker(worker);
|
||||
konanDestructInstance(worker);
|
||||
std_support::kdelete(worker);
|
||||
}
|
||||
|
||||
Future* addJobToWorkerUnlocked(
|
||||
@@ -405,7 +409,7 @@ class State {
|
||||
if (it == workers_.end()) return nullptr;
|
||||
worker = it->second;
|
||||
|
||||
future = konanConstructInstance<Future>(nextFutureId());
|
||||
future = new (std_support::kalloc) Future(nextFutureId());
|
||||
futures_[future->id()] = future;
|
||||
|
||||
Job job;
|
||||
@@ -507,7 +511,7 @@ class State {
|
||||
auto it = futures_.find(id);
|
||||
if (it != futures_.end()) {
|
||||
futures_.erase(it);
|
||||
konanDestructInstance(future);
|
||||
std_support::kdelete(future);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,7 +585,7 @@ class State {
|
||||
|
||||
template <typename F>
|
||||
void waitNativeWorkersTerminationUnlocked(bool checkLeaks, F waitForWorker) {
|
||||
KStdVector<std::pair<KInt, pthread_t>> workersToWait;
|
||||
std_support::vector<std::pair<KInt, pthread_t>> workersToWait;
|
||||
{
|
||||
Locker locker(&lock_);
|
||||
|
||||
@@ -628,9 +632,9 @@ class State {
|
||||
private:
|
||||
pthread_mutex_t lock_;
|
||||
pthread_cond_t cond_;
|
||||
KStdUnorderedMap<KInt, Future*> futures_;
|
||||
KStdUnorderedMap<KInt, Worker*> workers_;
|
||||
KStdUnorderedMap<KInt, pthread_t> terminating_native_workers_;
|
||||
std_support::unordered_map<KInt, Future*> futures_;
|
||||
std_support::unordered_map<KInt, Worker*> workers_;
|
||||
std_support::unordered_map<KInt, pthread_t> terminating_native_workers_;
|
||||
KInt currentWorkerId_;
|
||||
KInt currentFutureId_;
|
||||
KInt currentVersion_;
|
||||
@@ -643,11 +647,11 @@ State* theState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
State* result = konanConstructInstance<State>();
|
||||
State* result = new (std_support::kalloc) State();
|
||||
|
||||
State* old = __sync_val_compare_and_swap(&state, nullptr, result);
|
||||
if (old != nullptr) {
|
||||
konanDestructInstance(result);
|
||||
std_support::kdelete(result);
|
||||
// Someone else inited this data.
|
||||
return old;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
|
||||
#include "WorkerBoundReference.h"
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "Memory.h"
|
||||
#include "MemorySharedRefs.hpp"
|
||||
#include "std_support/New.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -27,7 +29,7 @@ RUNTIME_NOTHROW void DisposeWorkerBoundReference(KRef thiz) {
|
||||
// Can be null if WorkerBoundReference wasn't frozen.
|
||||
if (auto* holder = asWorkerBoundReference(thiz)->holder) {
|
||||
holder->dispose();
|
||||
konanDestructInstance(holder);
|
||||
std_support::kdelete(holder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +43,9 @@ RUNTIME_NOTHROW void WorkerBoundReferenceFreezeHook(KRef thiz) {
|
||||
extern "C" {
|
||||
|
||||
KNativePtr Kotlin_WorkerBoundReference_create(KRef value) {
|
||||
auto* holder = konanConstructInstance<KRefSharedHolder>();
|
||||
holder->init(value);
|
||||
return holder;
|
||||
auto* holder = new (std_support::kalloc) KRefSharedHolder();
|
||||
holder->init(value);
|
||||
return holder;
|
||||
}
|
||||
|
||||
OBJ_GETTER(Kotlin_WorkerBoundReference_deref, KNativePtr holder) {
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
#include "../KotlinMath.h"
|
||||
#include "../ReturnSlot.h"
|
||||
#include "../DoubleConversions.h"
|
||||
#include "../std_support/CStdlib.hpp"
|
||||
#include "../std_support/String.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
#if defined(LINUX) || defined(FREEBSD) || defined(ZOS) || defined(MACOSX) || defined(AIX)
|
||||
#define USE_LL
|
||||
@@ -177,8 +181,8 @@ static const KDouble tens[] = {
|
||||
}
|
||||
#define ERROR_OCCURED(x) (HIGH_I32_FROM_VAR(x) < 0)
|
||||
|
||||
#define allocateU64(x, n) if (!((x) = (U_64*) konan::calloc(1, (n) * sizeof(U_64)))) goto OutOfMemory;
|
||||
#define release(r) if ((r)) konan::free((r));
|
||||
#define allocateU64(x, n) if (!((x) = (U_64*) std_support::calloc(1, (n) * sizeof(U_64)))) goto OutOfMemory;
|
||||
#define release(r) if ((r)) std_support::free((r));
|
||||
|
||||
/*NB the Number converter methods are synchronized so it is possible to
|
||||
*have global data for use by bigIntDigitGenerator */
|
||||
@@ -654,7 +658,7 @@ OutOfMemory:
|
||||
KDouble Kotlin_native_FloatingPointParser_parseDoubleImpl (KString s, KInt e)
|
||||
{
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(s, 0);
|
||||
KStdString utf8;
|
||||
std_support::string utf8;
|
||||
utf8.reserve(s->count_);
|
||||
TRY_CATCH(utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)),
|
||||
utf8::unchecked::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)),
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
#include "../Natives.h"
|
||||
#include "../Porting.h"
|
||||
#include "../utf8.h"
|
||||
#include "../std_support/CStdlib.hpp"
|
||||
#include "../std_support/String.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
#if defined(LINUX) || defined(FREEBSD) || defined(MACOSX) || defined(ZOS) || defined(AIX)
|
||||
#define USE_LL
|
||||
@@ -117,8 +121,8 @@ static const U_32 tens[] = {
|
||||
} \
|
||||
}
|
||||
|
||||
#define allocateU64(x, n) if (!((x) = (U_64*) konan::calloc(1, (n) * sizeof(U_64)))) goto OutOfMemory;
|
||||
#define release(r) if ((r)) konan::free((r));
|
||||
#define allocateU64(x, n) if (!((x) = (U_64*) std_support::calloc(1, (n) * sizeof(U_64)))) goto OutOfMemory;
|
||||
#define release(r) if ((r)) std_support::free((r));
|
||||
|
||||
KFloat createFloat(const char *s, KInt e) {
|
||||
/* assumes s is a null terminated string with at least one
|
||||
@@ -542,7 +546,7 @@ extern "C" KFloat
|
||||
Kotlin_native_FloatingPointParser_parseFloatImpl(KString s, KInt e)
|
||||
{
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(s, 0);
|
||||
KStdString utf8;
|
||||
std_support::string utf8;
|
||||
utf8.reserve(s->count_);
|
||||
TRY_CATCH(utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)),
|
||||
utf8::unchecked::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)),
|
||||
|
||||
@@ -15,14 +15,6 @@ void* operator new(std::size_t count, kotlin::std_support::kalloc_t) noexcept {
|
||||
return std_support::calloc(1, count);
|
||||
}
|
||||
|
||||
void* operator new[](std::size_t count, kotlin::std_support::kalloc_t) noexcept {
|
||||
return std_support::calloc(1, count);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr, kotlin::std_support::kalloc_t) noexcept {
|
||||
std_support::free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr, kotlin::std_support::kalloc_t) noexcept {
|
||||
std_support::free(ptr);
|
||||
}
|
||||
|
||||
@@ -18,9 +18,7 @@ inline constexpr kalloc_t kalloc = kotlin::std_support::kalloc_t{};
|
||||
// (also requires removing `-fno-aligned-allocation` compiler flag).
|
||||
|
||||
void* operator new(std::size_t count, kotlin::std_support::kalloc_t) noexcept;
|
||||
void* operator new[](std::size_t count, kotlin::std_support::kalloc_t) noexcept;
|
||||
void operator delete(void* ptr, kotlin::std_support::kalloc_t) noexcept;
|
||||
void operator delete[](void* ptr, kotlin::std_support::kalloc_t) noexcept;
|
||||
|
||||
namespace kotlin::std_support {
|
||||
|
||||
|
||||
@@ -40,16 +40,6 @@ TEST(NewTest, NewDelete) {
|
||||
std_support::kdelete(ptr);
|
||||
}
|
||||
|
||||
TEST(NewTest, NewDeleteArray) {
|
||||
Class* ptr = new (std_support::kalloc) Class[13];
|
||||
EXPECT_THAT(ptr[3].x(), 17);
|
||||
std_support::kdelete(ptr);
|
||||
}
|
||||
|
||||
TEST(NewTest, NewThrows) {
|
||||
EXPECT_THROW(new (std_support::kalloc) ClassThrows(42), int);
|
||||
}
|
||||
|
||||
TEST(NewTest, NewThrowsArray) {
|
||||
EXPECT_THROW(new (std_support::kalloc) ClassThrows[13], int);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "ThreadData.hpp"
|
||||
#include "ThreadRegistry.hpp"
|
||||
#include "ExecFormat.h"
|
||||
#include "std_support/UnorderedSet.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -314,7 +315,7 @@ public:
|
||||
~KnownFunctionChecker() = delete;
|
||||
|
||||
private:
|
||||
KStdUnorderedSet<const void*> known_functions_;
|
||||
std_support::unordered_set<const void*> known_functions_;
|
||||
std::string_view good_names_copy_[sizeof(Kotlin_callsCheckerGoodFunctionNames) / sizeof(Kotlin_callsCheckerGoodFunctionNames[0])];
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "TestSupport.hpp"
|
||||
#include "ThreadData.hpp"
|
||||
#include "Types.h"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -19,11 +20,11 @@ namespace {
|
||||
|
||||
class ExceptionObjHolderTest : public ::testing::Test {
|
||||
public:
|
||||
static KStdVector<ObjHeader*> Collect(mm::ThreadData& threadData) {
|
||||
static std_support::vector<ObjHeader*> Collect(mm::ThreadData& threadData) {
|
||||
auto& stableRefs = mm::StableRefRegistry::Instance();
|
||||
stableRefs.ProcessThread(&threadData);
|
||||
stableRefs.ProcessDeletions();
|
||||
KStdVector<ObjHeader*> result;
|
||||
std_support::vector<ObjHeader*> result;
|
||||
for (const auto& obj : stableRefs.LockForIter()) {
|
||||
result.push_back(obj);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "Memory.h"
|
||||
#include "TypeInfo.h"
|
||||
#include "Utils.hpp"
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "Natives.h"
|
||||
#include "ObjectTraversal.hpp"
|
||||
#include "Types.h"
|
||||
#include "std_support/UnorderedSet.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -29,10 +31,10 @@ bool mm::IsFrozen(const ObjHeader* object) noexcept {
|
||||
ObjHeader* mm::FreezeSubgraph(ObjHeader* root) noexcept {
|
||||
if (IsFrozen(root)) return nullptr;
|
||||
|
||||
KStdVector<ObjHeader*> objects;
|
||||
KStdVector<ObjHeader*> stack;
|
||||
std_support::vector<ObjHeader*> objects;
|
||||
std_support::vector<ObjHeader*> stack;
|
||||
// TODO: This may be a suboptimal container for the job.
|
||||
KStdUnorderedSet<ObjHeader*> visited;
|
||||
std_support::unordered_set<ObjHeader*> visited;
|
||||
stack.push_back(root);
|
||||
while (!stack.empty()) {
|
||||
ObjHeader* object = stack.back();
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
void ProcessThread(mm::ThreadData* threadData) noexcept;
|
||||
|
||||
// Lock registry for safe iteration.
|
||||
// TODO: Iteration over `globals_` will be slow, because it's `KStdList` collected at different times from
|
||||
// TODO: Iteration over `globals_` will be slow, because it's `std_support::list` collected at different times from
|
||||
// different threads, and so the nodes are all over the memory. Use metrics to understand how
|
||||
// much of a problem is it.
|
||||
Iterable LockForIter() noexcept { return globals_.LockForIter(); }
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "TestSupport.hpp"
|
||||
#include "ThreadData.hpp"
|
||||
#include "Types.h"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -200,10 +201,10 @@ TEST_F(InitSingletonTest, InitSingletonConcurrent) {
|
||||
constexpr size_t kThreadCount = kDefaultThreadCount;
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<size_t> readyCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
ObjHeader* location = nullptr;
|
||||
KStdVector<ObjHeader*> stackLocations(kThreadCount, nullptr);
|
||||
KStdVector<ObjHeader*> actual(kThreadCount, nullptr);
|
||||
std_support::vector<ObjHeader*> stackLocations(kThreadCount, nullptr);
|
||||
std_support::vector<ObjHeader*> actual(kThreadCount, nullptr);
|
||||
|
||||
for (size_t i = 0; i < kThreadCount; ++i) {
|
||||
threads.emplace_back([this, i, &location, &stackLocations, &actual, &readyCount, &canStart]() {
|
||||
@@ -234,10 +235,10 @@ TEST_F(InitSingletonTest, InitSingletonConcurrentFailing) {
|
||||
constexpr size_t kThreadCount = kDefaultThreadCount;
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<size_t> readyCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
constexpr int kException = 42;
|
||||
ObjHeader* location = nullptr;
|
||||
KStdVector<ObjHeader*> stackLocations(kThreadCount, nullptr);
|
||||
std_support::vector<ObjHeader*> stackLocations(kThreadCount, nullptr);
|
||||
|
||||
for (size_t i = 0; i < kThreadCount; ++i) {
|
||||
threads.emplace_back([this, i, &location, &stackLocations, &readyCount, &canStart]() {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include "Alignment.hpp"
|
||||
#include "Alloc.h"
|
||||
#include "FinalizerHooks.hpp"
|
||||
#include "Memory.h"
|
||||
#include "Mutex.hpp"
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "ScopedThread.hpp"
|
||||
#include "TestSupport.hpp"
|
||||
#include "Types.h"
|
||||
#include "std_support/CStdlib.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -39,8 +41,8 @@ template <typename Storage>
|
||||
using Consumer = typename Storage::Consumer;
|
||||
|
||||
template <size_t DataAlignment>
|
||||
KStdVector<void*> Collect(ObjectFactoryStorage<DataAlignment>& storage) {
|
||||
KStdVector<void*> result;
|
||||
std_support::vector<void*> Collect(ObjectFactoryStorage<DataAlignment>& storage) {
|
||||
std_support::vector<void*> result;
|
||||
for (auto& node : storage.LockForIter()) {
|
||||
result.push_back(node.Data());
|
||||
}
|
||||
@@ -48,8 +50,8 @@ KStdVector<void*> Collect(ObjectFactoryStorage<DataAlignment>& storage) {
|
||||
}
|
||||
|
||||
template <typename T, size_t DataAlignment>
|
||||
KStdVector<T> Collect(ObjectFactoryStorage<DataAlignment>& storage) {
|
||||
KStdVector<T> result;
|
||||
std_support::vector<T> Collect(ObjectFactoryStorage<DataAlignment>& storage) {
|
||||
std_support::vector<T> result;
|
||||
for (auto& node : storage.LockForIter()) {
|
||||
result.push_back(*static_cast<T*>(node.Data()));
|
||||
}
|
||||
@@ -57,8 +59,8 @@ KStdVector<T> Collect(ObjectFactoryStorage<DataAlignment>& storage) {
|
||||
}
|
||||
|
||||
template <typename T, size_t DataAlignment>
|
||||
KStdVector<T> Collect(Consumer<ObjectFactoryStorage<DataAlignment>>& consumer) {
|
||||
KStdVector<T> result;
|
||||
std_support::vector<T> Collect(Consumer<ObjectFactoryStorage<DataAlignment>>& consumer) {
|
||||
std_support::vector<T> result;
|
||||
for (auto& node : consumer) {
|
||||
result.push_back(*static_cast<T*>(node.Data()));
|
||||
}
|
||||
@@ -630,8 +632,8 @@ TEST(ObjectFactoryStorageTest, ConcurrentPublish) {
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> readyCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
KStdVector<int> expected;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
std_support::vector<int> expected;
|
||||
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
expected.push_back(i);
|
||||
@@ -661,8 +663,8 @@ TEST(ObjectFactoryStorageTest, IterWhileConcurrentPublish) {
|
||||
constexpr int kStartCount = 50;
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
|
||||
KStdVector<int> expectedBefore;
|
||||
KStdVector<int> expectedAfter;
|
||||
std_support::vector<int> expectedBefore;
|
||||
std_support::vector<int> expectedAfter;
|
||||
Producer<ObjectFactoryStorageRegular> producer(storage, SimpleAllocator());
|
||||
for (int i = 0; i < kStartCount; ++i) {
|
||||
expectedBefore.push_back(i);
|
||||
@@ -674,7 +676,7 @@ TEST(ObjectFactoryStorageTest, IterWhileConcurrentPublish) {
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> readyCount(0);
|
||||
std::atomic<int> startedCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
int j = i + kStartCount;
|
||||
expectedAfter.push_back(j);
|
||||
@@ -689,7 +691,7 @@ TEST(ObjectFactoryStorageTest, IterWhileConcurrentPublish) {
|
||||
});
|
||||
}
|
||||
|
||||
KStdVector<int> actualBefore;
|
||||
std_support::vector<int> actualBefore;
|
||||
{
|
||||
auto iter = storage.LockForIter();
|
||||
while (readyCount < kThreadCount) {
|
||||
@@ -719,7 +721,7 @@ TEST(ObjectFactoryStorageTest, EraseWhileConcurrentPublish) {
|
||||
constexpr int kStartCount = 50;
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
|
||||
KStdVector<int> expectedAfter;
|
||||
std_support::vector<int> expectedAfter;
|
||||
Producer<ObjectFactoryStorageRegular> producer(storage, SimpleAllocator());
|
||||
for (int i = 0; i < kStartCount; ++i) {
|
||||
if (i % 2 == 0) {
|
||||
@@ -732,7 +734,7 @@ TEST(ObjectFactoryStorageTest, EraseWhileConcurrentPublish) {
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> readyCount(0);
|
||||
std::atomic<int> startedCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
int j = i + kStartCount;
|
||||
expectedAfter.push_back(j);
|
||||
@@ -782,9 +784,9 @@ public:
|
||||
MOCK_METHOD(void*, Alloc, (size_t, size_t));
|
||||
MOCK_METHOD(void, Free, (void*));
|
||||
|
||||
void* DefaultAlloc(size_t size, size_t alignment) { return konanAllocAlignedMemory(size, alignment); }
|
||||
void* DefaultAlloc(size_t size, size_t alignment) { return std_support::aligned_calloc(alignment, 1, size); }
|
||||
|
||||
void DefaultFree(void* instance) { konanFreeMemory(instance); }
|
||||
void DefaultFree(void* instance) { std_support::free(instance); }
|
||||
};
|
||||
|
||||
class GlobalMockAllocator {
|
||||
@@ -1056,7 +1058,7 @@ TEST(ObjectFactoryTest, RunFinalizers) {
|
||||
ObjectFactory::ThreadQueue threadQueue(objectFactory, GlobalMockAllocator());
|
||||
ObjectFactory::FinalizerQueue finalizerQueue;
|
||||
|
||||
KStdVector<ObjHeader*> objects;
|
||||
std_support::vector<ObjHeader*> objects;
|
||||
EXPECT_CALL(allocator, Alloc(_, _)).Times(10);
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
objects.push_back(threadQueue.CreateObject(objectType.typeInfo()));
|
||||
@@ -1089,9 +1091,9 @@ TEST(ObjectFactoryTest, ConcurrentPublish) {
|
||||
constexpr int kThreadCount = kDefaultThreadCount;
|
||||
std::atomic<bool> canStart(false);
|
||||
std::atomic<int> readyCount(0);
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
std::mutex expectedMutex;
|
||||
KStdVector<ObjHeader*> expected;
|
||||
std_support::vector<ObjHeader*> expected;
|
||||
|
||||
EXPECT_CALL(allocator, Alloc(_, _)).Times(kThreadCount);
|
||||
for (int i = 0; i < kThreadCount; ++i) {
|
||||
@@ -1116,7 +1118,7 @@ TEST(ObjectFactoryTest, ConcurrentPublish) {
|
||||
threads.clear();
|
||||
|
||||
auto iter = objectFactory.LockForIter();
|
||||
KStdVector<ObjHeader*> actual;
|
||||
std_support::vector<ObjHeader*> actual;
|
||||
for (auto it = iter.begin(); it != iter.end(); ++it) {
|
||||
actual.push_back(it->GetObjHeader());
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "ShadowStack.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -21,7 +23,7 @@ class StackEntry : private Pinned {
|
||||
public:
|
||||
static_assert(LocalsCount > 0, "Must have at least 1 object on stack");
|
||||
|
||||
explicit StackEntry(mm::ShadowStack& shadowStack) : shadowStack_(shadowStack), value_(make_unique<ObjHeader>()) {
|
||||
explicit StackEntry(mm::ShadowStack& shadowStack) : shadowStack_(shadowStack), value_(std_support::make_unique<ObjHeader>()) {
|
||||
// Fill `locals_` with some values.
|
||||
for (size_t i = 0; i < LocalsCount; ++i) {
|
||||
(*this)[i] = value_.get() + i;
|
||||
@@ -36,7 +38,7 @@ public:
|
||||
|
||||
private:
|
||||
mm::ShadowStack& shadowStack_;
|
||||
KStdUniquePtr<ObjHeader> value_;
|
||||
std_support::unique_ptr<ObjHeader> value_;
|
||||
|
||||
// The following is what the compiler creates on the stack.
|
||||
static inline constexpr int kFrameOverlayCount = sizeof(FrameOverlay) / sizeof(ObjHeader**);
|
||||
@@ -59,7 +61,7 @@ TEST(ThreadRootSetTest, Basic) {
|
||||
|
||||
mm::ThreadRootSet iter(stack, tls);
|
||||
|
||||
KStdVector<mm::ThreadRootSet::Value> actual;
|
||||
std_support::vector<mm::ThreadRootSet::Value> actual;
|
||||
for (auto object : iter) {
|
||||
actual.push_back(object);
|
||||
}
|
||||
@@ -79,7 +81,7 @@ TEST(ThreadRootSetTest, Empty) {
|
||||
|
||||
mm::ThreadRootSet iter(stack, tls);
|
||||
|
||||
KStdVector<mm::ThreadRootSet::Value> actual;
|
||||
std_support::vector<mm::ThreadRootSet::Value> actual;
|
||||
for (auto object : iter) {
|
||||
actual.push_back(object);
|
||||
}
|
||||
@@ -109,7 +111,7 @@ TEST(GlobalRootSetTest, Basic) {
|
||||
|
||||
mm::GlobalRootSet iter(globals, stableRefs);
|
||||
|
||||
KStdVector<mm::GlobalRootSet::Value> actual;
|
||||
std_support::vector<mm::GlobalRootSet::Value> actual;
|
||||
for (auto object : iter) {
|
||||
actual.push_back(object);
|
||||
}
|
||||
@@ -128,7 +130,7 @@ TEST(GlobalRootSetTest, Empty) {
|
||||
|
||||
mm::GlobalRootSet iter(globals, stableRefs);
|
||||
|
||||
KStdVector<mm::GlobalRootSet::Value> actual;
|
||||
std_support::vector<mm::GlobalRootSet::Value> actual;
|
||||
for (auto object : iter) {
|
||||
actual.push_back(object);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "Memory.h"
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/Memory.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
using namespace kotlin;
|
||||
|
||||
@@ -21,7 +23,7 @@ class StackEntry : private Pinned {
|
||||
public:
|
||||
static_assert(ParametersCount + LocalsCount > 0, "Must have at least 1 object on stack");
|
||||
|
||||
explicit StackEntry(mm::ShadowStack& shadowStack) : shadowStack_(shadowStack), value_(make_unique<ObjHeader>()) {
|
||||
explicit StackEntry(mm::ShadowStack& shadowStack) : shadowStack_(shadowStack), value_(std_support::make_unique<ObjHeader>()) {
|
||||
// Fill `locals_` with some values.
|
||||
for (size_t i = 0; i < LocalsCount; ++i) {
|
||||
(*this)[i] = value_.get() + i;
|
||||
@@ -36,7 +38,7 @@ public:
|
||||
|
||||
private:
|
||||
mm::ShadowStack& shadowStack_;
|
||||
KStdUniquePtr<ObjHeader> value_;
|
||||
std_support::unique_ptr<ObjHeader> value_;
|
||||
|
||||
// The following is what the compiler creates on the stack.
|
||||
static inline constexpr int kFrameOverlayCount = sizeof(FrameOverlay) / sizeof(ObjHeader**);
|
||||
@@ -44,8 +46,8 @@ private:
|
||||
std::array<ObjHeader*, kTotalCount> data_;
|
||||
};
|
||||
|
||||
KStdVector<ObjHeader*> Collect(mm::ShadowStack& shadowStack) {
|
||||
KStdVector<ObjHeader*> result;
|
||||
std_support::vector<ObjHeader*> Collect(mm::ShadowStack& shadowStack) {
|
||||
std_support::vector<ObjHeader*> result;
|
||||
for (ObjHeader* local : shadowStack) {
|
||||
result.push_back(local);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
void ProcessDeletions() noexcept;
|
||||
|
||||
// Lock registry for safe iteration.
|
||||
// TODO: Iteration over `stableRefs_` will be slow, because it's `KStdList` collected at different times from
|
||||
// TODO: Iteration over `stableRefs_` will be slow, because it's `std_support::list` collected at different times from
|
||||
// different threads, and so the nodes are all over the memory. Use metrics to understand how
|
||||
// much of a problem is it.
|
||||
Iterable LockForIter() noexcept { return stableRefs_.LockForIter(); }
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
#include "ShadowStack.hpp"
|
||||
#include "StableRefRegistry.hpp"
|
||||
#include "ThreadLocalStorage.hpp"
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "ThreadSuspension.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
struct ObjHeader;
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
|
||||
ShadowStack& shadowStack() noexcept { return shadowStack_; }
|
||||
|
||||
KStdVector<std::pair<ObjHeader**, ObjHeader*>>& initializingSingletons() noexcept { return initializingSingletons_; }
|
||||
std_support::vector<std::pair<ObjHeader**, ObjHeader*>>& initializingSingletons() noexcept { return initializingSingletons_; }
|
||||
|
||||
gc::GC::ThreadData& gc() noexcept { return gc_; }
|
||||
|
||||
@@ -85,7 +85,7 @@ private:
|
||||
ExtraObjectDataFactory::ThreadQueue extraObjectDataThreadQueue_;
|
||||
ShadowStack shadowStack_;
|
||||
gc::GC::ThreadData gc_;
|
||||
KStdVector<std::pair<ObjHeader**, ObjHeader*>> initializingSingletons_;
|
||||
std_support::vector<std::pair<ObjHeader**, ObjHeader*>> initializingSingletons_;
|
||||
ThreadSuspensionData suspensionData_;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "Memory.h"
|
||||
#include "Types.h"
|
||||
#include "Utils.hpp"
|
||||
#include "std_support/UnorderedMap.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
namespace kotlin {
|
||||
namespace mm {
|
||||
@@ -23,7 +25,7 @@ public:
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
explicit Iterator(KStdVector<ObjHeader*>::iterator iterator) : iterator_(iterator) {}
|
||||
explicit Iterator(std_support::vector<ObjHeader*>::iterator iterator) : iterator_(iterator) {}
|
||||
|
||||
ObjHeader** operator*() noexcept { return &*iterator_; }
|
||||
|
||||
@@ -36,7 +38,7 @@ public:
|
||||
bool operator!=(const Iterator& rhs) const noexcept { return iterator_ != rhs.iterator_; }
|
||||
|
||||
private:
|
||||
KStdVector<ObjHeader*>::iterator iterator_;
|
||||
std_support::vector<ObjHeader*>::iterator iterator_;
|
||||
};
|
||||
|
||||
// Add TLS record. Can only be called before `Commit`.
|
||||
@@ -65,9 +67,9 @@ private:
|
||||
|
||||
ObjHeader** Lookup(Entry entry, int index) noexcept;
|
||||
|
||||
KStdVector<ObjHeader*> storage_;
|
||||
// TODO: `KStdUnorderedMap` is probably the wrong container here.
|
||||
KStdUnorderedMap<Key, Entry> map_;
|
||||
std_support::vector<ObjHeader*> storage_;
|
||||
// TODO: `std_support::unordered_map` is probably the wrong container here.
|
||||
std_support::unordered_map<Key, Entry> map_;
|
||||
State state_ = State::kBuilding;
|
||||
int size_ = 0; // Only used in `State::kBuilding`
|
||||
std::pair<Key, Entry> lastKeyAndEntry_;
|
||||
|
||||
@@ -56,12 +56,12 @@ TEST(ThreadLocalStorageTest, Iterate) {
|
||||
tls.AddRecord(&key2, 2);
|
||||
tls.Commit();
|
||||
|
||||
KStdVector<ObjHeader**> expected;
|
||||
std_support::vector<ObjHeader**> expected;
|
||||
expected.push_back(tls.Lookup(&key1, 0));
|
||||
expected.push_back(tls.Lookup(&key2, 0));
|
||||
expected.push_back(tls.Lookup(&key2, 1));
|
||||
|
||||
KStdVector<ObjHeader**> actual;
|
||||
std_support::vector<ObjHeader**> actual;
|
||||
for (auto item : tls) {
|
||||
actual.push_back(item);
|
||||
}
|
||||
@@ -80,12 +80,12 @@ TEST(ThreadLocalStorageTest, AddRecordEmpty) {
|
||||
tls.AddRecord(&key3, 2);
|
||||
tls.Commit();
|
||||
|
||||
KStdVector<ObjHeader**> expected;
|
||||
std_support::vector<ObjHeader**> expected;
|
||||
expected.push_back(tls.Lookup(&key1, 0));
|
||||
expected.push_back(tls.Lookup(&key3, 0));
|
||||
expected.push_back(tls.Lookup(&key3, 1));
|
||||
|
||||
KStdVector<ObjHeader**> actual;
|
||||
std_support::vector<ObjHeader**> actual;
|
||||
for (auto item : tls) {
|
||||
actual.push_back(item);
|
||||
}
|
||||
@@ -101,10 +101,10 @@ TEST(ThreadLocalStorageTest, AddRecordSameSize) {
|
||||
tls.AddRecord(&key1, 1);
|
||||
tls.Commit();
|
||||
|
||||
KStdVector<ObjHeader**> expected;
|
||||
std_support::vector<ObjHeader**> expected;
|
||||
expected.push_back(tls.Lookup(&key1, 0));
|
||||
|
||||
KStdVector<ObjHeader**> actual;
|
||||
std_support::vector<ObjHeader**> actual;
|
||||
for (auto item : tls) {
|
||||
actual.push_back(item);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ TEST(ThreadLocalStorageTest, NoRecords) {
|
||||
|
||||
tls.Commit();
|
||||
|
||||
KStdVector<ObjHeader**> actual;
|
||||
std_support::vector<ObjHeader**> actual;
|
||||
for (auto item : tls) {
|
||||
actual.push_back(item);
|
||||
}
|
||||
@@ -132,7 +132,7 @@ TEST(ThreadLocalStorageTest, ClearEmpty) {
|
||||
|
||||
tls.Clear();
|
||||
|
||||
KStdVector<ObjHeader**> actual;
|
||||
std_support::vector<ObjHeader**> actual;
|
||||
for (auto item : tls) {
|
||||
actual.push_back(item);
|
||||
}
|
||||
@@ -149,7 +149,7 @@ TEST(ThreadLocalStorageTest, ClearNonEmpty) {
|
||||
|
||||
tls.Clear();
|
||||
|
||||
KStdVector<ObjHeader**> actual;
|
||||
std_support::vector<ObjHeader**> actual;
|
||||
for (auto item : tls) {
|
||||
actual.push_back(item);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "ScopedThread.hpp"
|
||||
#include "ThreadSuspension.hpp"
|
||||
#include "ThreadState.hpp"
|
||||
#include "std_support/Vector.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
@@ -31,8 +32,8 @@ constexpr size_t kDefaultIterations = 10000;
|
||||
constexpr size_t kDefaultReportingStep = 1000;
|
||||
#endif // #ifdef KONAN_WINDOWS
|
||||
|
||||
KStdVector<mm::ThreadData*> collectThreadData() {
|
||||
KStdVector<mm::ThreadData*> result;
|
||||
std_support::vector<mm::ThreadData*> collectThreadData() {
|
||||
std_support::vector<mm::ThreadData*> result;
|
||||
auto iter = mm::ThreadRegistry::Instance().LockForIter();
|
||||
for (auto& thread : iter) {
|
||||
result.push_back(&thread);
|
||||
@@ -40,15 +41,15 @@ KStdVector<mm::ThreadData*> collectThreadData() {
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, typename F>
|
||||
KStdVector<T> collectFromThreadData(F extractFunction) {
|
||||
KStdVector<T> result;
|
||||
template <typename T, typename F>
|
||||
std_support::vector<T> collectFromThreadData(F extractFunction) {
|
||||
std_support::vector<T> result;
|
||||
auto threadData = collectThreadData();
|
||||
std::transform(threadData.begin(), threadData.end(), std::back_inserter(result), extractFunction);
|
||||
return result;
|
||||
}
|
||||
|
||||
KStdVector<bool> collectSuspended() {
|
||||
std_support::vector<bool> collectSuspended() {
|
||||
return collectFromThreadData<bool>(
|
||||
[](mm::ThreadData* threadData) { return threadData->suspensionData().suspended(); });
|
||||
}
|
||||
@@ -82,7 +83,7 @@ public:
|
||||
static constexpr size_t kThreadCount = kDefaultThreadCount;
|
||||
static constexpr size_t kIterations = kDefaultIterations;
|
||||
|
||||
KStdVector<ScopedThread> threads;
|
||||
std_support::vector<ScopedThread> threads;
|
||||
std::array<std::atomic<bool>, kThreadCount> ready{false};
|
||||
std::atomic<bool> canStart{false};
|
||||
std::atomic<bool> shouldStop{false};
|
||||
|
||||
Reference in New Issue
Block a user