[K/N] Added function SetCurrentFrame to use in unwind block
This commit is contained in:
+1
@@ -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.
|
||||||
|
|||||||
@@ -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,11 +1052,11 @@ 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:
|
||||||
@@ -1067,6 +1067,7 @@ JobKind Worker::processQueueElement(bool blocking) {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user