[K/N] Added function SetCurrentFrame to use in unwind block

This commit is contained in:
Elena Lepilkina
2021-09-29 17:49:02 +03:00
committed by Space
parent 42c213d950
commit cde51ecc3a
12 changed files with 91 additions and 20 deletions
@@ -456,6 +456,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) : Runti
val zeroArrayRefsFunction = importRtFunction("ZeroArrayRefs") val zeroArrayRefsFunction = importRtFunction("ZeroArrayRefs")
val enterFrameFunction = importRtFunction("EnterFrame") val enterFrameFunction = importRtFunction("EnterFrame")
val leaveFrameFunction = importRtFunction("LeaveFrame") val leaveFrameFunction = importRtFunction("LeaveFrame")
val setCurrentFrameFunction = importRtFunction("SetCurrentFrame")
val lookupInterfaceTableRecord = importRtFunction("LookupInterfaceTableRecord") val lookupInterfaceTableRecord = importRtFunction("LookupInterfaceTableRecord")
val isInstanceFunction = importRtFunction("IsInstance") val isInstanceFunction = importRtFunction("IsInstance")
val isInstanceOfClassFastFunction = importRtFunction("IsInstanceOfClassFast") val isInstanceOfClassFastFunction = importRtFunction("IsInstanceOfClassFast")
@@ -2561,6 +2561,17 @@ void leaveFrame(ObjHeader** start, int parameters, int count) {
} }
} }
template <bool Strict>
void setCurrentFrame(ObjHeader** start) {
MEMORY_LOG("SetCurrentFrame %p\n", start)
FrameOverlay* frame = reinterpret_cast<FrameOverlay*>(start);
if (Strict) {
currentFrame = frame;
} else {
RuntimeFail("Relaxed memory model is deprecated and doesn't support exception handling proper way!\n");
}
}
void suspendGC() { void suspendGC() {
GC_LOG("suspendGC\n") GC_LOG("suspendGC\n")
memoryState->gcSuspendCount++; memoryState->gcSuspendCount++;
@@ -3466,6 +3477,13 @@ RUNTIME_NOTHROW void LeaveFrameRelaxed(ObjHeader** start, int parameters, int co
leaveFrame<false>(start, parameters, count); leaveFrame<false>(start, parameters, count);
} }
RUNTIME_NOTHROW void SetCurrentFrameStrict(ObjHeader** start) {
setCurrentFrame<true>(start);
}
RUNTIME_NOTHROW void SetCurrentFrameRelaxed(ObjHeader** start) {
setCurrentFrame<false>(start);
}
void Kotlin_native_internal_GC_collect(KRef) { void Kotlin_native_internal_GC_collect(KRef) {
#if USE_GC #if USE_GC
garbageCollect(); garbageCollect();
@@ -3654,6 +3672,10 @@ RUNTIME_NOTHROW void GC_RegisterWorker(void* worker) {
#endif // USE_CYCLIC_GC #endif // USE_CYCLIC_GC
} }
RUNTIME_NOTHROW FrameOverlay* getCurrentFrame() {
return currentFrame;
}
RUNTIME_NOTHROW void GC_UnregisterWorker(void* worker) { RUNTIME_NOTHROW void GC_UnregisterWorker(void* worker) {
#if USE_CYCLIC_GC #if USE_CYCLIC_GC
cyclicRemoveWorker(worker, g_hasCyclicCollector); cyclicRemoveWorker(worker, g_hasCyclicCollector);
@@ -326,6 +326,7 @@ MODEL_VARIANTS(void, UpdateHeapRefsInsideOneArray, const ArrayHeader* array, int
int count); int count);
MODEL_VARIANTS(void, EnterFrame, ObjHeader** start, int parameters, int count); MODEL_VARIANTS(void, EnterFrame, ObjHeader** start, int parameters, int count);
MODEL_VARIANTS(void, LeaveFrame, ObjHeader** start, int parameters, int count); MODEL_VARIANTS(void, LeaveFrame, ObjHeader** start, int parameters, int count);
MODEL_VARIANTS(void, SetCurrentFrame, ObjHeader** start);
void ReleaseHeapRef(const ObjHeader* object) RUNTIME_NOTHROW; void ReleaseHeapRef(const ObjHeader* object) RUNTIME_NOTHROW;
MODEL_VARIANTS(void, ReleaseHeapRef, const ObjHeader* object); MODEL_VARIANTS(void, ReleaseHeapRef, const ObjHeader* object);
@@ -35,6 +35,7 @@ void EnsureDeclarationsEmitted() {
ensureUsed(ZeroArrayRefs); ensureUsed(ZeroArrayRefs);
ensureUsed(EnterFrame); ensureUsed(EnterFrame);
ensureUsed(LeaveFrame); ensureUsed(LeaveFrame);
ensureUsed(SetCurrentFrame);
ensureUsed(AddTLSRecord); ensureUsed(AddTLSRecord);
ensureUsed(LookupTLS); ensureUsed(LookupTLS);
ensureUsed(MutationCheck); ensureUsed(MutationCheck);
@@ -18,6 +18,7 @@
#define RUNTIME_MEMORY_H #define RUNTIME_MEMORY_H
#include <utility> #include <utility>
#include <functional>
#include "KAssert.h" #include "KAssert.h"
#include "Common.h" #include "Common.h"
@@ -122,6 +123,7 @@ ALWAYS_INLINE inline bool isNullOrMarker(const ObjHeader* obj) noexcept {
} }
class ForeignRefManager; class ForeignRefManager;
struct FrameOverlay;
typedef ForeignRefManager* ForeignRefContext; typedef ForeignRefManager* ForeignRefContext;
#ifdef __cplusplus #ifdef __cplusplus
@@ -241,6 +243,10 @@ OBJ_GETTER(ReadHeapRefNoLock, ObjHeader* object, int32_t index);
void EnterFrame(ObjHeader** start, int parameters, int count) RUNTIME_NOTHROW; void EnterFrame(ObjHeader** start, int parameters, int count) RUNTIME_NOTHROW;
// Called on frame leave, if it has object slots. // Called on frame leave, if it has object slots.
void LeaveFrame(ObjHeader** start, int parameters, int count) RUNTIME_NOTHROW; void LeaveFrame(ObjHeader** start, int parameters, int count) RUNTIME_NOTHROW;
// Set current frame in case if exception caught.
void SetCurrentFrame(ObjHeader** start) RUNTIME_NOTHROW;
FrameOverlay* getCurrentFrame() RUNTIME_NOTHROW;
// Clears object subgraph references from memory subsystem, and optionally // Clears object subgraph references from memory subsystem, and optionally
// checks if subgraph referenced by given root is disjoint from the rest of // checks if subgraph referenced by given root is disjoint from the rest of
// object graph, i.e. no external references exists. // object graph, i.e. no external references exists.
+27 -20
View File
@@ -160,7 +160,7 @@ class Worker {
bool waitForQueueLocked(KLong timeoutMicroseconds, KLong* remaining); bool waitForQueueLocked(KLong timeoutMicroseconds, KLong* remaining);
JobKind processQueueElement(bool blocking); RUNTIME_NODEBUG JobKind processQueueElement(bool blocking);
bool park(KLong timeoutMicroseconds, bool process); bool park(KLong timeoutMicroseconds, bool process);
@@ -1052,21 +1052,22 @@ JobKind Worker::processQueueElement(bool blocking) {
ObjHolder operationHolder, dummyHolder; ObjHolder operationHolder, dummyHolder;
KRef obj = DerefStablePointer(job.executeAfter.operation, operationHolder.slot()); KRef obj = DerefStablePointer(job.executeAfter.operation, operationHolder.slot());
try { try {
#if KONAN_OBJC_INTEROP #if KONAN_OBJC_INTEROP
konan::AutoreleasePool autoreleasePool; konan::AutoreleasePool autoreleasePool;
#endif #endif
WorkerLaunchpad(obj, dummyHolder.slot()); WorkerLaunchpad(obj, dummyHolder.slot());
} catch (ExceptionObjHolder& e) { } catch(ExceptionObjHolder& e) {
switch (exceptionHandling()) { switch (exceptionHandling()) {
case WorkerExceptionHandling::kIgnore: break; case WorkerExceptionHandling::kIgnore: break;
case WorkerExceptionHandling::kDefault: case WorkerExceptionHandling::kDefault:
kotlin::ProcessUnhandledException(e.GetExceptionObject()); kotlin::ProcessUnhandledException(e.GetExceptionObject());
break; break;
case WorkerExceptionHandling::kLog: case WorkerExceptionHandling::kLog:
ReportUnhandledException(e.GetExceptionObject()); ReportUnhandledException(e.GetExceptionObject());
break; break;
} }
} }
DisposeStablePointer(job.executeAfter.operation); DisposeStablePointer(job.executeAfter.operation);
break; break;
} }
@@ -1076,15 +1077,21 @@ JobKind Worker::processQueueElement(bool blocking) {
ObjHolder argumentHolder; ObjHolder argumentHolder;
ObjHolder resultHolder; ObjHolder resultHolder;
KRef argument = AdoptStablePointer(job.regularJob.argument, argumentHolder.slot()); KRef argument = AdoptStablePointer(job.regularJob.argument, argumentHolder.slot());
#if !KONAN_NO_EXCEPTIONS
FrameOverlay* currentFrame = getCurrentFrame();
#else
RuntimeFail("Exceptions aren't supported!\n");
#endif
try { try {
#if KONAN_OBJC_INTEROP #if KONAN_OBJC_INTEROP
konan::AutoreleasePool autoreleasePool; konan::AutoreleasePool autoreleasePool;
#endif #endif
job.regularJob.function(argument, resultHolder.slot()); job.regularJob.function(argument, resultHolder.slot());
argumentHolder.clear(); argumentHolder.clear();
// Transfer the result. // Transfer the result.
result = transfer(&resultHolder, job.regularJob.transferMode); result = transfer(&resultHolder, job.regularJob.transferMode);
} catch (ExceptionObjHolder& e) { } catch (ExceptionObjHolder& e) {
SetCurrentFrame(reinterpret_cast<ObjHeader**>(currentFrame));
ok = false; ok = false;
switch (exceptionHandling()) { switch (exceptionHandling()) {
case WorkerExceptionHandling::kIgnore: case WorkerExceptionHandling::kIgnore:
@@ -51,6 +51,9 @@ extern "C" const char* Kotlin_callsCheckerGoodFunctionNames[] = {
"_ZSt17rethrow_exceptionNSt15__exception_ptr13exception_ptrE", // std::rethrow_exception(std::__exception_ptr::exception_ptr) "_ZSt17rethrow_exceptionNSt15__exception_ptr13exception_ptrE", // std::rethrow_exception(std::__exception_ptr::exception_ptr)
"_ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_", // std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) "_ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_", // std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)
"_ZN9__gnu_cxx27__verbose_terminate_handlerEv", // __gnu_cxx::__verbose_terminate_handler() "_ZN9__gnu_cxx27__verbose_terminate_handlerEv", // __gnu_cxx::__verbose_terminate_handler()
"_Znwm", // new
"_Znwy",
"_ZdlPv", // delete
"__mingw_vsnprintf", "__mingw_vsnprintf",
"__cxa_allocate_exception", "__cxa_allocate_exception",
"__cxa_begin_catch", "__cxa_begin_catch",
@@ -238,6 +238,18 @@ extern "C" RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, in
threadData->shadowStack().LeaveFrame(start, parameters, count); threadData->shadowStack().LeaveFrame(start, parameters, count);
} }
extern "C" RUNTIME_NOTHROW void SetCurrentFrame(ObjHeader** start) {
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
AssertThreadState(threadData, ThreadState::kRunnable);
threadData->shadowStack().SetCurrentFrame(start);
}
extern "C" RUNTIME_NOTHROW FrameOverlay* getCurrentFrame() {
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
AssertThreadState(threadData, ThreadState::kRunnable);
return threadData->shadowStack().getCurrentFrame();
}
extern "C" RUNTIME_NOTHROW void AddTLSRecord(MemoryState* memory, void** key, int size) { extern "C" RUNTIME_NOTHROW void AddTLSRecord(MemoryState* memory, void** key, int size) {
memory->GetThreadData()->tls().AddRecord(key, size); memory->GetThreadData()->tls().AddRecord(key, size);
} }
@@ -35,3 +35,11 @@ void mm::ShadowStack::LeaveFrame(ObjHeader** start, int parameters, int count) n
FrameOverlay* frame = reinterpret_cast<FrameOverlay*>(start); FrameOverlay* frame = reinterpret_cast<FrameOverlay*>(start);
currentFrame_ = frame->previous; currentFrame_ = frame->previous;
} }
void mm::ShadowStack::SetCurrentFrame(ObjHeader** start) noexcept {
currentFrame_ = reinterpret_cast<FrameOverlay*>(start);
}
FrameOverlay* mm::ShadowStack::getCurrentFrame() noexcept {
return currentFrame_;
}
@@ -53,6 +53,8 @@ public:
void EnterFrame(ObjHeader** start, int parameters, int count) noexcept; void EnterFrame(ObjHeader** start, int parameters, int count) noexcept;
void LeaveFrame(ObjHeader** start, int parameters, int count) noexcept; void LeaveFrame(ObjHeader** start, int parameters, int count) noexcept;
void SetCurrentFrame(ObjHeader** start) noexcept;
FrameOverlay* getCurrentFrame() noexcept;
Iterator begin() noexcept { return Iterator(currentFrame_); } Iterator begin() noexcept { return Iterator(currentFrame_); }
Iterator end() noexcept { return Iterator(nullptr); } Iterator end() noexcept { return Iterator(nullptr); }
@@ -63,6 +63,10 @@ RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) {
LeaveFrameRelaxed(start, parameters, count); LeaveFrameRelaxed(start, parameters, count);
} }
RUNTIME_NOTHROW void SetCurrentFrame(ObjHeader** start) {
SetCurrentFrameRelaxed(start);
}
RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) { RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) {
UpdateStackRefRelaxed(location, object); UpdateStackRefRelaxed(location, object);
} }
@@ -63,6 +63,10 @@ RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) {
LeaveFrameStrict(start, parameters, count); LeaveFrameStrict(start, parameters, count);
} }
RUNTIME_NOTHROW void SetCurrentFrame(ObjHeader** start) {
SetCurrentFrameStrict(start);
}
RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) { RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) {
UpdateStackRefStrict(location, object); UpdateStackRefStrict(location, object);
} }