[K/N][New MM] Support thread state switching

Including

* Support thread state switching in codegen
* Introduce and use GCUnsafeCall annotation
* Switch thread state in C++ runtime code

Also

* Register current thread in Mark&Sweep tests
* Store MemoryState in Worker instance
* Set worker tid in WorkerInit
This commit is contained in:
Ilya Matveev
2021-01-25 19:06:27 +07:00
committed by Space
parent 0b46ed3cde
commit 4d346d3735
86 changed files with 1340 additions and 721 deletions
+22 -21
View File
@@ -243,10 +243,13 @@ void LeaveFrame(ObjHeader** start, int parameters, int count) RUNTIME_NOTHROW;
// checks if subgraph referenced by given root is disjoint from the rest of
// object graph, i.e. no external references exists.
bool ClearSubgraphReferences(ObjHeader* root, bool checked) RUNTIME_NOTHROW;
// Creates stable pointer out of the object.
// Creates a stable pointer out of the object.
void* CreateStablePointer(ObjHeader* obj) RUNTIME_NOTHROW;
// Disposes stable pointer to the object.
// Disposes a stable pointer to the object.
void DisposeStablePointer(void* pointer) RUNTIME_NOTHROW;
// Disposes a stable pointer to the object.
// Accepts a MemoryState, thus can be called from deinitiliazation methods, when TLS is already deallocated.
void DisposeStablePointerFor(MemoryState* memoryState, void* pointer) RUNTIME_NOTHROW;
// Translate stable pointer to object reference.
OBJ_GETTER(DerefStablePointer, void*) RUNTIME_NOTHROW;
// Move stable pointer ownership.
@@ -394,8 +397,14 @@ enum class ThreadState {
kRunnable, kNative
};
ThreadState GetThreadState(MemoryState* thread) noexcept;
inline ThreadState GetThreadState() noexcept {
return GetThreadState(mm::GetMemoryState());
}
// Switches the state of the given thread to `newState` and returns the previous thread state.
ALWAYS_INLINE ThreadState SwitchThreadState(MemoryState* thread, ThreadState newState) noexcept;
ALWAYS_INLINE ThreadState SwitchThreadState(MemoryState* thread, ThreadState newState, bool reentrant = false) noexcept;
// Asserts that the given thread is in the given state.
ALWAYS_INLINE void AssertThreadState(MemoryState* thread, ThreadState expected) noexcept;
@@ -409,35 +418,27 @@ ALWAYS_INLINE inline void AssertThreadState(ThreadState expected) noexcept {
class ThreadStateGuard final : private Pinned {
public:
// Set the state for the given thread.
ThreadStateGuard(MemoryState* thread, ThreadState state) noexcept : thread_(thread) {
oldState_ = SwitchThreadState(thread_, state);
ThreadStateGuard(MemoryState* thread, ThreadState state, bool reentrant = false) noexcept : thread_(thread), reentrant_(reentrant) {
oldState_ = SwitchThreadState(thread_, state, reentrant_);
}
// Sets the state for the current thread.
explicit ThreadStateGuard(ThreadState state) noexcept
: ThreadStateGuard(mm::GetMemoryState(), state) {};
explicit ThreadStateGuard(ThreadState state, bool reentrant = false) noexcept
: ThreadStateGuard(mm::GetMemoryState(), state, reentrant) {};
~ThreadStateGuard() noexcept {
SwitchThreadState(thread_, oldState_);
SwitchThreadState(thread_, oldState_, reentrant_);
}
private:
MemoryState* thread_;
ThreadState oldState_;
bool reentrant_;
};
// Calls the given function in the `Runnable` thread state.
template <typename R, typename... Args>
ALWAYS_INLINE inline R CallKotlin(R(*kotlinFunction)(Args...), Args... args) {
ThreadStateGuard guard(ThreadState::kRunnable);
return kotlinFunction(std::forward<Args>(args)...);
}
// Calls the given function in the `Runnable` thread state. The function must be marked as RUNTIME_NORETURN.
// If the function returns, behaviour is undefined.
template <typename... Args>
ALWAYS_INLINE RUNTIME_NORETURN inline void CallKotlinNoReturn(void(*noreturnKotlinFunction)(Args...), Args... args) {
CallKotlin(noreturnKotlinFunction, std::forward<Args>(args)...);
RuntimeFail("The function must not return");
template <ThreadState state, typename R, typename... Args>
ALWAYS_INLINE inline R CallWithThreadState(R(*function)(Args...), Args... args) {
ThreadStateGuard guard(state);
return function(std::forward<Args>(args)...);
}
} // namespace kotlin