blob: 39fb669b535820d073d054d1c1b58d7c949d0c33 [file]
/*
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
#ifndef RUNTIME_MM_THREAD_DATA_H
#define RUNTIME_MM_THREAD_DATA_H
#include <atomic>
#include <cstdint>
#include <vector>
#include "GlobalData.hpp"
#include "GlobalsRegistry.hpp"
#include "GC.hpp"
#include "ShadowStack.hpp"
#include "ExternalRCRefRegistry.hpp"
#include "ThreadLocalStorage.hpp"
#include "Utils.hpp"
#include "ThreadSuspension.hpp"
struct ObjHeader;
namespace kotlin {
namespace mm {
// `ThreadData` is supposed to be thread local singleton.
// Pin it in memory to prevent accidental copying.
class ThreadData final : private Pinned {
public:
explicit ThreadData(uintptr_t threadId) noexcept :
threadId_(threadId),
globalsThreadQueue_(GlobalsRegistry::Instance()),
externalRCRefRegistry_(ExternalRCRefRegistry::instance()),
gcScheduler_(GlobalData::Instance().gcScheduler(), *this),
allocator_(GlobalData::Instance().allocator()),
gc_(GlobalData::Instance().gc(), *this),
suspensionData_(ThreadState::kNative, *this) {}
~ThreadData() = default;
uintptr_t threadId() const noexcept { return threadId_; }
GlobalsRegistry::ThreadQueue& globalsThreadQueue() noexcept { return globalsThreadQueue_; }
ThreadLocalStorage& tls() noexcept { return tls_; }
ExternalRCRefRegistry::ThreadQueue& externalRCRefRegistry() noexcept { return externalRCRefRegistry_; }
ThreadState state() noexcept { return suspensionData_.state(); }
ThreadState setState(ThreadState state) noexcept { return suspensionData_.setState(state); }
ShadowStack& shadowStack() noexcept { return shadowStack_; }
std::vector<std::pair<ObjHeader**, ObjHeader*>>& initializingSingletons() noexcept { return initializingSingletons_; }
gcScheduler::GCScheduler::ThreadData& gcScheduler() noexcept { return gcScheduler_; }
alloc::Allocator::ThreadData& allocator() noexcept { return allocator_; }
gc::GC::ThreadData& gc() noexcept { return gc_; }
ThreadSuspensionData& suspensionData() { return suspensionData_; }
void Publish() noexcept {
// TODO: These use separate locks, which is inefficient.
globalsThreadQueue_.Publish();
externalRCRefRegistry_.publish();
}
void ClearForTests() noexcept {
globalsThreadQueue_.ClearForTests();
externalRCRefRegistry_.clearForTests();
allocator_.clearForTests();
}
private:
const uintptr_t threadId_;
GlobalsRegistry::ThreadQueue globalsThreadQueue_;
ThreadLocalStorage tls_;
ExternalRCRefRegistry::ThreadQueue externalRCRefRegistry_;
ShadowStack shadowStack_;
gcScheduler::GCScheduler::ThreadData gcScheduler_;
alloc::Allocator::ThreadData allocator_;
gc::GC::ThreadData gc_;
std::vector<std::pair<ObjHeader**, ObjHeader*>> initializingSingletons_;
ThreadSuspensionData suspensionData_;
};
} // namespace mm
} // namespace kotlin
#endif // RUNTIME_MM_THREAD_DATA_H