[K/N] Added checks for tests that current frame after catch is right

This commit is contained in:
Elena Lepilkina
2021-10-14 15:58:54 +03:00
committed by Space
parent ccddf5b2d5
commit 2d72f4d5a9
9 changed files with 25 additions and 0 deletions
@@ -1051,6 +1051,11 @@ internal abstract class FunctionGenerationContext(
return exception return exception
} }
fun generateFrameCheck() {
assert(slotsPhi != null)
call(context.llvm.checkCurrentFrameFunction, listOf(slotsPhi!!))
}
inline fun ifThenElse( inline fun ifThenElse(
condition: LLVMValueRef, condition: LLVMValueRef,
thenValue: LLVMValueRef, thenValue: LLVMValueRef,
@@ -457,6 +457,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) : Runti
val enterFrameFunction = importRtFunction("EnterFrame") val enterFrameFunction = importRtFunction("EnterFrame")
val leaveFrameFunction = importRtFunction("LeaveFrame") val leaveFrameFunction = importRtFunction("LeaveFrame")
val setCurrentFrameFunction = importRtFunction("SetCurrentFrame") val setCurrentFrameFunction = importRtFunction("SetCurrentFrame")
val checkCurrentFrameFunction = importRtFunction("CheckCurrentFrame")
val lookupInterfaceTableRecord = importRtFunction("LookupInterfaceTableRecord") val lookupInterfaceTableRecord = importRtFunction("LookupInterfaceTableRecord")
val isInstanceFunction = importRtFunction("IsInstance") val isInstanceFunction = importRtFunction("IsInstance")
val isInstanceOfClassFastFunction = importRtFunction("IsInstanceOfClassFast") val isInstanceOfClassFastFunction = importRtFunction("IsInstanceOfClassFast")
@@ -1213,6 +1213,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
fun genCatchBlock() { fun genCatchBlock() {
using(VariableScope()) { using(VariableScope()) {
currentCodeContext.genDeclareVariable(catch.catchParameter, exception, null) currentCodeContext.genDeclareVariable(catch.catchParameter, exception, null)
functionGenerationContext.generateFrameCheck()
evaluateExpressionAndJump(catch.result, success) evaluateExpressionAndJump(catch.result, success)
} }
} }
@@ -3676,6 +3676,11 @@ RUNTIME_NOTHROW FrameOverlay* getCurrentFrame() {
return currentFrame; return currentFrame;
} }
ALWAYS_INLINE RUNTIME_NOTHROW void CheckCurrentFrame(ObjHeader** frame) {
FrameOverlay* expectedFrame = reinterpret_cast<FrameOverlay*>(frame);
RuntimeAssert(currentFrame == expectedFrame, "Frame is expected to be %p, but current frame is %p", expectedFrame, 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);
@@ -36,6 +36,7 @@ void EnsureDeclarationsEmitted() {
ensureUsed(EnterFrame); ensureUsed(EnterFrame);
ensureUsed(LeaveFrame); ensureUsed(LeaveFrame);
ensureUsed(SetCurrentFrame); ensureUsed(SetCurrentFrame);
ensureUsed(CheckCurrentFrame);
ensureUsed(AddTLSRecord); ensureUsed(AddTLSRecord);
ensureUsed(LookupTLS); ensureUsed(LookupTLS);
ensureUsed(MutationCheck); ensureUsed(MutationCheck);
@@ -246,6 +246,7 @@ void LeaveFrame(ObjHeader** start, int parameters, int count) RUNTIME_NOTHROW;
// Set current frame in case if exception caught. // Set current frame in case if exception caught.
void SetCurrentFrame(ObjHeader** start) RUNTIME_NOTHROW; void SetCurrentFrame(ObjHeader** start) RUNTIME_NOTHROW;
FrameOverlay* getCurrentFrame() RUNTIME_NOTHROW; FrameOverlay* getCurrentFrame() RUNTIME_NOTHROW;
ALWAYS_INLINE void CheckCurrentFrame(ObjHeader** frame) 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
@@ -250,6 +250,12 @@ extern "C" RUNTIME_NOTHROW FrameOverlay* getCurrentFrame() {
return threadData->shadowStack().getCurrentFrame(); return threadData->shadowStack().getCurrentFrame();
} }
extern "C" RUNTIME_NOTHROW ALWAYS_INLINE void CheckCurrentFrame(ObjHeader** frame) {
auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
AssertThreadState(threadData, ThreadState::kRunnable);
return threadData->shadowStack().checkCurrentFrame(reinterpret_cast<FrameOverlay*>(frame));
}
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);
} }
@@ -43,3 +43,7 @@ void mm::ShadowStack::SetCurrentFrame(ObjHeader** start) noexcept {
FrameOverlay* mm::ShadowStack::getCurrentFrame() noexcept { FrameOverlay* mm::ShadowStack::getCurrentFrame() noexcept {
return currentFrame_; return currentFrame_;
} }
void mm::ShadowStack::checkCurrentFrame(FrameOverlay* frame) noexcept {
RuntimeAssert(currentFrame_ == frame, "Frame is expected to be %p, but current frame is %p", frame, currentFrame_);
}
@@ -55,6 +55,7 @@ public:
void LeaveFrame(ObjHeader** start, int parameters, int count) noexcept; void LeaveFrame(ObjHeader** start, int parameters, int count) noexcept;
void SetCurrentFrame(ObjHeader** start) noexcept; void SetCurrentFrame(ObjHeader** start) noexcept;
FrameOverlay* getCurrentFrame() noexcept; FrameOverlay* getCurrentFrame() noexcept;
void checkCurrentFrame(FrameOverlay* frame) 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); }