From: sergey ignatov Date: Sat, 1 Sep 2018 14:40:44 +0000 (+0300) Subject: i386: Fixed definition with declaration in eetoprofinterfaceimpl.cpp (dotnet/coreclr... X-Git-Tag: submit/tizen/20210909.063632~11030^2~3991 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fd1eadb6e3cae1635b9597e8d01600221f14899a;p=platform%2Fupstream%2Fdotnet%2Fruntime.git i386: Fixed definition with declaration in eetoprofinterfaceimpl.cpp (dotnet/coreclr#18792) Commit migrated from https://github.com/dotnet/coreclr/commit/a1757ce8e80cd089d9dc31ba2d4e3246e387a6b8 --- diff --git a/docs/coreclr/botr/clr-abi.md b/docs/coreclr/botr/clr-abi.md index ea5a49e..0a40b41 100644 --- a/docs/coreclr/botr/clr-abi.md +++ b/docs/coreclr/botr/clr-abi.md @@ -599,6 +599,8 @@ For AMD64, all probes receive a second parameter (passed in `RDX` according to t TODO: describe ARM64 tail call convention. +On Linux/x86 the profiling hooks are declared with the ```__cdecl``` attribute. In cdecl (which stands for C declaration), subroutine arguments are passed on the stack. Integer values and memory addresses are returned in the EAX register, floating point values in the ST0 x87 register. Registers EAX, ECX, and EDX are caller-saved, and the rest are callee-saved. The x87 floating point registers ST0 to ST7 must be empty (popped or freed) when calling a new function, and ST1 to ST7 must be empty on exiting a function. ST0 must also be empty when not used for returning a value. Returned values of managed-code are formed before the leave/tailcall profiling hooks, so they should be saved in these hooks and restored on returning from them. The instruction ```ret``` for assembler implementations of profiling hooks should be without a parameter. + JIT32 only generates one epilog (and causes all returns to branch to it) when there are profiler hooks. # Synchronized Methods diff --git a/src/coreclr/src/inc/corprof.idl b/src/coreclr/src/inc/corprof.idl index 7766bf9..feeac08 100644 --- a/src/coreclr/src/inc/corprof.idl +++ b/src/coreclr/src/inc/corprof.idl @@ -125,6 +125,8 @@ import "wtypes.idl"; import "unknwn.idl"; #endif +#define STDMETHODCALLTYPE + typedef UINT_PTR ProcessID; typedef UINT_PTR AssemblyID; typedef UINT_PTR AppDomainID; @@ -303,13 +305,13 @@ typedef struct _COR_PRF_METHOD * bits cleared for COR_PRF_ENABLE_FRAME_INFO, COR_PRF_ENABLE_FUNCTION_RETVAL * and COR_PRF_ENABLE_FUNCTION_ARGS. */ -typedef void __stdcall FunctionEnter( +typedef void STDMETHODCALLTYPE FunctionEnter( FunctionID funcID); -typedef void __stdcall FunctionLeave( +typedef void STDMETHODCALLTYPE FunctionLeave( FunctionID funcID); -typedef void __stdcall FunctionTailcall( +typedef void STDMETHODCALLTYPE FunctionTailcall( FunctionID funcID); /* @@ -320,19 +322,19 @@ typedef void __stdcall FunctionTailcall( * functionality, use the FunctionEnter3/Leave3/Tailcall3 callbacks. */ -typedef void __stdcall FunctionEnter2( +typedef void STDMETHODCALLTYPE FunctionEnter2( FunctionID funcId, UINT_PTR clientData, COR_PRF_FRAME_INFO func, COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo); -typedef void __stdcall FunctionLeave2( +typedef void STDMETHODCALLTYPE FunctionLeave2( FunctionID funcId, UINT_PTR clientData, COR_PRF_FRAME_INFO func, COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange); -typedef void __stdcall FunctionTailcall2( +typedef void STDMETHODCALLTYPE FunctionTailcall2( FunctionID funcId, UINT_PTR clientData, COR_PRF_FRAME_INFO func); @@ -348,13 +350,13 @@ typedef void __stdcall FunctionTailcall2( * true FunctionID of the function. */ -typedef void __stdcall FunctionEnter3( +typedef void STDMETHODCALLTYPE FunctionEnter3( FunctionIDOrClientID functionIDOrClientID); -typedef void __stdcall FunctionLeave3( +typedef void STDMETHODCALLTYPE FunctionLeave3( FunctionIDOrClientID functionIDOrClientID); -typedef void __stdcall FunctionTailcall3( +typedef void STDMETHODCALLTYPE FunctionTailcall3( FunctionIDOrClientID functionIDOrClientID); /* @@ -371,15 +373,15 @@ typedef void __stdcall FunctionTailcall3( * It is only valid during the callback to which it is passed. */ -typedef void __stdcall FunctionEnter3WithInfo( +typedef void STDMETHODCALLTYPE FunctionEnter3WithInfo( FunctionIDOrClientID functionIDOrClientID, COR_PRF_ELT_INFO eltInfo); -typedef void __stdcall FunctionLeave3WithInfo( +typedef void STDMETHODCALLTYPE FunctionLeave3WithInfo( FunctionIDOrClientID functionIDOrClientID, COR_PRF_ELT_INFO eltInfo); -typedef void __stdcall FunctionTailcall3WithInfo( +typedef void STDMETHODCALLTYPE FunctionTailcall3WithInfo( FunctionIDOrClientID functionIDOrClientID, COR_PRF_ELT_INFO eltInfo); diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index b1b780f..c967892 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -2436,16 +2436,20 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode) #endif #if EMIT_TRACK_STACK_DEPTH - /* Check our max stack level. Needed for fgAddCodeRef(). - We need to relax the assert as our estimation won't include code-gen - stack changes (which we know don't affect fgAddCodeRef()) */ + // Check our max stack level. Needed for fgAddCodeRef(). + // We need to relax the assert as our estimation won't include code-gen + // stack changes (which we know don't affect fgAddCodeRef()). + // NOTE: after emitEndCodeGen (including here), emitMaxStackDepth is a + // count of DWORD-sized arguments, NOT argument size in bytes. { unsigned maxAllowedStackDepth = compiler->fgPtrArgCntMax + // Max number of pointer-sized stack arguments. compiler->compHndBBtabCount + // Return address for locally-called finallys genTypeStSz(TYP_LONG) + // longs/doubles may be transferred via stack, etc (compiler->compTailCallUsed ? 4 : 0); // CORINFO_HELP_TAILCALL args #if defined(UNIX_X86_ABI) - maxAllowedStackDepth += maxNestedAlignment; + // Convert maxNestedAlignment to DWORD count before adding to maxAllowedStackDepth. + assert(maxNestedAlignment % sizeof(int) == 0); + maxAllowedStackDepth += maxNestedAlignment / sizeof(int); #endif noway_assert(getEmitter()->emitMaxStackDepth <= maxAllowedStackDepth); } @@ -6926,8 +6930,13 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) unsigned saveStackLvl2 = genStackLevel; #if defined(_TARGET_X86_) - // Important note: when you change enter probe layout, you must also update SKIP_ENTER_PROF_CALLBACK() - // for x86 stack unwinding +// Important note: when you change enter probe layout, you must also update SKIP_ENTER_PROF_CALLBACK() +// for x86 stack unwinding + +#if defined(UNIX_X86_ABI) + // Manually align the stack to be 16-byte aligned. This is similar to CodeGen::genAlignStackBeforeCall() + getEmitter()->emitIns_R_I(INS_sub, EA_4BYTE, REG_SPBASE, 0xC); +#endif // UNIX_X86_ABI // Push the profilerHandle if (compiler->compProfilerMethHndIndirected) @@ -6938,6 +6947,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) { inst_IV(INS_push, (size_t)compiler->compProfilerMethHnd); } + #elif defined(_TARGET_ARM_) // On Arm arguments are prespilled on stack, which frees r0-r3. // For generating Enter callout we would need two registers and one of them has to be r0 to pass profiler handle. @@ -6974,6 +6984,12 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) #if defined(_TARGET_X86_) // Check that we have place for the push. assert(compiler->fgPtrArgCntMax >= 1); + +#if defined(UNIX_X86_ABI) + // Restoring alignment manually. This is similar to CodeGen::genRemoveAlignmentAfterCall + getEmitter()->emitIns_R_I(INS_add, EA_4BYTE, REG_SPBASE, 0x10); +#endif // UNIX_X86_ABI + #elif defined(_TARGET_ARM_) if (initReg == argReg) { @@ -7148,6 +7164,13 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC #elif defined(_TARGET_X86_) +#if defined(UNIX_X86_ABI) + // Manually align the stack to be 16-byte aligned. This is similar to CodeGen::genAlignStackBeforeCall() + getEmitter()->emitIns_R_I(INS_sub, EA_4BYTE, REG_SPBASE, 0xC); + AddStackLevel(0xC); + AddNestedAlignment(0xC); +#endif // UNIX_X86_ABI + // // Push the profilerHandle // @@ -7162,13 +7185,23 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC } genSinglePush(); - genEmitHelperCall(helper, - sizeof(int) * 1, // argSize - EA_UNKNOWN); // retSize +#if defined(UNIX_X86_ABI) + int argSize = -REGSIZE_BYTES; // negative means caller-pop (cdecl) +#else + int argSize = REGSIZE_BYTES; +#endif + genEmitHelperCall(helper, argSize, EA_UNKNOWN /* retSize */); // Check that we have place for the push. assert(compiler->fgPtrArgCntMax >= 1); +#if defined(UNIX_X86_ABI) + // Restoring alignment manually. This is similar to CodeGen::genRemoveAlignmentAfterCall + getEmitter()->emitIns_R_I(INS_add, EA_4BYTE, REG_SPBASE, 0x10); + SubtractStackLevel(0x10); + SubtractNestedAlignment(0xC); +#endif // UNIX_X86_ABI + #elif defined(_TARGET_ARM_) // // Push the profilerHandle diff --git a/src/coreclr/src/pal/prebuilt/inc/corprof.h b/src/coreclr/src/pal/prebuilt/inc/corprof.h index 06adddc..2e18c12 100644 --- a/src/coreclr/src/pal/prebuilt/inc/corprof.h +++ b/src/coreclr/src/pal/prebuilt/inc/corprof.h @@ -438,50 +438,50 @@ typedef struct _COR_PRF_METHOD mdMethodDef methodId; } COR_PRF_METHOD; -typedef void __stdcall __stdcall FunctionEnter( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionEnter( FunctionID funcID); -typedef void __stdcall __stdcall FunctionLeave( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionLeave( FunctionID funcID); -typedef void __stdcall __stdcall FunctionTailcall( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionTailcall( FunctionID funcID); -typedef void __stdcall __stdcall FunctionEnter2( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionEnter2( FunctionID funcId, UINT_PTR clientData, COR_PRF_FRAME_INFO func, COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo); -typedef void __stdcall __stdcall FunctionLeave2( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionLeave2( FunctionID funcId, UINT_PTR clientData, COR_PRF_FRAME_INFO func, COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange); -typedef void __stdcall __stdcall FunctionTailcall2( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionTailcall2( FunctionID funcId, UINT_PTR clientData, COR_PRF_FRAME_INFO func); -typedef void __stdcall __stdcall FunctionEnter3( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionEnter3( FunctionIDOrClientID functionIDOrClientID); -typedef void __stdcall __stdcall FunctionLeave3( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionLeave3( FunctionIDOrClientID functionIDOrClientID); -typedef void __stdcall __stdcall FunctionTailcall3( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionTailcall3( FunctionIDOrClientID functionIDOrClientID); -typedef void __stdcall __stdcall FunctionEnter3WithInfo( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionEnter3WithInfo( FunctionIDOrClientID functionIDOrClientID, COR_PRF_ELT_INFO eltInfo); -typedef void __stdcall __stdcall FunctionLeave3WithInfo( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionLeave3WithInfo( FunctionIDOrClientID functionIDOrClientID, COR_PRF_ELT_INFO eltInfo); -typedef void __stdcall __stdcall FunctionTailcall3WithInfo( +typedef void STDMETHODCALLTYPE STDMETHODCALLTYPE FunctionTailcall3WithInfo( FunctionIDOrClientID functionIDOrClientID, COR_PRF_ELT_INFO eltInfo); diff --git a/src/coreclr/src/vm/amd64/unixstubs.cpp b/src/coreclr/src/vm/amd64/unixstubs.cpp index 83764e0..e592193 100644 --- a/src/coreclr/src/vm/amd64/unixstubs.cpp +++ b/src/coreclr/src/vm/amd64/unixstubs.cpp @@ -53,8 +53,8 @@ extern "C" // check OS has enabled both XMM and YMM state support return ((eax & 0x06) == 0x06) ? 1 : 0; } - - void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle) + + void STDMETHODCALLTYPE JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle) { } }; diff --git a/src/coreclr/src/vm/arm64/stubs.cpp b/src/coreclr/src/vm/arm64/stubs.cpp index 38779b7..248a103 100644 --- a/src/coreclr/src/vm/arm64/stubs.cpp +++ b/src/coreclr/src/vm/arm64/stubs.cpp @@ -1071,7 +1071,7 @@ void emitCOMStubCall (ComCallMethodDesc *pCOMMethod, PCODE target) #endif // FEATURE_COMINTEROP -void JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle) +void STDMETHODCALLTYPE JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle) { _ASSERTE(!"ARM64:NYI"); } diff --git a/src/coreclr/src/vm/eetoprofinterfaceimpl.cpp b/src/coreclr/src/vm/eetoprofinterfaceimpl.cpp index a9975c3..1f22386 100644 --- a/src/coreclr/src/vm/eetoprofinterfaceimpl.cpp +++ b/src/coreclr/src/vm/eetoprofinterfaceimpl.cpp @@ -2071,9 +2071,9 @@ HRESULT EEToProfInterfaceImpl::EnsureProfilerDetachable() } // Declarations for asm wrappers of profiler callbacks -EXTERN_C void __stdcall ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID); -EXTERN_C void __stdcall ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID); -EXTERN_C void __stdcall ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID); +EXTERN_C void STDMETHODCALLTYPE ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID); +EXTERN_C void STDMETHODCALLTYPE ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID); +EXTERN_C void STDMETHODCALLTYPE ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID); #define PROFILECALLBACK(name) name##Naked //--------------------------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/i386/asmhelpers.S b/src/coreclr/src/vm/i386/asmhelpers.S index 480eb2d..2052088 100644 --- a/src/coreclr/src/vm/i386/asmhelpers.S +++ b/src/coreclr/src/vm/i386/asmhelpers.S @@ -1225,3 +1225,19 @@ NESTED_ENTRY BackPatchWorkerAsmStub, _TEXT, NoHandler EPILOG_END ret NESTED_END BackPatchWorkerAsmStub, _TEXT + +NESTED_ENTRY ProfileEnterNaked, _TEXT, NoHandler + ret +NESTED_END ProfileEnterNaked, _TEXT + +NESTED_ENTRY ProfileLeaveNaked, _TEXT, NoHandler + ret +NESTED_END ProfileLeaveNaked, _TEXT + +NESTED_ENTRY ProfileTailcallNaked, _TEXT, NoHandler + ret +NESTED_END ProfileTailcallNaked, _TEXT + +NESTED_ENTRY JIT_ProfilerEnterLeaveTailcallStub, _TEXT, NoHandler + ret +NESTED_END JIT_ProfilerEnterLeaveTailcallStub, _TEXT diff --git a/src/coreclr/src/vm/i386/unixstubs.cpp b/src/coreclr/src/vm/i386/unixstubs.cpp index 2a7b3af..8167476 100644 --- a/src/coreclr/src/vm/i386/unixstubs.cpp +++ b/src/coreclr/src/vm/i386/unixstubs.cpp @@ -4,28 +4,6 @@ #include "common.h" -extern "C" -{ - void ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID) - { - PORTABILITY_ASSERT("Implement for PAL"); - } - - void ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID) - { - PORTABILITY_ASSERT("Implement for PAL"); - } - - void ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID) - { - PORTABILITY_ASSERT("Implement for PAL"); - } - - void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle) - { - } -}; - EXTERN_C VOID JIT_TailCall() { PORTABILITY_ASSERT("JIT_TailCall"); diff --git a/src/coreclr/src/vm/jitinterface.h b/src/coreclr/src/vm/jitinterface.h index ebe64ed..b4cfa20 100644 --- a/src/coreclr/src/vm/jitinterface.h +++ b/src/coreclr/src/vm/jitinterface.h @@ -423,7 +423,7 @@ extern "C" void STDCALL JIT_MemSet(void *dest, int c, SIZE_T count); void STDCALL JIT_MemCpy(void *dest, const void *src, SIZE_T count); - void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle); + void STDMETHODCALLTYPE JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle); }; diff --git a/src/coreclr/src/vm/profilinghelper.cpp b/src/coreclr/src/vm/profilinghelper.cpp index 03d4332..a7c64e7 100644 --- a/src/coreclr/src/vm/profilinghelper.cpp +++ b/src/coreclr/src/vm/profilinghelper.cpp @@ -460,9 +460,9 @@ void ProfilingAPIUtility::LogProfInfo(int iStringResourceID, ...) // InitializeProfiling() below solely for the debug-only, test-only code to allow // enter/leave/tailcall to be turned on at startup without a profiler. See // code:ProfControlBlock#TestOnlyELT -EXTERN_C void __stdcall ProfileEnterNaked(UINT_PTR clientData); -EXTERN_C void __stdcall ProfileLeaveNaked(UINT_PTR clientData); -EXTERN_C void __stdcall ProfileTailcallNaked(UINT_PTR clientData); +EXTERN_C void STDMETHODCALLTYPE ProfileEnterNaked(UINT_PTR clientData); +EXTERN_C void STDMETHODCALLTYPE ProfileLeaveNaked(UINT_PTR clientData); +EXTERN_C void STDMETHODCALLTYPE ProfileTailcallNaked(UINT_PTR clientData); #endif //PROF_TEST_ONLY_FORCE_ELT // ----------------------------------------------------------------------------