diff options
author | Brian Sullivan <briansul@microsoft.com> | 2019-03-20 16:43:53 -0700 |
---|---|---|
committer | Brian Sullivan <briansul@microsoft.com> | 2019-03-20 16:43:53 -0700 |
commit | 8e1882ee40cda54233cbdb4d5d47e9825978ddb5 (patch) | |
tree | 36dc6b19fd0ff72aa97a995e97f32211e4f30dc0 | |
parent | b2c397b649181f793d6c29f1de78d0aee0a52596 (diff) | |
parent | 69dc790d171783584f5af3a5da60a25e2c301899 (diff) | |
download | coreclr-8e1882ee40cda54233cbdb4d5d47e9825978ddb5.tar.gz coreclr-8e1882ee40cda54233cbdb4d5d47e9825978ddb5.tar.bz2 coreclr-8e1882ee40cda54233cbdb4d5d47e9825978ddb5.zip |
Merge branch 'master' into hva-tests
26 files changed, 876 insertions, 141 deletions
diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5016d7514a..9711bb7271 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -108,6 +108,13 @@ jobs: parameters: jobTemplate: build-job.yml buildConfig: checked + ${{ if eq(variables['Build.DefinitionName'], 'coreclr-outerloop-gcstress0x3-gcstress0xc') }}: + platforms: + - Linux_arm + - Linux_arm64 + - Linux_x64 + - Windows_NT_x64 + - Windows_NT_x86 # # Release build (Pull request) @@ -142,6 +149,13 @@ jobs: parameters: jobTemplate: test-job.yml buildConfig: checked + ${{ if eq(variables['Build.DefinitionName'], 'coreclr-outerloop-gcstress0x3-gcstress0xc') }}: + platforms: + - Linux_arm + - Linux_arm64 + - Linux_x64 + - Windows_NT_x64 + - Windows_NT_x86 jobParameters: ${{ if eq(variables['Build.DefinitionName'], 'coreclr-ci') }}: testGroup: innerloop diff --git a/eng/build-job.yml b/eng/build-job.yml index 7e9f631c01..1d3cde4baf 100644 --- a/eng/build-job.yml +++ b/eng/build-job.yml @@ -195,10 +195,3 @@ jobs: targetPath: $(Build.SourcesDirectory)/bin/Logs continueOnError: true condition: always() - - # Kill tasks that hold onto files on Windows. Otherwise git clean - # may fail for later jobs on the same agent. - - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - - script: eng/kill_tasks.cmd - displayName: Kill tasks that hold on to files - condition: always() diff --git a/eng/kill_tasks.cmd b/eng/kill_tasks.cmd deleted file mode 100644 index ee7099c94d..0000000000 --- a/eng/kill_tasks.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@if not defined _echo @echo off -setlocal EnableDelayedExpansion - -:: Check if VBCSCompiler.exe is running -tasklist /fi "imagename eq VBCSCompiler.exe" |find ":" > nul -:: Compiler is running if errorlevel == 1 -if errorlevel 1 ( - echo Stop VBCSCompiler.exe execution. - for /f "tokens=2 delims=," %%F in ('tasklist /nh /fi "imagename eq VBCSCompiler.exe" /fo csv') do taskkill /f /PID %%~F -) diff --git a/src/dlls/mscorrc/mscorrc.rc b/src/dlls/mscorrc/mscorrc.rc index 517c548bd7..8e272ad2af 100644 --- a/src/dlls/mscorrc/mscorrc.rc +++ b/src/dlls/mscorrc/mscorrc.rc @@ -557,6 +557,7 @@ BEGIN IDS_EE_BADMARSHAL_DECIMALARRAY "Invalid managed/unmanaged type combination (Decimal[] must be paired with an ArraySubType of Struct or Currency)." IDS_EE_BADMARSHAL_WINRT_MARSHAL_AS "Invalid managed/unmanaged type combination (Windows Runtime parameters and fields must not have a MarshalAs attribute set)." IDS_EE_BADMARSHAL_WINRT_MISSING_GUID "Invalid managed/unmanaged type combination (Windows Runtime interfaces, classes and delegates must have a Guid or a default interface)." + IDS_EE_BADMARSHAL_WINRT_COPYCTOR "Windows Runtime marshaler does not support types with copy constructor." IDS_EE_BADMARSHAL_WINRT_DELEGATE "Invalid managed/unmanaged type combination (Delegates must be Windows Runtime delegates)." IDS_EE_BADMARSHAL_DEFAULTIFACE_NOT_WINRT_IFACE "The default interface must refer to a Windows Runtime interface with a GUID." IDS_EE_BADMARSHAL_DEFAULTIFACE_NOT_SUBTYPE "The default interface must refer to an interface that is implemented by the type." @@ -611,6 +612,7 @@ BEGIN IDS_EE_BADMARSHAL_ASANYRESTRICTION "AsAny cannot be used on return types, ByRef parameters, ArrayWithOffset, or parameters passed from unmanaged to managed." IDS_EE_BADMARSHAL_VBBYVALSTRRESTRICTION "VBByRefStr can only be used in combination with in/out, ByRef managed-to-unmanaged strings." IDS_EE_BADMARSHAL_AWORESTRICTION "ArrayWithOffsets can only be marshaled as inout, non-ByRef, managed-to-unmanaged parameters." + IDS_EE_BADMARSHAL_COPYCTORRESTRICTION "Classes with copy-ctors can only be marshaled by value." IDS_EE_BADMARSHAL_ARGITERATORRESTRICTION "ArgIterators cannot be marshaled ByRef." IDS_EE_BADMARSHAL_HANDLEREFRESTRICTION "HandleRefs cannot be marshaled ByRef or from unmanaged to managed." IDS_EE_BADMARSHAL_SAFEHANDLENATIVETOCOM "SafeHandles cannot be marshaled from unmanaged to managed." diff --git a/src/dlls/mscorrc/resource.h b/src/dlls/mscorrc/resource.h index cec39bbb30..a7d94874f4 100644 --- a/src/dlls/mscorrc/resource.h +++ b/src/dlls/mscorrc/resource.h @@ -718,3 +718,5 @@ #define IDS_EE_NDIRECT_GETPROCADDR_WIN_DLL 0x2644 #define IDS_EE_NDIRECT_GETPROCADDR_UNIX_SO 0x2645 #define IDS_EE_BADMARSHAL_STRING_OUT 0x2646 +#define IDS_EE_BADMARSHAL_COPYCTORRESTRICTION 0x2647 +#define IDS_EE_BADMARSHAL_WINRT_COPYCTOR 0x2648 diff --git a/src/jit/codegen.h b/src/jit/codegen.h index be20865c0e..11c81c4b91 100644 --- a/src/jit/codegen.h +++ b/src/jit/codegen.h @@ -561,8 +561,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX siVarLoc* varLoc); void genSetScopeInfo(); +#ifdef USING_SCOPE_INFO + void genSetScopeInfoUsingsiScope(); -protected: /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX @@ -668,7 +669,6 @@ public: const char* siStackVarName(size_t offs, size_t size, unsigned reg, unsigned stkOffs); #endif // LATE_DISASM -public: /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX @@ -749,14 +749,16 @@ protected: void psiEndPrologScope(psiScope* scope); void psSetScopeOffset(psiScope* newScope, LclVarDsc* lclVarDsc1); +#endif // USING_SCOPE_INFO -/***************************************************************************** - * TrnslLocalVarInfo - * - * This struct holds the LocalVarInfo in terms of the generated native code - * after a call to genSetScopeInfo() - */ + /***************************************************************************** + * TrnslLocalVarInfo + * + * This struct holds the LocalVarInfo in terms of the generated native code + * after a call to genSetScopeInfo() + */ +protected: #ifdef DEBUG struct TrnslLocalVarInfo diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp index 50180133d4..0c84bedb75 100644 --- a/src/jit/codegenarmarch.cpp +++ b/src/jit/codegenarmarch.cpp @@ -3860,11 +3860,12 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni #ifdef _TARGET_ARM_ compiler->unwindAllocStack(frameSize); - +#ifdef USING_SCOPE_INFO if (!doubleAlignOrFramePointerUsed()) { psiAdjustStackLevel(frameSize); } +#endif // USING_SCOPE_INFO #endif // _TARGET_ARM_ } diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp index b90cf5548d..2b5236b82a 100644 --- a/src/jit/codegencommon.cpp +++ b/src/jit/codegencommon.cpp @@ -732,8 +732,9 @@ void Compiler::compChangeLife(VARSET_VALARG_TP newLife) JITDUMP("\t\t\t\t\t\t\tV%02u becoming live\n", varNum); } } - +#ifdef USING_SCOPE_INFO codeGen->siUpdate(); +#endif // USING_SCOPE_INFO } // Need an explicit instantiation. @@ -3804,11 +3805,12 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere assert(varDsc->lvSize() >= baseOffset + (unsigned)size); } #endif // !UNIX_AMD64_ABI - +#ifdef USING_SCOPE_INFO if (regArgTab[argNum].slot == 1) { psiMoveToStack(varNum); } +#endif // USING_SCOPE_INFO } /* mark the argument as processed */ @@ -3952,9 +3954,10 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere regArgMaskLive &= ~genRegMask(varDscSrc->lvArgReg); regArgMaskLive &= ~genRegMask(varDscDest->lvArgReg); - +#ifdef USING_SCOPE_INFO psiMoveToReg(varNumSrc); psiMoveToReg(varNumDest); +#endif // USING_SCOPE_INFO } else #endif // _TARGET_XARCH_ @@ -4016,9 +4019,9 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere regSet.verifyRegUsed(xtraReg); *pXtraRegClobbered = true; - +#ifdef USING_SCOPE_INFO psiMoveToReg(varNumDest, xtraReg); - +#endif // USING_SCOPE_INFO /* start moving everything to its right place */ while (srcReg != begReg) @@ -4083,9 +4086,9 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere getEmitter()->emitIns_R_R(insCopy, size, destRegNum, xtraReg); regSet.verifyRegUsed(destRegNum); - +#ifdef USING_SCOPE_INFO psiMoveToReg(varNumSrc); - +#endif // USING_SCOPE_INFO /* mark the beginning register as processed */ regArgTab[srcReg].processed = true; @@ -4269,8 +4272,9 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere #endif getEmitter()->emitIns_R_R(ins_Copy(destMemType), size, destRegNum, regNum); - +#ifdef USING_SCOPE_INFO psiMoveToReg(varNum); +#endif // USING_SCOPE_INFO } /* mark the argument as processed */ @@ -4404,8 +4408,9 @@ void CodeGen::genEnregisterIncomingStackArgs() getEmitter()->emitIns_R_S(ins_Load(type), emitTypeSize(type), regNum, varNum, 0); regSet.verifyRegUsed(regNum); - +#ifdef USING_SCOPE_INFO psiMoveToReg(varNum); +#endif // USING_SCOPE_INFO } } @@ -5247,12 +5252,12 @@ void CodeGen::genPushCalleeSavedRegisters() { inst_RV(INS_push, reg, TYP_REF); compiler->unwindPush(reg); - +#ifdef USING_SCOPE_INFO if (!doubleAlignOrFramePointerUsed()) { psiAdjustStackLevel(REGSIZE_BYTES); } - +#endif // USING_SCOPE_INFO rsPushRegs &= ~regBit; } } @@ -7531,7 +7536,9 @@ void CodeGen::genEstablishFramePointer(int delta, bool reportUnwindData) if (delta == 0) { getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_FPBASE, REG_SPBASE); +#ifdef USING_SCOPE_INFO psiMoveESPtoEBP(); +#endif // USING_SCOPE_INFO } else { @@ -7633,12 +7640,13 @@ void CodeGen::genFnProlog() printf("\n__prolog:\n"); } #endif - +#ifdef USING_SCOPE_INFO if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0)) { // Create new scopes for the method-parameters for the prolog-block. psiBegProlog(); } +#endif // USING_SCOPE_INFO #ifdef DEBUG @@ -7963,8 +7971,9 @@ void CodeGen::genFnProlog() { inst_RV(INS_push, REG_FPBASE, TYP_REF); compiler->unwindPush(REG_FPBASE); +#ifdef USING_SCOPE_INFO psiAdjustStackLevel(REGSIZE_BYTES); - +#endif // USING_SCOPE_INFO #ifndef _TARGET_AMD64_ // On AMD64, establish the frame pointer after the "sub rsp" genEstablishFramePointer(0, /*reportUnwindData*/ true); #endif // !_TARGET_AMD64_ @@ -8284,12 +8293,12 @@ void CodeGen::genFnProlog() genPrologPadForReJit(); getEmitter()->emitMarkPrologEnd(); } - +#ifdef USING_SCOPE_INFO if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0)) { psiEndProlog(); } - +#endif // USING_SCOPE_INFO if (hasGCRef) { getEmitter()->emitSetFrameRangeGCRs(GCrefLo, GCrefHi); @@ -10486,27 +10495,40 @@ void CodeGen::genSetScopeInfo() } noway_assert(compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0)); - noway_assert(psiOpenScopeList.scNext == nullptr); - - unsigned i; - unsigned scopeCnt = siScopeCnt + psiScopeCnt; - compiler->eeSetLVcount(scopeCnt); + unsigned varsHomeCount = 0; +#ifdef USING_SCOPE_INFO + varsHomeCount = siScopeCnt + psiScopeCnt; +#endif // USING_SCOPE_INFO + compiler->eeSetLVcount(varsHomeCount); #ifdef DEBUG - genTrnslLocalVarCount = scopeCnt; - if (scopeCnt) + genTrnslLocalVarCount = varsHomeCount; + if (varsHomeCount) { - genTrnslLocalVarInfo = new (compiler, CMK_DebugOnly) TrnslLocalVarInfo[scopeCnt]; + genTrnslLocalVarInfo = new (compiler, CMK_DebugOnly) TrnslLocalVarInfo[varsHomeCount]; } #endif +#ifdef USING_SCOPE_INFO + genSetScopeInfoUsingsiScope(); +#endif // USING_SCOPE_INFO + + compiler->eeSetLVdone(); +} + +#ifdef USING_SCOPE_INFO +void CodeGen::genSetScopeInfoUsingsiScope() +{ + noway_assert(psiOpenScopeList.scNext == nullptr); + // Record the scopes found for the parameters over the prolog. // The prolog needs to be treated differently as a variable may not // have the same info in the prolog block as is given by compiler->lvaTable. // eg. A register parameter is actually on the stack, before it is loaded to reg. CodeGen::psiScope* scopeP; + unsigned i; for (i = 0, scopeP = psiScopeList.scNext; i < psiScopeCnt; i++, scopeP = scopeP->scNext) { @@ -10563,9 +10585,8 @@ void CodeGen::genSetScopeInfo() genSetScopeInfo(psiScopeCnt + i, startOffs, endOffs - startOffs, scopeL->scVarNum, scopeL->scLVnum, scopeL->scAvailable, &varLoc); } - - compiler->eeSetLVdone(); } +#endif // USING_SCOPE_INFO //------------------------------------------------------------------------ // genSetScopeInfo: Record scope information for debug info diff --git a/src/jit/codegeninterface.h b/src/jit/codegeninterface.h index 94fd8f4635..9a67649084 100644 --- a/src/jit/codegeninterface.h +++ b/src/jit/codegeninterface.h @@ -25,6 +25,12 @@ #include "jitgcinfo.h" #include "treelifeupdater.h" +// Disable this flag to avoid using psiScope/siScope info to report reporting +// variables' home location during the method/prolog code. +#if 1 +#define USING_SCOPE_INFO +#endif // USING_SCOPE_INFO + // Forward reference types class CodeGenInterface; @@ -385,7 +391,9 @@ private: bool m_cgFullPtrRegMap; public: +#ifdef USING_SCOPE_INFO virtual void siUpdate() = 0; +#endif // USING_SCOPE_INFO /* These are the different addressing modes used to access a local var. * The JIT has to report the location of the locals back to the EE diff --git a/src/jit/codegenlinear.cpp b/src/jit/codegenlinear.cpp index 149bb3333f..c0a20343a3 100644 --- a/src/jit/codegenlinear.cpp +++ b/src/jit/codegenlinear.cpp @@ -84,12 +84,13 @@ void CodeGen::genInitializeRegisterState() // iterated. void CodeGen::genInitialize() { +#ifdef USING_SCOPE_INFO // Initialize the line# tracking logic - if (compiler->opts.compScopeInfo) { siInit(); } +#endif // USING_SCOPE_INFO // The current implementation of switch tables requires the first block to have a label so it // can generate offsets to the switch label targets. @@ -350,9 +351,9 @@ void CodeGen::genCodeForBBlist() /* Tell everyone which basic block we're working on */ compiler->compCurBB = block; - +#ifdef USING_SCOPE_INFO siBeginBlock(block); - +#endif // USING_SCOPE_INFO // BBF_INTERNAL blocks don't correspond to any single IL instruction. if (compiler->opts.compDbgInfo && (block->bbFlags & BBF_INTERNAL) && !compiler->fgBBisScratch(block)) // If the block is the distinguished first scratch block, then no need to @@ -508,7 +509,7 @@ void CodeGen::genCodeForBBlist() // This can lead to problems when debugging the generated code. To prevent these issues, make sure // we've generated code for the last IL offset we saw in the block. genEnsureCodeEmitted(currentILOffset); - +#ifdef USING_SCOPE_INFO if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0)) { siEndBlock(block); @@ -533,6 +534,7 @@ void CodeGen::genCodeForBBlist() siCloseAllOpenScopes(); } } +#endif // USING_SCOPE_INFO SubtractStackLevel(savedStkLvl); diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp index f332b0043a..9256650978 100644 --- a/src/jit/codegenxarch.cpp +++ b/src/jit/codegenxarch.cpp @@ -2333,11 +2333,12 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni } compiler->unwindAllocStack(frameSize); - +#ifdef USING_SCOPE_INFO if (!doubleAlignOrFramePointerUsed()) { psiAdjustStackLevel(frameSize); } +#endif // USING_SCOPE_INFO } //------------------------------------------------------------------------ diff --git a/src/jit/scopeinfo.cpp b/src/jit/scopeinfo.cpp index 3a47a32453..9e8d6b911c 100644 --- a/src/jit/scopeinfo.cpp +++ b/src/jit/scopeinfo.cpp @@ -131,30 +131,6 @@ bool CodeGenInterface::siVarLoc::vlIsOnStk(regNumber reg, signed offset) const } //------------------------------------------------------------------------ -// siVarLoc: Non-empty constructor of siVarLoc struct -// Arguments: -// varDsc - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc". -// baseReg - a "regNumber" use as a base for the offset. -// offset - a signed amount of bytes distance from "baseReg" for the position of the variable. -// isFramePointerUsed - a boolean variable -// -// Notes: -// Called for every psiScope in "psiScopeList" codegen.h -CodeGenInterface::siVarLoc::siVarLoc(const LclVarDsc* varDsc, regNumber baseReg, int offset, bool isFramePointerUsed) -{ - var_types type = genActualType(varDsc->TypeGet()); - - if (varDsc->lvIsInReg()) - { - siFillRegisterVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed); - } - else - { - siFillStackVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed); - } -} - -//------------------------------------------------------------------------ // Equals: Compares first reference and then values of the structures. // // Arguments: @@ -228,65 +204,6 @@ bool CodeGenInterface::siVarLoc::Equals(const siVarLoc* lhs, const siVarLoc* rhs } //------------------------------------------------------------------------ -// getSiVarLoc: Creates a "CodegenInterface::siVarLoc" instance from using the properties -// of the "psiScope" instance. -// -// Notes: -// Called for every psiScope in "psiScopeList" codegen.h -CodeGenInterface::siVarLoc CodeGen::psiScope::getSiVarLoc() const -{ - CodeGenInterface::siVarLoc varLoc; - - if (scRegister) - { - varLoc.vlType = VLT_REG; - varLoc.vlReg.vlrReg = (regNumber)u1.scRegNum; - } - else - { - varLoc.vlType = VLT_STK; - varLoc.vlStk.vlsBaseReg = (regNumber)u2.scBaseReg; - varLoc.vlStk.vlsOffset = u2.scOffset; - } - - return varLoc; -} - -//------------------------------------------------------------------------ -// getSiVarLoc: Returns a "siVarLoc" instance representing the place where the variable -// is given its description, "baseReg", and "offset" (if needed). -// -// Arguments: -// varDsc - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc". -// scope - a "siScope" Scope info of the variable. -// -// Return Value: -// A "siVarLoc" filled with the correct case struct fields for the variable, which could live -// in a register, an stack position, or a combination of both. -// -// Notes: -// Called for each siScope in siScopeList when "genSetScopeInfo". -CodeGenInterface::siVarLoc CodeGen::getSiVarLoc(const LclVarDsc* varDsc, const siScope* scope) const -{ - // For stack vars, find the base register, and offset - - regNumber baseReg; - signed offset = varDsc->lvStkOffs; - - if (!varDsc->lvFramePointerBased) - { - baseReg = REG_SPBASE; - offset += scope->scStackLevel; - } - else - { - baseReg = REG_FPBASE; - } - - return CodeGenInterface::siVarLoc(varDsc, baseReg, offset, isFramePointerUsed()); -} - -//------------------------------------------------------------------------ // siFillStackVarLoc: Fill "siVarLoc" struct indicating the stack position of the variable // using "LclVarDsc" and "baseReg"/"offset". // @@ -471,6 +388,90 @@ void CodeGenInterface::siVarLoc::siFillRegisterVarLoc( } } +//------------------------------------------------------------------------ +// siVarLoc: Non-empty constructor of siVarLoc struct +// Arguments: +// varDsc - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc". +// baseReg - a "regNumber" use as a base for the offset. +// offset - a signed amount of bytes distance from "baseReg" for the position of the variable. +// isFramePointerUsed - a boolean variable +// +// Notes: +// Called for every psiScope in "psiScopeList" codegen.h +CodeGenInterface::siVarLoc::siVarLoc(const LclVarDsc* varDsc, regNumber baseReg, int offset, bool isFramePointerUsed) +{ + var_types type = genActualType(varDsc->TypeGet()); + + if (varDsc->lvIsInReg()) + { + siFillRegisterVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed); + } + else + { + siFillStackVarLoc(varDsc, type, baseReg, offset, isFramePointerUsed); + } +} + +#ifdef USING_SCOPE_INFO +//------------------------------------------------------------------------ +// getSiVarLoc: Returns a "siVarLoc" instance representing the place where the variable +// is given its description, "baseReg", and "offset" (if needed). +// +// Arguments: +// varDsc - a "LclVarDsc *" to the variable it is desired to build the "siVarLoc". +// scope - a "siScope" Scope info of the variable. +// +// Return Value: +// A "siVarLoc" filled with the correct case struct fields for the variable, which could live +// in a register, an stack position, or a combination of both. +// +// Notes: +// Called for each siScope in siScopeList when "genSetScopeInfo". +CodeGenInterface::siVarLoc CodeGen::getSiVarLoc(const LclVarDsc* varDsc, const siScope* scope) const +{ + // For stack vars, find the base register, and offset + + regNumber baseReg; + signed offset = varDsc->lvStkOffs; + + if (!varDsc->lvFramePointerBased) + { + baseReg = REG_SPBASE; + offset += scope->scStackLevel; + } + else + { + baseReg = REG_FPBASE; + } + + return CodeGenInterface::siVarLoc(varDsc, baseReg, offset, isFramePointerUsed()); +} + +//------------------------------------------------------------------------ +// getSiVarLoc: Creates a "CodegenInterface::siVarLoc" instance from using the properties +// of the "psiScope" instance. +// +// Notes: +// Called for every psiScope in "psiScopeList" codegen.h +CodeGenInterface::siVarLoc CodeGen::psiScope::getSiVarLoc() const +{ + CodeGenInterface::siVarLoc varLoc; + + if (scRegister) + { + varLoc.vlType = VLT_REG; + varLoc.vlReg.vlrReg = (regNumber)u1.scRegNum; + } + else + { + varLoc.vlType = VLT_STK; + varLoc.vlStk.vlsBaseReg = (regNumber)u2.scBaseReg; + varLoc.vlStk.vlsOffset = u2.scOffset; + } + + return varLoc; +} + /*============================================================================ * * Implementation for ScopeInfo @@ -1613,3 +1614,4 @@ void CodeGen::psiEndProlog() psiEndPrologScope(scope); } } +#endif // USING_SCOPE_INFO diff --git a/src/jit/treelifeupdater.cpp b/src/jit/treelifeupdater.cpp index ecfdaeee86..d5e3ad9a0b 100644 --- a/src/jit/treelifeupdater.cpp +++ b/src/jit/treelifeupdater.cpp @@ -245,8 +245,9 @@ void TreeLifeUpdater<ForCodeGen>::UpdateLifeVar(GenTree* tree) } #endif // DEBUG } - +#ifdef USING_SCOPE_INFO compiler->codeGen->siUpdate(); +#endif // USING_SCOPE_INFO } } diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp index 6fb16c51f6..f4c2838385 100644 --- a/src/vm/dllimport.cpp +++ b/src/vm/dllimport.cpp @@ -4139,6 +4139,7 @@ static void CreateNDirectStubWorker(StubState* pss, COMPlusThrow(kMarshalDirectiveException, IDS_EE_NDIRECT_BADNATL_THISCALL); } + fHasCopyCtorArgs = info.GetMarshalType() == MarshalInfo::MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR ? TRUE : FALSE; argidx++; } diff --git a/src/vm/ilmarshalers.cpp b/src/vm/ilmarshalers.cpp index 2b7f7a6cdf..7d8f04671c 100644 --- a/src/vm/ilmarshalers.cpp +++ b/src/vm/ilmarshalers.cpp @@ -3292,6 +3292,92 @@ ILCriticalHandleMarshaler::ReturnOverride( return OVERRIDDEN; } // ILCriticalHandleMarshaler::ReturnOverride +MarshalerOverrideStatus ILBlittableValueClassWithCopyCtorMarshaler::ArgumentOverride(NDirectStubLinker* psl, + BOOL byref, + BOOL fin, + BOOL fout, + BOOL fManagedToNative, + OverrideProcArgs* pargs, + UINT* pResID, + UINT argidx, + UINT nativeStackOffset) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + + ILCodeStream* pslIL = psl->GetMarshalCodeStream(); + ILCodeStream* pslILDispatch = psl->GetDispatchCodeStream(); + + if (byref) + { + *pResID = IDS_EE_BADMARSHAL_COPYCTORRESTRICTION; + return DISALLOWED; + } + + if (fManagedToNative) + { + // 1) create new native value type local + // 2) run new->CopyCtor(old) + // 3) run old->Dtor() + + LocalDesc locDesc(pargs->mm.m_pMT); + + DWORD dwNewValueTypeLocal; + + // Step 1 + dwNewValueTypeLocal = pslIL->NewLocal(locDesc); + + // Step 2 + if (pargs->mm.m_pCopyCtor) + { + // Managed copy constructor has signature of CopyCtor(T* new, T old); + pslIL->EmitLDLOCA(dwNewValueTypeLocal); + pslIL->EmitLDARG(argidx); + pslIL->EmitCALL(pslIL->GetToken(pargs->mm.m_pCopyCtor), 2, 0); + } + else + { + pslIL->EmitLDARG(argidx); + pslIL->EmitLDOBJ(pslIL->GetToken(pargs->mm.m_pMT)); + pslIL->EmitSTLOC(dwNewValueTypeLocal); + } + + // Step 3 + if (pargs->mm.m_pDtor) + { + // Managed destructor has signature of Destructor(T old); + pslIL->EmitLDARG(argidx); + pslIL->EmitCALL(pslIL->GetToken(pargs->mm.m_pDtor), 1, 0); + } +#ifdef _TARGET_X86_ + pslIL->SetStubTargetArgType(&locDesc); // native type is the value type + pslILDispatch->EmitLDLOC(dwNewValueTypeLocal); // we load the local directly +#else + pslIL->SetStubTargetArgType(ELEMENT_TYPE_I); // native type is a pointer + pslILDispatch->EmitLDLOCA(dwNewValueTypeLocal); +#endif + + return OVERRIDDEN; + } + else + { + // nothing to do but pass the value along + // note that on x86 the argument comes by-value but is converted to pointer by the UM thunk + // so that we don't make copies that would not be accounted for by copy ctors + LocalDesc locDesc(pargs->mm.m_pMT); + locDesc.MakeCopyConstructedPointer(); + + pslIL->SetStubTargetArgType(&locDesc); // native type is a pointer + pslILDispatch->EmitLDARG(argidx); + + return OVERRIDDEN; + } +} LocalDesc ILArgIteratorMarshaler::GetNativeType() { diff --git a/src/vm/ilmarshalers.h b/src/vm/ilmarshalers.h index 99a3d8f8d6..c892ae66a9 100644 --- a/src/vm/ilmarshalers.h +++ b/src/vm/ilmarshalers.h @@ -2725,8 +2725,40 @@ protected: virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit); }; +class ILBlittableValueClassWithCopyCtorMarshaler : public ILMarshaler +{ +public: + enum + { + c_fInOnly = TRUE, + c_nativeSize = VARIABLESIZE, + c_CLRSize = sizeof(OBJECTREF), + }; + LocalDesc GetManagedType() + { + LIMITED_METHOD_CONTRACT; + return LocalDesc(); + } + LocalDesc GetNativeType() + { + LIMITED_METHOD_CONTRACT; + return LocalDesc(); + } + + static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl, + BOOL byref, + BOOL fin, + BOOL fout, + BOOL fManagedToNative, + OverrideProcArgs* pargs, + UINT* pResID, + UINT argidx, + UINT nativeStackOffset); + + +}; class ILArgIteratorMarshaler : public ILMarshaler { diff --git a/src/vm/mlinfo.cpp b/src/vm/mlinfo.cpp index e007891aa8..edbf759322 100644 --- a/src/vm/mlinfo.cpp +++ b/src/vm/mlinfo.cpp @@ -1438,6 +1438,7 @@ MarshalInfo::MarshalInfo(Module* pModule, CorNativeType nativeType = NATIVE_TYPE_DEFAULT; Assembly *pAssembly = pModule->GetAssembly(); + BOOL fNeedsCopyCtor = FALSE; m_BestFit = BestFit; m_ThrowOnUnmappableChar = ThrowOnUnmappableChar; m_ms = ms; @@ -1548,6 +1549,21 @@ MarshalInfo::MarshalInfo(Module* pModule, IfFailGoto(sig.GetElemType(NULL), lFail); mtype = sig.PeekElemTypeNormalized(pModule, pTypeContext); + // Check for Copy Constructor Modifier - peek closed elem type here to prevent ELEMENT_TYPE_VALUETYPE + // turning into a primitive. + if (sig.PeekElemTypeClosed(pModule, pTypeContext) == ELEMENT_TYPE_VALUETYPE) + { + // Skip ET_BYREF + IfFailGoto(sigtmp.GetByte(NULL), lFail); + + if (sigtmp.HasCustomModifier(pModule, "Microsoft.VisualC.NeedsCopyConstructorModifier", ELEMENT_TYPE_CMOD_REQD) || + sigtmp.HasCustomModifier(pModule, "System.Runtime.CompilerServices.IsCopyConstructed", ELEMENT_TYPE_CMOD_REQD) ) + { + mtype = ELEMENT_TYPE_VALUETYPE; + fNeedsCopyCtor = TRUE; + m_byref = FALSE; + } + } } else { @@ -1590,6 +1606,19 @@ MarshalInfo::MarshalInfo(Module* pModule, IfFailGoto(E_FAIL, lFail); } + // Check for Copy Constructor Modifier + if (sigtmp.HasCustomModifier(pModule, "Microsoft.VisualC.NeedsCopyConstructorModifier", ELEMENT_TYPE_CMOD_REQD) || + sigtmp.HasCustomModifier(pModule, "System.Runtime.CompilerServices.IsCopyConstructed", ELEMENT_TYPE_CMOD_REQD) ) + { + mtype = mtype2; + + // Keep the sig pointer in sync with mtype (skip ELEMENT_TYPE_PTR) because for the rest + // of this method we are pretending that the parameter is a value type passed by-value. + IfFailGoto(sig.GetElemType(NULL), lFail); + + fNeedsCopyCtor = TRUE; + m_byref = FALSE; + } } } else @@ -2684,6 +2713,29 @@ MarshalInfo::MarshalInfo(Module* pModule, } else { + if (fNeedsCopyCtor) + { +#ifdef FEATURE_COMINTEROP + if (m_ms == MARSHAL_SCENARIO_WINRT) + { + // our WinRT-optimized GetCOMIPFromRCW helpers don't support copy + // constructor stubs so make sure that this marshaler will not be used + m_resID = IDS_EE_BADMARSHAL_WINRT_COPYCTOR; + IfFailGoto(E_FAIL, lFail); + } +#endif + + MethodDesc *pCopyCtor; + MethodDesc *pDtor; + FindCopyCtor(pModule, m_pMT, &pCopyCtor); + FindDtor(pModule, m_pMT, &pDtor); + + m_args.mm.m_pMT = m_pMT; + m_args.mm.m_pCopyCtor = pCopyCtor; + m_args.mm.m_pDtor = pDtor; + m_type = MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR; + } + else #ifdef _TARGET_X86_ // JIT64 is not aware of normalized value types and this optimization // (returning small value types by value in registers) is already done in JIT64. @@ -3398,6 +3450,7 @@ UINT16 MarshalInfo::GetNativeSize(MarshalType mtype, MarshalScenario ms) { case MARSHAL_TYPE_BLITTABLEVALUECLASS: case MARSHAL_TYPE_VALUECLASS: + case MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR: return (UINT16) m_pMT->GetNativeSize(); default: @@ -4049,6 +4102,7 @@ DispParamMarshaler *MarshalInfo::GenerateDispParamMarshaler() case MARSHAL_TYPE_BLITTABLEVALUECLASS: case MARSHAL_TYPE_BLITTABLEPTR: case MARSHAL_TYPE_LAYOUTCLASSPTR: + case MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR: pDispParamMarshaler = new DispParamRecordMarshaler(m_pMT); break; @@ -4350,6 +4404,9 @@ VOID MarshalInfo::MarshalTypeToString(SString& strMarshalType, BOOL fSizeIsSpeci case MARSHAL_TYPE_ARGITERATOR: strRetVal = W("ArgIterator"); break; + case MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR: + strRetVal = W("blittable value class with copy constructor"); + break; #ifdef FEATURE_COMINTEROP case MARSHAL_TYPE_OBJECT: strRetVal = W("VARIANT"); diff --git a/src/vm/mtypes.h b/src/vm/mtypes.h index af21d267c7..5f75eeb6e6 100644 --- a/src/vm/mtypes.h +++ b/src/vm/mtypes.h @@ -88,7 +88,7 @@ DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_VALUECLASS, ValueClassMa DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_REFERENCECUSTOMMARSHALER, ReferenceCustomMarshaler, false) DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_ARGITERATOR, ArgIteratorMarshaler, false) - +DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR, BlittableValueClassWithCopyCtorMarshaler, false) #ifdef FEATURE_COMINTEROP DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_OBJECT, ObjectMarshaler, false) diff --git a/tests/src/GC/API/GC/Collect.csproj b/tests/src/GC/API/GC/Collect.csproj index 6a07e5527a..36a935e502 100644 --- a/tests/src/GC/API/GC/Collect.csproj +++ b/tests/src/GC/API/GC/Collect.csproj @@ -11,6 +11,7 @@ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> <CLRTestPriority>1</CLRTestPriority> + <GCStressIncompatible>true</GCStressIncompatible> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup> diff --git a/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt index b4dec5750d..32e4b77e16 100644 --- a/tests/src/Interop/CMakeLists.txt +++ b/tests/src/Interop/CMakeLists.txt @@ -89,5 +89,6 @@ if(WIN32) if(NOT CLR_CMAKE_PLATFORM_ARCH_ARM64) add_subdirectory(IJW/ManagedCallingNative/IjwNativeDll) add_subdirectory(IJW/NativeCallingManaged/IjwNativeCallingManagedDll) + add_subdirectory(IJW/CopyConstructorMarshaler) endif() endif(WIN32) diff --git a/tests/src/Interop/IJW/CopyConstructorMarshaler/CMakeLists.txt b/tests/src/Interop/IJW/CopyConstructorMarshaler/CMakeLists.txt new file mode 100644 index 0000000000..57726a4318 --- /dev/null +++ b/tests/src/Interop/IJW/CopyConstructorMarshaler/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required (VERSION 2.6) +project (CopyConstructorMarshaler) +include_directories( ${INC_PLATFORM_DIR} ) +set(SOURCES IjwCopyConstructorMarshaler.cpp) + +if (WIN32) + # 4365 - signed/unsigned mismatch + add_compile_options(/wd4365) + + # IJW + add_compile_options(/clr) + + # IJW requires the CRT as a dll, not linked in + add_compile_options(/MD$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>) + + # CMake enables /RTC1 and /EHsc by default, but they're not compatible with /clr, so remove them + if(CMAKE_CXX_FLAGS_DEBUG MATCHES "/RTC1") + string(REPLACE "/RTC1" " " CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + endif() + + if(CMAKE_CXX_FLAGS MATCHES "/EHsc") + string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + endif() + + # IJW isn't compatible with CFG + if(CMAKE_CXX_FLAGS MATCHES "/guard:cf") + string(REPLACE "/guard:cf" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + endif() + + # IJW isn't compatible with GR- + if(CMAKE_CXX_FLAGS MATCHES "/GR-") + string(REPLACE "/GR-" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + endif() + +endif() + +# add the shared library +add_library (IjwCopyConstructorMarshaler SHARED ${SOURCES}) +target_link_libraries(IjwCopyConstructorMarshaler ${LINK_LIBRARIES_ADDITIONAL}) + +# add the install targets +install (TARGETS IjwCopyConstructorMarshaler DESTINATION bin) diff --git a/tests/src/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.cs b/tests/src/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.cs new file mode 100644 index 0000000000..d589cd4fe8 --- /dev/null +++ b/tests/src/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.cs @@ -0,0 +1,66 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using TestLibrary; + +namespace CopyConstructorMarshaler +{ + class CopyConstructorMarshaler + { + static int Main(string[] args) + { + if(Environment.OSVersion.Platform != PlatformID.Win32NT || TestLibrary.Utilities.IsWindows7) + { + return 100; + } + + try + { + // Load a fake mscoree.dll to avoid starting desktop + LoadLibraryEx(Path.Combine(Environment.CurrentDirectory, "mscoree.dll"), IntPtr.Zero, 0); + + Assembly ijwNativeDll = Assembly.Load("IjwCopyConstructorMarshaler"); + Type testType = ijwNativeDll.GetType("TestClass"); + object testInstance = Activator.CreateInstance(testType); + MethodInfo testMethod = testType.GetMethod("PInvokeNumCopies"); + + // PInvoke will copy twice. Once from argument to parameter, and once from the managed to native parameter. + Assert.AreEqual(2, (int)testMethod.Invoke(testInstance, null)); + + testMethod = testType.GetMethod("ReversePInvokeNumCopies"); + + // Reverse PInvoke will copy 3 times. Two are from the same paths as the PInvoke, + // and the third is from the reverse P/Invoke call. + Assert.AreEqual(3, (int)testMethod.Invoke(testInstance, null)); + + testMethod = testType.GetMethod("PInvokeNumCopiesDerivedType"); + + // PInvoke will copy twice. Once from argument to parameter, and once from the managed to native parameter. + Assert.AreEqual(2, (int)testMethod.Invoke(testInstance, null)); + + testMethod = testType.GetMethod("ReversePInvokeNumCopiesDerivedType"); + + // Reverse PInvoke will copy 3 times. Two are from the same paths as the PInvoke, + // and the third is from the reverse P/Invoke call. + Assert.AreEqual(3, (int)testMethod.Invoke(testInstance, null)); + } + catch (Exception ex) + { + Console.WriteLine(ex); + return 101; + } + return 100; + } + + [DllImport("kernel32.dll")] + static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, int dwFlags); + + [DllImport("kernel32.dll")] + static extern IntPtr GetModuleHandle(string lpModuleName); + } +} diff --git a/tests/src/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.csproj b/tests/src/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.csproj new file mode 100644 index 0000000000..34aad536a0 --- /dev/null +++ b/tests/src/Interop/IJW/CopyConstructorMarshaler/CopyConstructorMarshaler.csproj @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Interop.settings.targets))\Interop.settings.targets" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>CopyConstructorMarshaler</AssemblyName> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{49D1D482-E783-4CA9-B6BA-A9714BF81036}</ProjectGuid> + <OutputType>Exe</OutputType> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> + + <!-- IJW is Windows-only --> + <!-- Test unsupported outside of windows --> + <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows> + <DisableProjectBuild Condition="'$(TargetsUnix)' == 'true'">true</DisableProjectBuild> + + <!-- IJW is not supported on ARM64 --> + <DisableProjectBuild Condition="'$(Platform)' == 'arm64'">true</DisableProjectBuild> + </PropertyGroup> + <!-- Default configurations to help VS understand the configurations --> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + </PropertyGroup> + <PropertyGroup> + <CopyDebugCRTDllsToOutputDirectory>true</CopyDebugCRTDllsToOutputDirectory> + </PropertyGroup> + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + <ItemGroup> + <Compile Include="CopyConstructorMarshaler.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="CMakeLists.txt" /> + <ProjectReference Include="../FakeMscoree/CMakeLists.txt" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Interop/IJW/CopyConstructorMarshaler/IjwCopyConstructorMarshaler.cpp b/tests/src/Interop/IJW/CopyConstructorMarshaler/IjwCopyConstructorMarshaler.cpp new file mode 100644 index 0000000000..b82c33b349 --- /dev/null +++ b/tests/src/Interop/IJW/CopyConstructorMarshaler/IjwCopyConstructorMarshaler.cpp @@ -0,0 +1,106 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#pragma managed +class A +{ + int copyCount; + +public: + A() + :copyCount(0) + {}; + + A(A& other) + :copyCount(other.copyCount + 1) + {} + + int GetCopyCount() + { + return copyCount; + } +}; + +class B : public A +{ + int bCopyCount; + +public: + B() + :A(), + bCopyCount(0) + {}; + + B(B& other) + :A(other), + bCopyCount(other.bCopyCount + 1) + {} + + int GetBCopyCount() + { + return bCopyCount; + } +}; + +int Managed_GetCopyCount(A a) +{ + return a.GetCopyCount(); +} + +int Managed_GetCopyCount(B b) +{ + return b.GetBCopyCount(); +} + +#pragma unmanaged + +int GetCopyCount(A a) +{ + return a.GetCopyCount(); +} + +int GetCopyCount_ViaManaged(A a) +{ + return Managed_GetCopyCount(a); +} + +int GetCopyCount(B b) +{ + return b.GetBCopyCount(); +} + +int GetCopyCount_ViaManaged(B b) +{ + return Managed_GetCopyCount(b); +} + +#pragma managed + +public ref class TestClass +{ +public: + int PInvokeNumCopies() + { + A a; + return GetCopyCount(a); + } + + int PInvokeNumCopiesDerivedType() + { + B b; + return GetCopyCount(b); + } + + int ReversePInvokeNumCopies() + { + A a; + return GetCopyCount_ViaManaged(a); + } + + int ReversePInvokeNumCopiesDerivedType() + { + B b; + return GetCopyCount_ViaManaged(b); + } +}; diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_18582/GitHub_18582.cs b/tests/src/JIT/Regression/JitBlue/GitHub_18582/GitHub_18582.cs new file mode 100644 index 0000000000..0a589d18e8 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_18582/GitHub_18582.cs @@ -0,0 +1,221 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.CompilerServices; +using System.Threading; + +// Repro for issue fixed 18582 (also seein in 23309) -- stack overflow when remorphing +// call with a lot of arguments and some CSEs when running with limited stack (as is +// done when CLR is hosted by IIS). + +class GitHub_18582 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static void Consume( + int x000, int x001, int x002, int x003, int x004, int x005, int x006, int x007, int x008, int x009, + int x010, int x011, int x012, int x013, int x014, int x015, int x016, int x017, int x018, int x019, + int x020, int x021, int x022, int x023, int x024, int x025, int x026, int x027, int x028, int x029, + int x030, int x031, int x032, int x033, int x034, int x035, int x036, int x037, int x038, int x039, + int x040, int x041, int x042, int x043, int x044, int x045, int x046, int x047, int x048, int x049, + int x050, int x051, int x052, int x053, int x054, int x055, int x056, int x057, int x058, int x059, + int x060, int x061, int x062, int x063, int x064, int x065, int x066, int x067, int x068, int x069, + int x070, int x071, int x072, int x073, int x074, int x075, int x076, int x077, int x078, int x079, + int x080, int x081, int x082, int x083, int x084, int x085, int x086, int x087, int x088, int x089, + int x090, int x091, int x092, int x093, int x094, int x095, int x096, int x097, int x098, int x099, + int x100, int x101, int x102, int x103, int x104, int x105, int x106, int x107, int x108, int x109, + int x110, int x111, int x112, int x113, int x114, int x115, int x116, int x117, int x118, int x119, + int x120, int x121, int x122, int x123, int x124, int x125, int x126, int x127, int x128, int x129, + int x130, int x131, int x132, int x133, int x134, int x135, int x136, int x137, int x138, int x139, + int x140, int x141, int x142, int x143, int x144, int x145, int x146, int x147, int x148, int x149, + int x150, int x151, int x152, int x153, int x154, int x155, int x156, int x157, int x158, int x159, + int x160, int x161, int x162, int x163, int x164, int x165, int x166, int x167, int x168, int x169, + int x170, int x171, int x172, int x173, int x174, int x175, int x176, int x177, int x178, int x179, + int x180, int x181, int x182, int x183, int x184, int x185, int x186, int x187, int x188, int x189, + int x190, int x191, int x192, int x193, int x194, int x195, int x196, int x197, int x198, int x199, + int x200, int x201, int x202, int x203, int x204, int x205, int x206, int x207, int x208, int x209, + int x210, int x211, int x212, int x213, int x214, int x215, int x216, int x217, int x218, int x219, + int x220, int x221, int x222, int x223, int x224, int x225, int x226, int x227, int x228, int x229, + int x230, int x231, int x232, int x233, int x234, int x235, int x236, int x237, int x238, int x239, + int x240, int x241, int x242, int x243, int x244, int x245, int x246, int x247, int x248, int x249, + int x250, int x251, int x252, int x253, int x254, int x255, int x256, int x257, int x258, int x259, + int x260, int x261, int x262, int x263, int x264, int x265, int x266, int x267, int x268, int x269, + int x270, int x271, int x272, int x273, int x274, int x275, int x276, int x277, int x278, int x279, + int x280, int x281, int x282, int x283, int x284, int x285, int x286, int x287, int x288, int x289, + int x290, int x291, int x292, int x293, int x294, int x295, int x296, int x297, int x298, int x299, + int x300, int x301, int x302, int x303, int x304, int x305, int x306, int x307, int x308, int x309, + int x310, int x311, int x312, int x313, int x314, int x315, int x316, int x317, int x318, int x319, + int x320, int x321, int x322, int x323, int x324, int x325, int x326, int x327, int x328, int x329, + int x330, int x331, int x332, int x333, int x334, int x335, int x336, int x337, int x338, int x339, + int x340, int x341, int x342, int x343, int x344, int x345, int x346, int x347, int x348, int x349, + int x350, int x351, int x352, int x353, int x354, int x355, int x356, int x357, int x358, int x359, + int x360, int x361, int x362, int x363, int x364, int x365, int x366, int x367, int x368, int x369, + int x370, int x371, int x372, int x373, int x374, int x375, int x376, int x377, int x378, int x379, + int x380, int x381, int x382, int x383, int x384, int x385, int x386, int x387, int x388, int x389, + int x390, int x391, int x392, int x393, int x394, int x395, int x396, int x397, int x398, int x399, + int x400, int x401, int x402, int x403, int x404, int x405, int x406, int x407, int x408, int x409, + int x410, int x411, int x412, int x413, int x414, int x415, int x416, int x417, int x418, int x419, + int x420, int x421, int x422, int x423, int x424, int x425, int x426, int x427, int x428, int x429, + int x430, int x431, int x432, int x433, int x434, int x435, int x436, int x437, int x438, int x439, + int x440, int x441, int x442, int x443, int x444, int x445, int x446, int x447, int x448, int x449, + int x450, int x451, int x452, int x453, int x454, int x455, int x456, int x457, int x458, int x459, + int x460, int x461, int x462, int x463, int x464, int x465, int x466, int x467, int x468, int x469, + int x470, int x471, int x472, int x473, int x474, int x475, int x476, int x477, int x478, int x479, + int x480, int x481, int x482, int x483, int x484, int x485, int x486, int x487, int x488, int x489, + int x490, int x491, int x492, int x493, int x494, int x495, int x496, int x497, int x498, int x499, + int x500, int x501, int x502, int x503, int x504, int x505, int x506, int x507, int x508, int x509, + int x510, int x511, int x512, int x513, int x514, int x515, int x516, int x517, int x518, int x519, + int x520, int x521, int x522, int x523, int x524, int x525, int x526, int x527, int x528, int x529, + int x530, int x531, int x532, int x533, int x534, int x535, int x536, int x537, int x538, int x539, + int x540, int x541, int x542, int x543, int x544, int x545, int x546, int x547, int x548, int x549, + int x550, int x551, int x552, int x553, int x554, int x555, int x556, int x557, int x558, int x559, + int x560, int x561, int x562, int x563, int x564, int x565, int x566, int x567, int x568, int x569, + int x570, int x571, int x572, int x573, int x574, int x575, int x576, int x577, int x578, int x579, + int x580, int x581, int x582, int x583, int x584, int x585, int x586, int x587, int x588, int x589, + int x590, int x591, int x592, int x593, int x594, int x595, int x596, int x597, int x598, int x599, + int x600, int x601, int x602, int x603, int x604, int x605, int x606, int x607, int x608, int x609, + int x610, int x611, int x612, int x613, int x614, int x615, int x616, int x617, int x618, int x619, + int x620, int x621, int x622, int x623, int x624, int x625, int x626, int x627, int x628, int x629, + int x630, int x631, int x632, int x633, int x634, int x635, int x636, int x637, int x638, int x639, + int x640, int x641, int x642, int x643, int x644, int x645, int x646, int x647, int x648, int x649, + int x650, int x651, int x652, int x653, int x654, int x655, int x656, int x657, int x658, int x659, + int x660, int x661, int x662, int x663, int x664, int x665, int x666, int x667, int x668, int x669, + int x670, int x671, int x672, int x673, int x674, int x675, int x676, int x677, int x678, int x679, + int x680, int x681, int x682, int x683, int x684, int x685, int x686, int x687, int x688, int x689, + int x690, int x691, int x692, int x693, int x694, int x695, int x696, int x697, int x698, int x699, + int x700, int x701, int x702, int x703, int x704, int x705, int x706, int x707, int x708, int x709, + int x710, int x711, int x712, int x713, int x714, int x715, int x716, int x717, int x718, int x719, + int x720, int x721, int x722, int x723, int x724, int x725, int x726, int x727, int x728, int x729, + int x730, int x731, int x732, int x733, int x734, int x735, int x736, int x737, int x738, int x739, + int x740, int x741, int x742, int x743, int x744, int x745, int x746, int x747, int x748, int x749, + int x750, int x751, int x752, int x753, int x754, int x755, int x756, int x757, int x758, int x759, + int x760, int x761, int x762, int x763, int x764, int x765, int x766, int x767, int x768, int x769, + int x770, int x771, int x772, int x773, int x774, int x775, int x776, int x777, int x778, int x779, + int x780, int x781, int x782, int x783, int x784, int x785, int x786, int x787, int x788, int x789, + int x790, int x791, int x792, int x793, int x794, int x795, int x796, int x797, int x798, int x799, + int x800, int x801, int x802, int x803, int x804, int x805, int x806, int x807, int x808, int x809, + int x810, int x811, int x812, int x813, int x814, int x815, int x816, int x817, int x818, int x819, + int x820, int x821, int x822, int x823, int x824, int x825, int x826, int x827, int x828, int x829, + int x830, int x831, int x832, int x833, int x834, int x835, int x836, int x837, int x838, int x839, + int x840, int x841, int x842, int x843, int x844, int x845, int x846, int x847, int x848, int x849) + { + s_x = x000 + x099 + x749 + x849; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static int q() => s_x + 1; + + public static void Test() + { + int z = s_x; + Consume( + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + q(), q(), q(), q(), q(), q(), q(), q(), q(), q(), + z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1); + } + + static int s_x; + + public static int Main() + { + s_x = 1; + int expected = 8; + Thread t = new Thread(Test, 512 * 1024); + t.Start(); + t.Join(); + + if (s_x == expected) + { + Console.WriteLine("PASSED"); + return 100; + } + else + { + Console.WriteLine($"FAILED, got {s_x}, expected {expected}"); + return -1; + } + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_18582/GitHub_18582.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_18582/GitHub_18582.csproj new file mode 100644 index 0000000000..5243a9a46c --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_18582/GitHub_18582.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>$(MSBuildProjectName)</AssemblyName> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <OutputType>Exe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath> + <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <CLRTestPriority>1</CLRTestPriority> + </PropertyGroup> + <!-- Default configurations to help VS understand the configurations --> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup> + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + <PropertyGroup> + <DebugType></DebugType> + <Optimize>True</Optimize> + </PropertyGroup> + <ItemGroup> + <Compile Include="GitHub_18582.cs" /> + </ItemGroup> + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> + <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> +</Project>
\ No newline at end of file |