[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 enterFrameFunction = importRtFunction("EnterFrame")
val leaveFrameFunction = importRtFunction("LeaveFrame")
val setCurrentFrameFunction = importRtFunction("SetCurrentFrame")
val lookupInterfaceTableRecord = importRtFunction("LookupInterfaceTableRecord")
val isInstanceFunction = importRtFunction("IsInstance")
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() {
GC_LOG("suspendGC\n")
memoryState->gcSuspendCount++;
@@ -3466,6 +3477,13 @@ RUNTIME_NOTHROW void LeaveFrameRelaxed(ObjHeader** start, int parameters, int co
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) {
#if USE_GC
garbageCollect();
@@ -3654,6 +3672,10 @@ RUNTIME_NOTHROW void GC_RegisterWorker(void* worker) {
#endif // USE_CYCLIC_GC
}
RUNTIME_NOTHROW FrameOverlay* getCurrentFrame() {
return currentFrame;
}
RUNTIME_NOTHROW void GC_UnregisterWorker(void* worker) {
#if USE_CYCLIC_GC
cyclicRemoveWorker(worker, g_hasCyclicCollector);
@@ -326,6 +326,7 @@ MODEL_VARIANTS(void, UpdateHeapRefsInsideOneArray, const ArrayHeader* array, int
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, SetCurrentFrame, ObjHeader** start);
void ReleaseHeapRef(const ObjHeader* object) RUNTIME_NOTHROW;
MODEL_VARIANTS(void, ReleaseHeapRef, const ObjHeader* object);
@@ -35,6 +35,7 @@ void EnsureDeclarationsEmitted() {
ensureUsed(ZeroArrayRefs);
ensureUsed(EnterFrame);
ensureUsed(LeaveFrame);
ensureUsed(SetCurrentFrame);
ensureUsed(AddTLSRecord);
ensureUsed(LookupTLS);
ensureUsed(MutationCheck);
@@ -18,6 +18,7 @@
#define RUNTIME_MEMORY_H
#include <utility>
#include <functional>
#include "KAssert.h"
#include "Common.h"
@@ -122,6 +123,7 @@ ALWAYS_INLINE inline bool isNullOrMarker(const ObjHeader* obj) noexcept {
}
class ForeignRefManager;
struct FrameOverlay;
typedef ForeignRefManager* ForeignRefContext;
#ifdef __cplusplus
@@ -241,6 +243,10 @@ OBJ_GETTER(ReadHeapRefNoLock, ObjHeader* object, int32_t index);
void EnterFrame(ObjHeader** start, int parameters, int count) RUNTIME_NOTHROW;
// Called on frame leave, if it has object slots.
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
// checks if subgraph referenced by given root is disjoint from the rest of
// object graph, i.e. no external references exists.
+27 -20
View File
@@ -160,7 +160,7 @@ class Worker {
bool waitForQueueLocked(KLong timeoutMicroseconds, KLong* remaining);
JobKind processQueueElement(bool blocking);
RUNTIME_NODEBUG JobKind processQueueElement(bool blocking);
bool park(KLong timeoutMicroseconds, bool process);
@@ -1052,21 +1052,22 @@ JobKind Worker::processQueueElement(bool blocking) {
ObjHolder operationHolder, dummyHolder;
KRef obj = DerefStablePointer(job.executeAfter.operation, operationHolder.slot());
try {
#if KONAN_OBJC_INTEROP
konan::AutoreleasePool autoreleasePool;
#endif
WorkerLaunchpad(obj, dummyHolder.slot());
} catch (ExceptionObjHolder& e) {
#if KONAN_OBJC_INTEROP
konan::AutoreleasePool autoreleasePool;
#endif
WorkerLaunchpad(obj, dummyHolder.slot());
} catch(ExceptionObjHolder& e) {
switch (exceptionHandling()) {
case WorkerExceptionHandling::kIgnore: break;
case WorkerExceptionHandling::kDefault:
kotlin::ProcessUnhandledException(e.GetExceptionObject());
break;
case WorkerExceptionHandling::kLog:
ReportUnhandledException(e.GetExceptionObject());
break;
case WorkerExceptionHandling::kIgnore: break;
case WorkerExceptionHandling::kDefault:
kotlin::ProcessUnhandledException(e.GetExceptionObject());
break;
case WorkerExceptionHandling::kLog:
ReportUnhandledException(e.GetExceptionObject());
break;
}
}
DisposeStablePointer(job.executeAfter.operation);
break;
}
@@ -1076,15 +1077,21 @@ JobKind Worker::processQueueElement(bool blocking) {
ObjHolder argumentHolder;
ObjHolder resultHolder;
KRef argument = AdoptStablePointer(job.regularJob.argument, argumentHolder.slot());
#if !KONAN_NO_EXCEPTIONS
FrameOverlay* currentFrame = getCurrentFrame();
#else
RuntimeFail("Exceptions aren't supported!\n");
#endif
try {
#if KONAN_OBJC_INTEROP
konan::AutoreleasePool autoreleasePool;
#endif
job.regularJob.function(argument, resultHolder.slot());
argumentHolder.clear();
// Transfer the result.
result = transfer(&resultHolder, job.regularJob.transferMode);
#if KONAN_OBJC_INTEROP
konan::AutoreleasePool autoreleasePool;
#endif
job.regularJob.function(argument, resultHolder.slot());
argumentHolder.clear();
// Transfer the result.
result = transfer(&resultHolder, job.regularJob.transferMode);
} catch (ExceptionObjHolder& e) {
SetCurrentFrame(reinterpret_cast<ObjHeader**>(currentFrame));
ok = false;
switch (exceptionHandling()) {
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)
"_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()
"_Znwm", // new
"_Znwy",
"_ZdlPv", // delete
"__mingw_vsnprintf",
"__cxa_allocate_exception",
"__cxa_begin_catch",
@@ -238,6 +238,18 @@ extern "C" RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, in
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) {
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);
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 LeaveFrame(ObjHeader** start, int parameters, int count) noexcept;
void SetCurrentFrame(ObjHeader** start) noexcept;
FrameOverlay* getCurrentFrame() noexcept;
Iterator begin() noexcept { return Iterator(currentFrame_); }
Iterator end() noexcept { return Iterator(nullptr); }
@@ -63,6 +63,10 @@ RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) {
LeaveFrameRelaxed(start, parameters, count);
}
RUNTIME_NOTHROW void SetCurrentFrame(ObjHeader** start) {
SetCurrentFrameRelaxed(start);
}
RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) {
UpdateStackRefRelaxed(location, object);
}
@@ -63,6 +63,10 @@ RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) {
LeaveFrameStrict(start, parameters, count);
}
RUNTIME_NOTHROW void SetCurrentFrame(ObjHeader** start) {
SetCurrentFrameStrict(start);
}
RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) {
UpdateStackRefStrict(location, object);
}