Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/coreclr/interpreter/inc/interpretershared.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,22 @@ struct InterpHelperData {
uint32_t accessType : 3;
};

#ifndef INTERPRETER_COMPILER_INTERNAL
class MethodDesc;
#endif

struct CallStubHeader;

struct InterpMethod
{
#if DEBUG
InterpMethod *self;
#endif
#ifdef INTERPRETER_COMPILER_INTERNAL
CORINFO_METHOD_HANDLE methodHnd;
#else
DPTR(MethodDesc) methodDesc;
#endif
int32_t argsSize;
int32_t allocaSize;
void** pDataItems;
Expand All @@ -38,6 +46,7 @@ struct InterpMethod
bool initLocals;
bool unmanagedCallersOnly;

#ifdef INTERPRETER_COMPILER_INTERNAL
InterpMethod(
CORINFO_METHOD_HANDLE methodHnd, int32_t argsSize, int32_t allocaSize,
void** pDataItems, bool initLocals, bool unmanagedCallersOnly
Expand All @@ -54,6 +63,7 @@ struct InterpMethod
this->unmanagedCallersOnly = unmanagedCallersOnly;
pCallStub = NULL;
}
#endif

bool CheckIntegrity()
{
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/interpreter/interpreter.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#define INTERPRETER_COMPILER_INTERNAL
#include <stdint.h>
#include <wchar.h>
#include <stdio.h>
Expand Down
13 changes: 8 additions & 5 deletions src/coreclr/vm/amd64/AsmHelpers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extern OnHijackWorker:proc
extern JIT_RareDisableHelperWorker:proc
ifdef FEATURE_INTERPRETER
extern ExecuteInterpretedMethod:proc
extern GetInterpThreadContextWithPossiblyMissingThread:proc
extern GetInterpThreadContextWithPossiblyMissingThreadOrCallStub:proc
endif

extern g_pPollGC:QWORD
Expand Down Expand Up @@ -563,15 +563,16 @@ NESTED_ENTRY InterpreterStub, _TEXT

INLINE_GETTHREAD r10; thrashes rax and r11
test r10, r10
jz NoManagedThread
jz NoManagedThreadOrCallStub

mov rax, qword ptr [r10 + OFFSETOF__Thread__m_pInterpThreadContext]
test rax, rax
jnz HaveInterpThreadContext

NoManagedThread:
mov rcx, r10
call GetInterpThreadContextWithPossiblyMissingThread
NoManagedThreadOrCallStub:
lea rcx, [rsp + __PWTB_TransitionBlock] ; pTransitionBlock*
mov rdx, rbx
call GetInterpThreadContextWithPossiblyMissingThreadOrCallStub
RESTORE_ARGUMENT_REGISTERS __PWTB_ArgumentRegisters
RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters

Expand All @@ -580,6 +581,8 @@ HaveInterpThreadContext:
; Load the InterpMethod pointer from the IR bytecode
mov rax, qword ptr [rbx]
mov rax, qword ptr [rax + OFFSETOF__InterpMethod__pCallStub]
test rax, rax
jz NoManagedThreadOrCallStub
lea r11, qword ptr [rax + OFFSETOF__CallStubHeader__Routines]
lea rax, [rsp + __PWTB_TransitionBlock]
; Copy the arguments to the interpreter stack, invoke the InterpExecMethod and load the return value
Expand Down
11 changes: 7 additions & 4 deletions src/coreclr/vm/amd64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -444,21 +444,24 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler
INLINE_GETTHREAD // result in rax, it can thrash all argument registers as it can call a helper
mov r10, rax
test rax, rax
jz LOCAL_LABEL(NoManagedThread)
jz LOCAL_LABEL(NoManagedThreadOrCallStub)

mov rax, qword ptr [r10 + OFFSETOF__Thread__m_pInterpThreadContext]
test rax, rax
jnz LOCAL_LABEL(HaveInterpThreadContext)

LOCAL_LABEL(NoManagedThread):
mov rdi, r10
call C_FUNC(GetInterpThreadContextWithPossiblyMissingThread)
LOCAL_LABEL(NoManagedThreadOrCallStub):
lea rdi, [rsp + __PWTB_TransitionBlock]
mov rsi, rbx
call C_FUNC(GetInterpThreadContextWithPossiblyMissingThreadOrCallStub)

LOCAL_LABEL(HaveInterpThreadContext):
mov r10, qword ptr [rax + OFFSETOF__InterpThreadContext__pStackPointer]
// Load the InterpMethod pointer from the IR bytecode
mov rax, qword ptr [rbx]
mov rax, qword ptr [rax + OFFSETOF__InterpMethod__pCallStub]
test rax, rax
jz LOCAL_LABEL(NoManagedThreadOrCallStub)
// Reload the argument registers, the macro to get the thread have likely overwritten them
mov rdi, qword ptr [rsp + __InterpreterStubArgumentRegistersOffset]
mov rsi, qword ptr [rsp + __InterpreterStubArgumentRegistersOffset + 8]
Expand Down
12 changes: 7 additions & 5 deletions src/coreclr/vm/arm64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -698,23 +698,24 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler
mov x21, x0
#endif
INLINE_GETTHREAD x20 // thrashes x0 on Apple OSes (and possibly other arg registers on other Unixes)
cbz x20, LOCAL_LABEL(NoManagedThread)
cbz x20, LOCAL_LABEL(NoManagedThreadOrCallStub)

ldr x11, [x20, #OFFSETOF__Thread__m_pInterpThreadContext]
cbnz x11, LOCAL_LABEL(HaveInterpThreadContext)

LOCAL_LABEL(NoManagedThread):
LOCAL_LABEL(NoManagedThreadOrCallStub):
#ifdef TARGET_APPLE
// GetInterpThreadContextWithPossiblyMissingThread can destroy all argument registers, so we
// GetInterpThreadContextWithPossiblyMissingThreadOrCallStub can destroy all argument registers, so we
// need to save them. For non-Apple, they have been already saved in the PROLOG_WITH_TRANSITION_BLOCK
// Restore x0 thrashed by the INLINE_GETTHREAD
mov x0, x21
SAVE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
SAVE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
#endif

mov x0, x20
bl C_FUNC(GetInterpThreadContextWithPossiblyMissingThread)
add x0, sp, #__PWTB_TransitionBlock + 16
mov x1, x19
bl C_FUNC(GetInterpThreadContextWithPossiblyMissingThreadOrCallStub)
mov x11, x0

#ifndef TARGET_APPLE
Expand All @@ -733,6 +734,7 @@ LOCAL_LABEL(HaveInterpThreadContext):

ldr x9, [x19] // InterpMethod*
ldr x9, [x9, #OFFSETOF__InterpMethod__pCallStub]
cbz x9, LOCAL_LABEL(NoManagedThreadOrCallStub)
add x10, x9, #OFFSETOF__CallStubHeader__Routines
ldr x9, [x11, #OFFSETOF__InterpThreadContext__pStackPointer]
// x19 contains IR bytecode address
Expand Down
16 changes: 9 additions & 7 deletions src/coreclr/vm/arm64/asmhelpers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
IMPORT HijackHandler
IMPORT ThrowControlForThread
#ifdef FEATURE_INTERPRETER
IMPORT GetInterpThreadContextWithPossiblyMissingThread
IMPORT GetInterpThreadContextWithPossiblyMissingThreadOrCallStub
IMPORT ExecuteInterpretedMethod
#endif

Expand Down Expand Up @@ -1064,23 +1064,25 @@ JIT_PollGCRarePath
PROLOG_WITH_TRANSITION_BLOCK

INLINE_GETTHREAD x20, x19
cbz x20, NoManagedThread
cbz x20, NoManagedThreadOrCallStub
mov x19, METHODDESC_REGISTER ; x19 contains IR bytecode address

ldr x11, [x20, #OFFSETOF__Thread__m_pInterpThreadContext]
cbnz x11, HaveInterpThreadContext

NoManagedThread
mov x0, x20
bl GetInterpThreadContextWithPossiblyMissingThread
NoManagedThreadOrCallStub
add x0, sp, #__PWTB_TransitionBlock + 16
mov x1, x19
bl GetInterpThreadContextWithPossiblyMissingThreadOrCallStub
mov x11, x0
RESTORE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters

HaveInterpThreadContext
; IR bytecode address
mov x19, METHODDESC_REGISTER
ldr x9, [METHODDESC_REGISTER]
ldr x9, [x19]
ldr x9, [x9, #OFFSETOF__InterpMethod__pCallStub]
cbz x9, NoManagedThreadOrCallStub
add x10, x9, #OFFSETOF__CallStubHeader__Routines
ldr x9, [x11, #OFFSETOF__InterpThreadContext__pStackPointer]
; x19 contains IR bytecode address
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/vm/exceptionhandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ EXTERN_C BOOL CallRtlUnwind(EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame, PV
#endif
#endif // !TARGET_UNIX

bool IsCallDescrWorkerInternalReturnAddress(PCODE pCode);

#ifdef USE_CURRENT_CONTEXT_IN_FILTER
inline void CaptureNonvolatileRegisters(PKNONVOLATILE_CONTEXT pNonvolatileContext, PCONTEXT pContext)
{
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/exceptionhandling.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ VOID DECLSPEC_NORETURN DispatchRethrownManagedException(CONTEXT* pExceptionConte

void DECLSPEC_NORETURN DispatchExSecondPass(ExInfo *pExInfo);

bool IsCallDescrWorkerInternalReturnAddress(PCODE pCode);

enum CLRUnwindStatus { UnwindPending, FirstPassComplete, SecondPassComplete };

enum TrackerMemoryType
Expand Down
38 changes: 16 additions & 22 deletions src/coreclr/vm/interpexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,30 +298,24 @@ CallStubHeader *CreateNativeToInterpreterCallStub(InterpMethod* pInterpMethod)
{
CallStubGenerator callStubGenerator;
CallStubHeader *pHeader = VolatileLoadWithoutBarrier(&pInterpMethod->pCallStub);
GCX_PREEMP();

if (pHeader == NULL)
if (pHeader != NULL)
{
// Ensure that there is an interpreter thread context instance and thus an interpreter stack
// allocated for this thread. This allows us to not to have to check and allocate it from
// the interpreter stub right after this call.
GetThread()->GetInterpThreadContext();

GCX_PREEMP();
return pHeader;
}
GCX_PREEMP();

AllocMemTracker amTracker;
pHeader = callStubGenerator.GenerateCallStub((MethodDesc*)pInterpMethod->methodHnd, &amTracker, false /* interpreterToNative */);
AllocMemTracker amTracker;
pHeader = callStubGenerator.GenerateCallStub(pInterpMethod->methodDesc, &amTracker, false /* interpreterToNative */);

if (InterlockedCompareExchangeT(&pInterpMethod->pCallStub, pHeader, NULL) == NULL)
{
amTracker.SuppressRelease();
}
else
{
// We have lost the race for generating the header, use the one that was generated by another thread
// and let the amTracker release the memory of the one we generated.
pHeader = VolatileLoadWithoutBarrier(&pInterpMethod->pCallStub);
}
if (InterlockedCompareExchangeT(&pInterpMethod->pCallStub, pHeader, NULL) == NULL)
{
amTracker.SuppressRelease();
}
else
{
// We have lost the race for generating the header, use the one that was generated by another thread
// and let the amTracker release the memory of the one we generated.
pHeader = VolatileLoadWithoutBarrier(&pInterpMethod->pCallStub);
}

return pHeader;
Expand Down Expand Up @@ -352,7 +346,7 @@ void DBG_PrintInterpreterStack()
InterpMethodContextFrame* cxtFrame = pInterpFrame->GetTopInterpMethodContextFrame();
while (cxtFrame != NULL)
{
MethodDesc* currentMD = ((MethodDesc*)cxtFrame->startIp->Method->methodHnd);
MethodDesc* currentMD = cxtFrame->startIp->Method->methodDesc;

size_t irOffset = ((size_t)cxtFrame->ip - (size_t)(&cxtFrame->startIp[1])) / sizeof(size_t);
fprintf(stderr, "%4d) %s::%s, IR_%04zx\n",
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/precode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ TADDR InterpreterPrecode::GetMethodDesc()
LIMITED_METHOD_DAC_CONTRACT;

InterpByteCodeStart* pInterpreterCode = dac_cast<PTR_InterpByteCodeStart>(GetData()->ByteCodeAddr);
return (TADDR)pInterpreterCode->Method->methodHnd;
return dac_cast<TADDR>(pInterpreterCode->Method->methodDesc);
}
#endif // FEATURE_INTERPRETER

Expand Down
8 changes: 0 additions & 8 deletions src/coreclr/vm/prestub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2433,14 +2433,6 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo
pCode = DoBackpatch(pMT, pDispatchingMT, false /* doFullBackpatch */);

Return:
// Interpreter-FIXME: Call stubs are not yet supported on WASM
#if defined(FEATURE_INTERPRETER) && !defined(TARGET_WASM)
InterpByteCodeStart *pInterpreterCode = GetInterpreterCode();
if (pInterpreterCode != NULL)
{
CreateNativeToInterpreterCallStub(pInterpreterCode->Method);
}
#endif // FEATURE_INTERPRETER && !TARGET_WASM

RETURN pCode;
}
Expand Down
Loading
Loading