diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2015-05-06 23:43:46 -0700 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2015-05-07 12:03:00 -0700 |
commit | 484a2cf0b0c4e304a5093ec26e07fe41f8896c3c (patch) | |
tree | 348b56df4cdb235bb87ba9bc9118711c8db13bfd | |
parent | c6efc7047edb38075310cfef8ea28b91717b8108 (diff) | |
download | coreclr-484a2cf0b0c4e304a5093ec26e07fe41f8896c3c.tar.gz coreclr-484a2cf0b0c4e304a5093ec26e07fe41f8896c3c.tar.bz2 coreclr-484a2cf0b0c4e304a5093ec26e07fe41f8896c3c.zip |
Merge changes from parent branch
[tfs-changeset: 1466545]
62 files changed, 1357 insertions, 317 deletions
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp index fbd6993756..16f8bea1fe 100644 --- a/src/debug/daccess/nidump.cpp +++ b/src/debug/daccess/nidump.cpp @@ -5355,6 +5355,7 @@ const NativeImageDumper::EnumMnemonics s_CorCompileHdrFlags[] = #define CCHF_ENTRY(f) NativeImageDumper::EnumMnemonics(f, W(#f)) CCHF_ENTRY(CORCOMPILE_HEADER_HAS_SECURITY_DIRECTORY), CCHF_ENTRY(CORCOMPILE_HEADER_IS_IBC_OPTIMIZED), + CCHF_ENTRY(CORCOMPILE_HEADER_IS_READY_TO_RUN), #undef CCHF_ENTRY }; diff --git a/src/inc/corcompile.h b/src/inc/corcompile.h index 693cf31edf..e3f73a79c9 100644 --- a/src/inc/corcompile.h +++ b/src/inc/corcompile.h @@ -198,8 +198,16 @@ enum CorCompileCodegen CORCOMPILE_CODEGEN_PROFILING = 0x0004, // supports profiling CORCOMPILE_CODEGEN_PROF_INSTRUMENTING = 0x0008, // code is instrumented to collect profile count info + +#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR) + CORCOMPILE_CODEGEN_USE_RYUJIT = 0x0100, // code is generated by Ryu JIT +#endif }; +#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR) +bool UseRyuJit(); +#endif + // Used for INativeImageInstallInfo::GetConfigMask() // A bind will ask for the particular bits it needs set; if all bits are set, it is a match. Additional // bits are ignored. @@ -225,6 +233,8 @@ enum CorCompileHeaderFlags // Note it is useless to cache the actual directory contents // since it must be verified as part of the original image CORCOMPILE_HEADER_IS_IBC_OPTIMIZED = 0x00000002, + + CORCOMPILE_HEADER_IS_READY_TO_RUN = 0x00000004, }; // diff --git a/src/inc/eetwain.h b/src/inc/eetwain.h index d849bcf47c..21f74847e6 100644 --- a/src/inc/eetwain.h +++ b/src/inc/eetwain.h @@ -43,6 +43,8 @@ #define CHECK_APP_DOMAIN 0 #endif +#define NO_OVERRIDE_OFFSET (DWORD)-1 + struct EHContext; #ifdef DACCESS_COMPILE @@ -231,7 +233,8 @@ virtual bool EnumGcRefs(PREGDISPLAY pContext, EECodeInfo *pCodeInfo, unsigned flags, GCEnumCallback pCallback, - LPVOID hCallBack) = 0; + LPVOID hCallBack, + DWORD relOffsetOverride = NO_OVERRIDE_OFFSET) = 0; /* Return the address of the local security object reference @@ -460,7 +463,8 @@ bool EnumGcRefs(PREGDISPLAY pContext, EECodeInfo *pCodeInfo, unsigned flags, GCEnumCallback pCallback, - LPVOID hCallBack); + LPVOID hCallBack, + DWORD relOffsetOverride = NO_OVERRIDE_OFFSET); #ifdef FEATURE_CONSERVATIVE_GC // Temporary conservative collection, for testing purposes, until we have diff --git a/src/inc/eventtracebase.h b/src/inc/eventtracebase.h index 517125f49b..eac127e732 100644 --- a/src/inc/eventtracebase.h +++ b/src/inc/eventtracebase.h @@ -650,8 +650,23 @@ namespace ETW public: #ifdef FEATURE_EVENT_TRACE static VOID ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownException, BOOL bIsNewException); + static VOID ExceptionThrownEnd(); + static VOID ExceptionCatchBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP); + static VOID ExceptionCatchEnd(); + static VOID ExceptionFinallyBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP); + static VOID ExceptionFinallyEnd(); + static VOID ExceptionFilterBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP); + static VOID ExceptionFilterEnd(); + #else static VOID ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownException, BOOL bIsNewException) {}; + static VOID ExceptionThrownEnd() {}; + static VOID ExceptionCatchBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) {}; + static VOID ExceptionCatchEnd() {}; + static VOID ExceptionFinallyBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) {}; + static VOID ExceptionFinallyEnd() {}; + static VOID ExceptionFilterBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) {}; + static VOID ExceptionFilterEnd() {}; #endif // FEATURE_EVENT_TRACE typedef union _ExceptionStructs { diff --git a/src/inc/pedecoder.h b/src/inc/pedecoder.h index 71126d3ff3..a744764a6d 100644 --- a/src/inc/pedecoder.h +++ b/src/inc/pedecoder.h @@ -307,6 +307,7 @@ class PEDecoder const void *GetNativePreferredBase() const; BOOL GetNativeILHasSecurityDirectory() const; BOOL GetNativeILIsIbcOptimized() const; + BOOL GetNativeILHasReadyToRunHeader() const; BOOL IsNativeILILOnly() const; BOOL IsNativeILDll() const; void GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine) const; diff --git a/src/inc/pedecoder.inl b/src/inc/pedecoder.inl index 94c93c3526..9794625a58 100644 --- a/src/inc/pedecoder.inl +++ b/src/inc/pedecoder.inl @@ -1046,6 +1046,21 @@ inline BOOL PEDecoder::GetNativeILIsIbcOptimized() const return (GetNativeHeader()->Flags & CORCOMPILE_HEADER_IS_IBC_OPTIMIZED) != 0; } +inline BOOL PEDecoder::GetNativeILHasReadyToRunHeader() const +{ + CONTRACTL + { + INSTANCE_CHECK; + PRECONDITION(CheckNativeHeader()); + NOTHROW; + GC_NOTRIGGER; + } + CONTRACTL_END; + + PREFIX_ASSUME (GetNativeHeader()!=NULL); + return (GetNativeHeader()->Flags & CORCOMPILE_HEADER_IS_READY_TO_RUN) != 0; +} + inline BOOL PEDecoder::IsNativeILILOnly() const { CONTRACTL diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp index 98a269b397..9449a751ad 100644 --- a/src/jit/codegenxarch.cpp +++ b/src/jit/codegenxarch.cpp @@ -6759,6 +6759,7 @@ void CodeGen::genEmitHelperCall(unsigned helper, emitter::EmitCallType callType = emitter::EC_FUNC_TOKEN; addr = compiler->compGetHelperFtn((CorInfoHelpFunc)helper, &pAddr); regNumber callTarget = REG_NA; + regMaskTP killMask = compiler->compHelperCallKillSet((CorInfoHelpFunc)helper); if (!addr) { @@ -6782,13 +6783,16 @@ void CodeGen::genEmitHelperCall(unsigned helper, // If a callTargetReg has not been explicitly provided, we will use REG_DEFAULT_HELPER_CALL_TARGET, but // this is only a valid assumption if the helper call is known to kill REG_DEFAULT_HELPER_CALL_TARGET. callTargetReg = REG_DEFAULT_HELPER_CALL_TARGET; + regMaskTP callTargetMask = genRegMask(callTargetReg); + noway_assert((callTargetMask & killMask) == callTargetMask); + } + else + { + // The call target must not overwrite any live variable, though it may not be in the + // kill set for the call. + regMaskTP callTargetMask = genRegMask(callTargetReg); + noway_assert((callTargetMask & regSet.rsMaskVars) == RBM_NONE); } - - regMaskTP callTargetMask = genRegMask(callTargetReg); - regMaskTP callKillSet = compiler->compHelperCallKillSet((CorInfoHelpFunc)helper); - - // assert that all registers in callTargetMask are in the callKillSet - noway_assert((callTargetMask & callKillSet) == callTargetMask); #endif callTarget = callTargetReg; CodeGen::genSetRegToIcon(callTarget, (ssize_t) pAddr, TYP_I_IMPL); @@ -6812,7 +6816,6 @@ void CodeGen::genEmitHelperCall(unsigned helper, emitter::emitNoGChelper(helper)); - regMaskTP killMask = compiler->compHelperCallKillSet((CorInfoHelpFunc)helper); regTracker.rsTrashRegSet(killMask); regTracker.rsTrashRegsForGCInterruptability(); } diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index f05c4aa194..0463575029 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -16430,6 +16430,27 @@ void Compiler::fgExtendEHRegionBefore(BasicBlock* block) HBtab->ebdHndBeg = bPrev; bPrev->bbFlags |= BBF_DONT_REMOVE | BBF_HAS_LABEL; bPrev->bbRefs++; + + // If this is a handler for a filter, the last block of the filter will end with + // a BBJ_EJFILTERRET block that has a bbJumpDest that jumps to the first block of + // it's handler. So we need to update it to keep things in sync. + // + if (HBtab->HasFilter()) + { + BasicBlock* bFilterLast = HBtab->BBFilterLast(); + assert(bFilterLast != nullptr); + assert(bFilterLast->bbJumpKind == BBJ_EHFILTERRET); + assert(bFilterLast->bbJumpDest == block); +#ifdef DEBUG + if (verbose) + { + printf("EH#%u: Updating bbJumpDest for filter ret block: BB%02u => BB%02u\n", + ehGetIndex(HBtab), bFilterLast->bbNum, bPrev->bbNum); + } +#endif // DEBUG + // Change the bbJumpDest for bFilterLast from the old first 'block' to the new first 'bPrev' + bFilterLast->bbJumpDest = bPrev; + } } if (HBtab->HasFilter() && (HBtab->ebdFilter == block)) diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index b7d63850e4..4654350962 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -11597,9 +11597,13 @@ BasicBlock* BasicBlock::GetSucc(unsigned i, Compiler * comp) unreached(); // Should have been covered by assert above. case BBJ_EHFILTERRET: + { assert(comp != NULL); // Or else we're not looking for successors. + BasicBlock* result = comp->fgFirstBlockOfHandler(this); + noway_assert(result == bbJumpDest); // Handler is the (sole) normal successor of the filter. - return comp->fgFirstBlockOfHandler(this); + return result; + } case BBJ_EHFINALLYRET: return comp->fgSuccOfFinallyRet(this, i); diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp index a231ebbeee..4327e20bd6 100644 --- a/src/jit/lower.cpp +++ b/src/jit/lower.cpp @@ -417,76 +417,6 @@ GenTreePtr Lowering::CreateLocalTempAsg(GenTreePtr rhs, return store; } -/** Creates a byref to byref assignment where the actual values are not - * GC pointers. The assignment has the following shape: - * [dstObj + scale*index + offset] = [srcObj + scale*index + offset] - * The IR generated for this is: - * GT_ASG( - * GT_IND( - * GT_LEA(dstObj, index, scale, offset)), - * GT_IND( - * GT_LEA(srcObj, index, scale, offset))) - */ -GenTreePtr Lowering::CreateAsgByRefNonGcStmt (Compiler* comp, - BasicBlock* block, - GenTreePtr srcObj, - GenTreePtr dstObj, - GenTreePtr index, - unsigned scale, - unsigned offset) -{ - assert(srcObj != nullptr && dstObj != nullptr); - var_types type = TYP_INT; - switch (scale) - { - case 4: - type = TYP_INT; - break; - case 2: - type = TYP_USHORT; - break; - case 1: - type = TYP_UBYTE; - break; - default: - noway_assert(!"Unsupported scale size for addressing modes"); - } - GenTreePtr gtClonedSrc = comp->gtClone(srcObj); - GenTreePtr gtClonedDst = comp->gtClone(dstObj); - GenTreePtr gtClonedIndex = nullptr; - GenTreePtr gtClonedIndex2 = nullptr; - - assert(gtClonedSrc != nullptr && gtClonedDst != nullptr); - - if (index != nullptr) - { - gtClonedIndex = comp->gtClone(index); - gtClonedIndex2 = comp->gtClone(index); - assert(gtClonedIndex != nullptr && gtClonedIndex2 != nullptr); - } - - GenTreePtr gtSrcAddrNode = new(comp, GT_LEA) GenTreeAddrMode(type, - gtClonedSrc, - gtClonedIndex, - scale, - offset); - GenTreePtr gtSrcIndirNode = comp->gtNewOperNode(GT_IND, - type, - gtSrcAddrNode); - GenTreePtr gtDstAddrNode = new(comp, GT_LEA) GenTreeAddrMode(type, - gtClonedDst, - gtClonedIndex2, - scale, - offset); - GenTreePtr gtDstIndirNode = comp->gtNewOperNode(GT_IND, - type, - gtDstAddrNode); - GenTreePtr gtByRefAsgStmt = comp->fgNewStmtFromTree( - comp->gtNewAssignNode(gtDstIndirNode, gtSrcIndirNode), - block); - return gtByRefAsgStmt; -} - // This is the main entry point for Lowering. // In addition to that, LowerNode is also responsible for initializing the @@ -2086,6 +2016,7 @@ GenTree* Lowering::LowerDelegateInvoke(GenTreeCall* call) originalThisValue->InsertAfterSelf(newThisAddr); GenTree* newThis = comp->gtNewOperNode(GT_IND, TYP_REF, newThisAddr); + newThis->SetCosts(IND_COST_EX, 2); newThisAddr->InsertAfterSelf(newThis); *pThisExpr = newThis; diff --git a/src/jit/lower.h b/src/jit/lower.h index 6b78903d9f..e029e451a0 100644 --- a/src/jit/lower.h +++ b/src/jit/lower.h @@ -168,13 +168,6 @@ private: GenTreePtr indirCandidate); GenTreePtr CreateLocalTempAsg (GenTreePtr rhs, unsigned refCount, GenTreePtr *ppLclVar = nullptr); - GenTreePtr CreateAsgByRefNonGcStmt (Compiler* comp, - BasicBlock* block, - GenTreePtr srcObj, - GenTreePtr dstObj, - GenTreePtr index, - unsigned scale, - unsigned offset); bool AreSourcesPossiblyModified (GenTree* use, GenTree* src1, GenTree *src2); void ReplaceNode (GenTree** ppTreeLocation, diff --git a/src/jit/lowerxarch.cpp b/src/jit/lowerxarch.cpp index 87f6fa8c00..d803e5dd26 100644 --- a/src/jit/lowerxarch.cpp +++ b/src/jit/lowerxarch.cpp @@ -1874,19 +1874,32 @@ Lowering::TreeNodeInfoInitSIMD(GenTree* tree, LinearScan* lsra) // Otherwise, if the baseType is floating point, the targetReg will be a xmm reg and we // can use that in the process of extracting the element. // - // If the index is a constant and base type is a small int we can use pextrw. + // If the index is a constant and base type is a small int we can use pextrw, but on AVX + // we will need a temp if are indexing into the upper half of the AVX register. // In all other cases with constant index, we need a temp xmm register to extract the // element if index is other than zero. + if (!op2->IsCnsIntOrI()) { (void) comp->getSIMDInitTempVarNum(); } - else if (!varTypeIsFloating(simdTree->gtSIMDBaseType) && - !varTypeIsSmallInt(simdTree->gtSIMDBaseType) && - !op2->IsZero()) + else if (!varTypeIsFloating(simdTree->gtSIMDBaseType)) { - info->internalFloatCount = 1; - info->setInternalCandidates(lsra, lsra->allSIMDRegs()); + bool needFloatTemp; + if (varTypeIsSmallInt(simdTree->gtSIMDBaseType) && (comp->getSIMDInstructionSet() == InstructionSet_AVX)) + { + int byteShiftCnt = (int) op2->AsIntCon()->gtIconVal * genTypeSize(simdTree->gtSIMDBaseType); + needFloatTemp = (byteShiftCnt >= 16); + } + else + { + needFloatTemp = !op2->IsZero(); + } + if (needFloatTemp) + { + info->internalFloatCount = 1; + info->setInternalCandidates(lsra, lsra->allSIMDRegs()); + } } break; diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp index 76a98f3c53..f0831cf919 100644 --- a/src/jit/lsra.cpp +++ b/src/jit/lsra.cpp @@ -2974,6 +2974,17 @@ LinearScan::buildRefPositionsForNode(GenTree *tree, srcInterval->assignRelatedInterval(varDefInterval); } } + // We can have a case where the source of the store has a different register type, + // e.g. when the store is of a return value temp, and op1 is a Vector2 + // (8-byte SIMD, which is TYP_DOUBLE at this point). We will need to set the + // src candidates accordingly on op1 so that LSRA will generate a copy. + // We could do this during Lowering, but at that point we don't know whether + // this lclVar will be a register candidate, and if not, we would prefer to leave + // the type alone. + if (regType(tree->gtGetOp1()->TypeGet()) != regType(tree->TypeGet())) + { + tree->gtGetOp1()->gtLsraInfo.setSrcCandidates(this, allRegs(tree->TypeGet())); + } } if ((tree->gtFlags & GTF_VAR_DEATH) == 0) @@ -4154,7 +4165,7 @@ LinearScan::registerIsAvailable(RegRecord *physRegRecord, LsraLocation currentLo // Notes: // This will nearly always be identical to the registerType of the interval, except in the case // of SIMD types of 8 bytes (currently only Vector2) when they are passed and returned in integer -// registers. +// registers, or copied to a return temp. // This method need only be called in situations where we may be dealing with the register requirements // of a RefTypeUse RefPosition (i.e. not when we are only looking at the type of an interval, nor when // we are interested in the "defining" type of the interval). This is because the situation of interest @@ -4169,10 +4180,9 @@ LinearScan::getRegisterType(Interval *currentInterval, RefPosition* refPosition) #if defined(FEATURE_SIMD) && defined(_TARGET_AMD64_) if ((candidates & allRegs(regType)) == RBM_NONE) { - assert(genMaxOneBit(candidates) && - (regType == TYP_DOUBLE) && - (refPosition->refType == RefTypeUse) && - ((candidates & (RBM_ARG_REGS | RBM_LNGRET)) != RBM_NONE)); + assert((regType == TYP_DOUBLE) && + (refPosition->refType == RefTypeUse) && + ((candidates & allRegs(TYP_INT)) != RBM_NONE)); regType = TYP_INT; } #else // !(defined(FEATURE_SIMD) && defined(_TARGET_AMD64_)) @@ -6694,9 +6704,8 @@ LinearScan::insertUpperVectorSaveAndReload(GenTreePtr tree, RefPosition* refPosi assert(lclVarInterval->isLocalVar == true); LclVarDsc * varDsc = compiler->lvaTable + lclVarInterval->varNum; assert(varDsc->lvType == LargeVectorType); - regNumber lclVarReg = varDsc->lvRegNum; - assert(lclVarReg != REG_NA); - if (lclVarReg == REG_STK) + regNumber lclVarReg = lclVarInterval->physReg; + if (lclVarReg == REG_NA) { return; } diff --git a/src/jit/optimizer.cpp b/src/jit/optimizer.cpp index 61b1881bcd..2f781e9840 100644 --- a/src/jit/optimizer.cpp +++ b/src/jit/optimizer.cpp @@ -1813,6 +1813,24 @@ void Compiler::optFindNaturalLoops() goto NO_LOOP; } +#if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_) + // Disqualify loops where the first block of the loop is a finally target. + // The main problem is when multiple loops share a 'first' block that is a finally + // target and we canonicalize the loops by adding a new loop head. In that case, we + // need to update the blocks so the finally target bit is moved to the newly created + // block, and removed from the old 'first' block. This is 'hard', so at this point + // in the RyuJIT codebase (when we don't expect to keep the "old" ARM32 code generator + // long-term), it's easier to disallow the loop than to update the flow graph to + // support this case. + + if ((first->bbFlags & BBF_FINALLY_TARGET) != 0) + { + JITDUMP("Loop 'first' BB%02u is a finally target. Rejecting loop.\n", + first->bbNum); + goto NO_LOOP; + } +#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_) + /* At this point we have a loop - record it in the loop table * If we found only one exit, record it in the table too * (otherwise an exit = 0 in the loop table means multiple exits) */ diff --git a/src/jit/simdcodegenxarch.cpp b/src/jit/simdcodegenxarch.cpp index 59fed64056..6675b86f34 100644 --- a/src/jit/simdcodegenxarch.cpp +++ b/src/jit/simdcodegenxarch.cpp @@ -1428,6 +1428,39 @@ CodeGen::genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode) noway_assert(op2->isContained()); int byteShiftCnt = (int) op2->gtIntCon.gtIconVal * genTypeSize(baseType); + regNumber tmpReg = REG_NA; + if (simdNode->gtRsvdRegs != RBM_NONE) + { + assert(genCountBits(simdNode->gtRsvdRegs) == 1); + tmpReg = genRegNumFromMask(simdNode->gtRsvdRegs); + } + else + { + assert((byteShiftCnt == 0) || + varTypeIsFloating(baseType) || + (varTypeIsSmallInt(baseType) && (byteShiftCnt < 16))); + } + + if (byteShiftCnt >= 16) + { + assert(compiler->getSIMDInstructionSet() == InstructionSet_AVX); + byteShiftCnt -= 16; + regNumber newSrcReg; + if (varTypeIsFloating(baseType)) + { + newSrcReg = targetReg; + } + else + { + // Integer types + assert(tmpReg != REG_NA); + newSrcReg = tmpReg; + } + getEmitter()->emitIns_R_R_I(INS_vextractf128, EA_32BYTE, newSrcReg, srcReg, 0x01); + + srcReg = newSrcReg; + } + // Generate the following sequence: // 1) baseType is floating point // movaps targetReg, srcReg @@ -1435,6 +1468,7 @@ CodeGen::genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode) // // 2) baseType is not floating point // movaps tmpReg, srcReg <-- not generated if accessing zero'th element + // OR if tmpReg == srcReg // psrldq tmpReg, byteShiftCnt <-- not generated if accessing zero'th element // mov_xmm2i targetReg, tmpReg if (varTypeIsFloating(baseType)) @@ -1464,6 +1498,14 @@ CodeGen::genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode) { index /= 2; } + // We actually want index % 8 for the AVX case (for SSE it will never be > 8). + // Note that this doesn't matter functionally, because the instruction uses just the + // low 3 bits of index, but it's better to use the right value. + if (index > 8) + { + assert(compiler->getSIMDInstructionSet() == InstructionSet_AVX); + index -= 8; + } getEmitter()->emitIns_R_R_I(INS_pextrw, emitTypeSize(TYP_INT), targetReg, srcReg, index); @@ -1497,14 +1539,11 @@ CodeGen::genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode) { // We need a temp xmm register if the baseType is not floating point and // accessing non-zero'th element. - regNumber tmpReg = REG_NA; instruction ins; if (byteShiftCnt != 0) { - assert(simdNode->gtRsvdRegs != RBM_NONE); - assert(genCountBits(simdNode->gtRsvdRegs) == 1); - tmpReg = genRegNumFromMask(simdNode->gtRsvdRegs); + assert(tmpReg != REG_NA); if (tmpReg != srcReg) { @@ -1516,7 +1555,6 @@ CodeGen::genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode) } else { - assert(simdNode->gtRsvdRegs == RBM_NONE); tmpReg = srcReg; } diff --git a/src/jit/ssabuilder.cpp b/src/jit/ssabuilder.cpp index 69245c30a4..1dc9d3907d 100644 --- a/src/jit/ssabuilder.cpp +++ b/src/jit/ssabuilder.cpp @@ -753,14 +753,17 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count) // We have a variable i that is defined in block j and live at l, and l belongs to dom frontier of j. // So insert a phi node at l. JITDUMP("Inserting phi definition for V%02u at start of BB%02u.\n", lclNum, bbInDomFront->bbNum); - GenTreePtr phiLhs = m_pCompiler->gtNewLclvNode(lclNum, m_pCompiler->lvaTable[lclNum].TypeGet()); - GenTreePtr phiAsg = m_pCompiler->gtNewAssignNode( - phiLhs, - m_pCompiler->gtNewOperNode( - GT_PHI, - m_pCompiler->lvaTable[lclNum].TypeGet(), - NULL) - DEBUG_ARG(/*isPhiDefn*/true)); + + GenTreePtr phiLhs = m_pCompiler->gtNewLclvNode(lclNum, m_pCompiler->lvaTable[lclNum].TypeGet()); + + // Create 'phiRhs' as a GT_PHI node for 'lclNum', it will eventually hold a GT_LIST of GT_PHI_ARG nodes. + // However we have to construct this list so for now the gtOp1 of 'phiRhs' is a nullptr. + // It will get replaced with a GT_LIST of GT_PHI_ARG nodes in SsaBuilder::AssignPhiNodeRhsVariables() + // and in SsaBuilder::AddDefToHandlerPhis() + // + GenTreePtr phiRhs = m_pCompiler->gtNewOperNode(GT_PHI, m_pCompiler->lvaTable[lclNum].TypeGet(), nullptr); + + GenTreePtr phiAsg = m_pCompiler->gtNewAssignNode(phiLhs, phiRhs DEBUG_ARG(/*isPhiDefn*/true)); GenTreePtr stmt = m_pCompiler->fgInsertStmtAtBeg(bbInDomFront, phiAsg); m_pCompiler->gtSetStmtInfo(stmt); diff --git a/src/jit/valuenum.cpp b/src/jit/valuenum.cpp index c5625407b9..2680e0ec44 100644 --- a/src/jit/valuenum.cpp +++ b/src/jit/valuenum.cpp @@ -3890,9 +3890,18 @@ void Compiler::fgValueNumberBlock(BasicBlock* blk, bool newVNsForPhis) ValueNumPair sameVNPair; GenTreePtr phiFunc = phiDef->gtOp.gtOp2; + + // At this point a GT_PHI node should never have a nullptr for gtOp1 + // and the gtOp1 should always be a GT_LIST node. + GenTreePtr phiOp1 = phiFunc->gtOp.gtOp1; + noway_assert(phiOp1 != nullptr); + noway_assert(phiOp1->OperGet() == GT_LIST); + GenTreeArgList* phiArgs = phiFunc->gtOp.gtOp1->AsArgList(); - // Phi's should have more than one argument. - assert(phiArgs->Rest() != nullptr); + + // A GT_PHI node should have more than one argument. + noway_assert(phiArgs->Rest() != nullptr); + GenTreeLclVarCommon* phiArg = phiArgs->Current()->AsLclVarCommon(); phiArgs = phiArgs->Rest(); diff --git a/src/md/winmd/adapter.cpp b/src/md/winmd/adapter.cpp index 45c695c1d3..1be4e0a07b 100644 --- a/src/md/winmd/adapter.cpp +++ b/src/md/winmd/adapter.cpp @@ -207,6 +207,7 @@ WinMDAdapter::WinMDAdapter(IMDCommon *pRawMDCommon) , m_redirectedTypeSpecSigMemoTable(pRawMDCommon->GetMetaModelCommonRO()->CommonGetRowCount(mdtTypeSpec), NULL) , m_redirectedMethodSpecSigMemoTable(pRawMDCommon->GetMetaModelCommonRO()->CommonGetRowCount(mdtMethodSpec), NULL) , m_mangledTypeNameTable(pRawMDCommon->GetMetaModelCommonRO()->CommonGetRowCount(mdtTypeDef), NULL) + , m_extraAssemblyRefCount(-1) { m_rawAssemblyRefCount = pRawMDCommon->GetMetaModelCommonRO()->CommonGetRowCount(mdtAssemblyRef); m_pRedirectedVersionString = NULL; @@ -1095,6 +1096,60 @@ HRESULT WinMDAdapter::ModifyExportedTypeName( //------------------------------------------------------------------------------ +// We must optionaly add an assembly ref for System.Numerics.Vectors.dll since this assembly is not available +// on downlevel platforms. +// +// This function assumes that System.Numerics.Vectors.dll is the last assembly that +// we add so if we find a reference then we return ContractAssembly_Count otherwise we return +// ContractAssembly_Count - 1. +int WinMDAdapter::GetExtraAssemblyRefCount() +{ + HRESULT hr; + + if (m_extraAssemblyRefCount == -1) + { + mdAssemblyRef tkSystemNumericsVectors = TokenFromRid(m_rawAssemblyRefCount + ContractAssembly_SystemNumericsVectors + 1, mdtAssemblyRef); + ULONG cTypeRefRecs = m_pRawMetaModelCommonRO->CommonGetRowCount(mdtTypeRef); + BOOL systemNumericsVectorsTypeFound = FALSE; + + for (ULONG i = 1; i <= cTypeRefRecs; i++) + { + mdToken tkResolutionScope; + mdTypeRef tkTypeRef = TokenFromRid(i, mdtTypeRef); + + // Get the resolution scope(AssemblyRef) token for the type. GetTypeRefProps does the type redirection. + IfFailGo(GetTypeRefProps(tkTypeRef, nullptr, nullptr, &tkResolutionScope)); + + if (tkResolutionScope == tkSystemNumericsVectors) + { + systemNumericsVectorsTypeFound = TRUE; + break; + } + } + + if (systemNumericsVectorsTypeFound) + { + m_extraAssemblyRefCount = ContractAssembly_Count; + } + else + { + m_extraAssemblyRefCount = ContractAssembly_Count - 1; + } + } + +ErrExit: + if (m_extraAssemblyRefCount == -1) + { + // Setting m_extraAssemblyRefCount to ContractAssembly_Count so that this function returns a stable value and + // that if there is a System.Numerics type ref that it does not have a dangling assembly ref + m_extraAssemblyRefCount = ContractAssembly_Count; + } + + return m_extraAssemblyRefCount; +} + +//------------------------------------------------------------------------------ + /*static*/ void WinMDAdapter::GetExtraAssemblyRefProps(FrameworkAssemblyIndex index, LPCSTR* ppName, diff --git a/src/md/winmd/inc/adapter.h b/src/md/winmd/inc/adapter.h index 87fc410a77..748d65d473 100644 --- a/src/md/winmd/inc/adapter.h +++ b/src/md/winmd/inc/adapter.h @@ -102,7 +102,8 @@ public: ContractAssembly_SystemObjectModel, ContractAssembly_SystemRuntimeWindowsRuntime, ContractAssembly_SystemRuntimeWindowsRuntimeUIXaml, - ContractAssembly_SystemNumericsVectors, + ContractAssembly_SystemNumericsVectors, // GetExtraAssemblyRefCount assumes SystemNumericsVectors is the last assembly. + // If you add an assembly you must update GetActualExtraAssemblyRefCount. ContractAssembly_Count, }; @@ -120,10 +121,7 @@ public: WinMDTypeKind_Runtimeclass, }; - static int GetExtraAssemblyRefCount() - { - return ContractAssembly_Count; - } + int GetExtraAssemblyRefCount(); // Factory and destructor static HRESULT Create(IMDCommon *pRawMDCommon, /*[out]*/ WinMDAdapter **ppAdapter); @@ -813,7 +811,8 @@ private: //----------------------------------------------------------------------------------- mdAssemblyRef m_assemblyRefMscorlib; BOOL m_fReferencesMscorlibV4; // m_assemblyRefMscorlib is a version=4.0.0.0 AssemblyRef - ULONG m_rawAssemblyRefCount; // the saw assembly ref count not including the extra ones. + ULONG m_rawAssemblyRefCount; // the raw assembly ref count not including the extra ones. + LONG m_extraAssemblyRefCount; // the assembly ref count to return from IMetaDataAssemblyImport::EnumAssemblyRefs private: diff --git a/src/md/winmd/winmdimport.cpp b/src/md/winmd/winmdimport.cpp index ace02c262b..b0a229dbb0 100644 --- a/src/md/winmd/winmdimport.cpp +++ b/src/md/winmd/winmdimport.cpp @@ -1661,7 +1661,7 @@ class WinMDImport : public IMetaDataImport2 _ASSERTE(phInternalEnum->m_EnumType == MDSimpleEnum); _ASSERTE( phInternalEnum->m_ulCount == m_pWinMDAdapter->GetRawAssemblyRefCount()); - int n = WinMDAdapter::GetExtraAssemblyRefCount(); + int n = m_pWinMDAdapter->GetExtraAssemblyRefCount(); phInternalEnum->m_ulCount += n; phInternalEnum->u.m_ulEnd += n; diff --git a/src/md/winmd/winmdinternalimportro.cpp b/src/md/winmd/winmdinternalimportro.cpp index 1d82e13aeb..b4a448dd27 100644 --- a/src/md/winmd/winmdinternalimportro.cpp +++ b/src/md/winmd/winmdinternalimportro.cpp @@ -160,7 +160,7 @@ class WinMDInternalImportRO : public IMDInternalImport, IWinMDImport, IMetaModel { if (tkKind == mdtAssemblyRef) { - return m_pRawInternalImport->GetCountWithTokenKind(tkKind) + WinMDAdapter::GetExtraAssemblyRefCount(); + return m_pRawInternalImport->GetCountWithTokenKind(tkKind) + m_pWinMDAdapter->GetExtraAssemblyRefCount(); } else { @@ -297,7 +297,7 @@ class WinMDInternalImportRO : public IMDInternalImport, IWinMDImport, IMetaModel if (tkKind == mdtAssemblyRef) { _ASSERTE( phEnum->m_ulCount == m_pWinMDAdapter->GetRawAssemblyRefCount()); - int n = WinMDAdapter::GetExtraAssemblyRefCount(); + int n = m_pWinMDAdapter->GetExtraAssemblyRefCount(); phEnum->m_ulCount += n; phEnum->u.m_ulEnd += n; } @@ -320,7 +320,7 @@ ErrExit: if (tkKind == mdtAssemblyRef) { _ASSERTE( phEnum->m_ulCount == m_pWinMDAdapter->GetRawAssemblyRefCount()); - int n = WinMDAdapter::GetExtraAssemblyRefCount(); + int n = m_pWinMDAdapter->GetExtraAssemblyRefCount(); phEnum->m_ulCount += n; phEnum->u.m_ulEnd += n; } diff --git a/src/mscorlib/src/System/AppDomain.cs b/src/mscorlib/src/System/AppDomain.cs index 52375b1534..932a66021a 100644 --- a/src/mscorlib/src/System/AppDomain.cs +++ b/src/mscorlib/src/System/AppDomain.cs @@ -606,7 +606,27 @@ namespace System { [SecuritySafeCritical] internal String GetTargetFrameworkName() { - return _FusionStore.TargetFrameworkName; + String targetFrameworkName = _FusionStore.TargetFrameworkName; + + if (targetFrameworkName == null && IsDefaultAppDomain() && !_FusionStore.CheckedForTargetFrameworkName) + { + // This should only be run in the default appdomain. All other appdomains should have + // values copied from the default appdomain and/or specified by the host. + Assembly assembly = Assembly.GetEntryAssembly(); + if (assembly != null) + { + TargetFrameworkAttribute[] attrs = (TargetFrameworkAttribute[])assembly.GetCustomAttributes(typeof(TargetFrameworkAttribute)); + if (attrs != null && attrs.Length > 0) + { + Contract.Assert(attrs.Length == 1); + targetFrameworkName = attrs[0].FrameworkName; + _FusionStore.TargetFrameworkName = targetFrameworkName; + } + } + _FusionStore.CheckedForTargetFrameworkName = true; + } + + return targetFrameworkName; } /// <summary> diff --git a/src/mscorlib/src/System/AppDomainSetup.cs b/src/mscorlib/src/System/AppDomainSetup.cs index 8bb8d8c0ef..198404ddb2 100644 --- a/src/mscorlib/src/System/AppDomainSetup.cs +++ b/src/mscorlib/src/System/AppDomainSetup.cs @@ -209,10 +209,7 @@ namespace System { _AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo(copy._AppDomainSortingSetupInfo); } #endif - // The behavior of computing the TargetFrameworkName should be preserved! - // This value needs to be computed before the copy constructor returns the value. - // Note: The computed value can be null if the assembly does not have a TargetFrameworkAttribute - _TargetFrameworkName = copy.TargetFrameworkName; + _TargetFrameworkName = copy._TargetFrameworkName; #if FEATURE_RANDOMIZED_STRING_HASHING _UseRandomizedStringHashing = copy._UseRandomizedStringHashing; @@ -650,23 +647,6 @@ namespace System { // A target Framework moniker, in a format parsible by the FrameworkName class. public String TargetFrameworkName { get { - if (!CheckedForTargetFrameworkName && _TargetFrameworkName == null && AppDomain.CurrentDomain.IsDefaultAppDomain() && AppDomain.CurrentDomain.FusionStore == this) - { - // This should only be run for the default appdomain. All other appdomains should have - // values copied from the default appdomain and/or specified by the host. - Assembly assembly = Assembly.GetEntryAssembly(); - if (assembly != null) - { - TargetFrameworkAttribute[] attrs = (TargetFrameworkAttribute[])assembly.GetCustomAttributes(typeof(TargetFrameworkAttribute)); - if (attrs != null && attrs.Length > 0) - { - Contract.Assert(attrs.Length == 1); - _TargetFrameworkName = attrs[0].FrameworkName; - } - } - CheckedForTargetFrameworkName = true; - } - return _TargetFrameworkName; } set { diff --git a/src/mscorlib/src/System/Globalization/CalendarData.cs b/src/mscorlib/src/System/Globalization/CalendarData.cs index 1e5133e37c..8f8e20805f 100644 --- a/src/mscorlib/src/System/Globalization/CalendarData.cs +++ b/src/mscorlib/src/System/Globalization/CalendarData.cs @@ -259,6 +259,14 @@ namespace System.Globalization case CalendarId.JAPANESELUNISOLAR: this.saEraNames = JapaneseCalendar.EraNames(); break; + + case CalendarId.PERSIAN: + if (this.saEraNames == null || this.saEraNames.Length == 0 || String.IsNullOrEmpty(this.saEraNames[0])) + { + this.saEraNames = new String[] { "\x0647\x002e\x0634" }; + } + break; + default: // Most calendars are just "A.D." this.saEraNames = Invariant.saEraNames; @@ -313,6 +321,14 @@ namespace System.Globalization this.saAbbrevEraNames[0] = this.saEraNames[0]; } break; + + case CalendarId.PERSIAN: + if (this.saAbbrevEraNames == null || this.saAbbrevEraNames.Length == 0 || String.IsNullOrEmpty(this.saAbbrevEraNames[0])) + { + this.saAbbrevEraNames = this.saEraNames; + } + break; + default: // Most calendars just use the full name this.saAbbrevEraNames = this.saEraNames; diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs index dde61478cc..91bd6e7020 100644 --- a/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs +++ b/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs @@ -492,7 +492,11 @@ namespace System.Reflection.Emit { else { if (destType.IsValueType) - throw new ArgumentException(Environment.GetResourceString("Argument_ConstantNull")); + { + // nullable types can hold null value. + if (!(destType.IsGenericType && destType.GetGenericTypeDefinition() == typeof(Nullable<>))) + throw new ArgumentException(Environment.GetResourceString("Argument_ConstantNull")); + } SetConstantValue(module.GetNativeHandle(), tk, (int)CorElementType.Class, null); } diff --git a/src/pal/prebuilt/inc/clretwall.h b/src/pal/prebuilt/inc/clretwall.h index 6d3f9b6c04..865fccf866 100644 --- a/src/pal/prebuilt/inc/clretwall.h +++ b/src/pal/prebuilt/inc/clretwall.h @@ -218,7 +218,7 @@ Remarks: #endif #endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION //+ -// Provider Microsoft-Windows-DotNETRuntime Event Count 159 +// Provider Microsoft-Windows-DotNETRuntime Event Count 166 //+ EXTERN_C __declspec(selectany) const GUID MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER = {0xe13c0d23, 0xccbc, 0x4e12, {0x93, 0x1b, 0xd9, 0xcc, 0x2e, 0xee, 0x27, 0xe4}}; @@ -327,6 +327,12 @@ EXTERN_C __declspec(selectany) const GUID IOThreadRetirementId = {0x840c8456, 0x EXTERN_C __declspec(selectany) const GUID ThreadpoolSuspensionId = {0xc424b3e3, 0x2ae0, 0x416e, {0xa0, 0x39, 0x41, 0x0c, 0x5d, 0x8e, 0x5f, 0x14}}; #define CLR_EXCEPTION_TASK 0x7 EXTERN_C __declspec(selectany) const GUID ExceptionId = {0x300ce105, 0x86d1, 0x41f8, {0xb9, 0xd2, 0x83, 0xfc, 0xbf, 0xf3, 0x2d, 0x99}}; +#define CLR_EXCEPTION_CATCH_TASK 0x1b +EXTERN_C __declspec(selectany) const GUID ExceptionCatchId = {0x5bbf9499, 0x1715, 0x4658, {0x88, 0xdc, 0xaf, 0xd7, 0x69, 0x0a, 0x87, 0x11}}; +#define CLR_EXCEPTION_FINALLY_TASK 0x1c +EXTERN_C __declspec(selectany) const GUID ExceptionFinallyId = {0x9565bc31, 0x300f, 0x4ea2, {0xa5, 0x32, 0x30, 0xbc, 0xe9, 0xa1, 0x41, 0x99}}; +#define CLR_EXCEPTION_FILTER_TASK 0x1d +EXTERN_C __declspec(selectany) const GUID ExceptionFilterId = {0x72e72606, 0xbb71, 0x4290, {0xa2, 0x42, 0xd5, 0xf3, 0x6c, 0xe5, 0x31, 0x2e}}; #define CLR_CONTENTION_TASK 0x8 EXTERN_C __declspec(selectany) const GUID ContentionId = {0x561410f5, 0xa138, 0x4ab3, {0x94, 0x5e, 0x51, 0x64, 0x83, 0xcd, 0xdf, 0xbc}}; #define CLR_METHOD_TASK 0x9 @@ -396,6 +402,7 @@ EXTERN_C __declspec(selectany) const GUID DebugExceptionProcessingId = {0xc44121 #define CLR_STACK_KEYWORD 0x40000000 #define CLR_THREADTRANSFER_KEYWORD 0x80000000 #define CLR_DEBUGGER_KEYWORD 0x100000000 +#define CLR_MONITORING_KEYWORD 0x200000000 // // Event Descriptors @@ -568,8 +575,22 @@ EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ThreadRunning = {0x47, 0x0 #define ThreadRunning_value 0x47 EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionThrown = {0x50, 0x0, 0x0, 0x4, 0x1, 0x7, 0x0}; #define ExceptionThrown_value 0x50 -EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionThrown_V1 = {0x50, 0x1, 0x0, 0x2, 0x1, 0x7, 0x8000}; +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionThrown_V1 = {0x50, 0x1, 0x0, 0x2, 0x1, 0x7, 0x200008000}; #define ExceptionThrown_V1_value 0x50 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionCatchStart = {0xfa, 0x0, 0x0, 0x4, 0x1, 0x1b, 0x8000}; +#define ExceptionCatchStart_value 0xfa +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionCatchStop = {0xfb, 0x0, 0x0, 0x4, 0x2, 0x1b, 0x8000}; +#define ExceptionCatchStop_value 0xfb +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionFinallyStart = {0xfc, 0x0, 0x0, 0x4, 0x1, 0x1c, 0x8000}; +#define ExceptionFinallyStart_value 0xfc +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionFinallyStop = {0xfd, 0x0, 0x0, 0x4, 0x2, 0x1c, 0x8000}; +#define ExceptionFinallyStop_value 0xfd +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionFilterStart = {0xfe, 0x0, 0x0, 0x4, 0x1, 0x1d, 0x8000}; +#define ExceptionFilterStart_value 0xfe +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionFilterStop = {0xff, 0x0, 0x0, 0x4, 0x2, 0x1d, 0x8000}; +#define ExceptionFilterStop_value 0xff +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ExceptionThrownStop = {0x100, 0x0, 0x0, 0x4, 0x2, 0x7, 0x8000}; +#define ExceptionThrownStop_value 0x100 EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Contention = {0x51, 0x0, 0x0, 0x4, 0x1, 0x8, 0x0}; #define Contention_value 0x51 EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ContentionStart_V1 = {0x51, 0x1, 0x0, 0x4, 0x1, 0x8, 0x4000}; @@ -747,9 +768,9 @@ EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR DebugExceptionProcessingEn // EXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG Microsoft_Windows_DotNETRuntimeEnableBits[1]; -EXTERN_C __declspec(selectany) const ULONGLONG Microsoft_Windows_DotNETRuntimeKeywords[30] = {0x1, 0x1, 0x10001, 0x80000, 0x100000, 0x200000, 0x400000, 0x2, 0x2000000, 0x10000, 0x10000, 0x80010000, 0x80010000, 0x0, 0x8000, 0x4000, 0x40000000, 0x800, 0x10800, 0x2000, 0x30, 0x10, 0x1000, 0x20000, 0x8, 0x20000008, 0x20000000, 0x400, 0x400, 0x100000000}; -EXTERN_C __declspec(selectany) const UCHAR Microsoft_Windows_DotNETRuntimeLevels[30] = {4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 2, 4, 0, 4, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 4, 4}; -EXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context = {0, 0, 0, 0, 0, 0, 0, 0, 30, Microsoft_Windows_DotNETRuntimeEnableBits, Microsoft_Windows_DotNETRuntimeKeywords, Microsoft_Windows_DotNETRuntimeLevels}; +EXTERN_C __declspec(selectany) const ULONGLONG Microsoft_Windows_DotNETRuntimeKeywords[31] = {0x1, 0x1, 0x10001, 0x80000, 0x100000, 0x200000, 0x400000, 0x2, 0x2000000, 0x10000, 0x10000, 0x80010000, 0x80010000, 0x0, 0x200008000, 0x8000, 0x4000, 0x40000000, 0x800, 0x10800, 0x2000, 0x30, 0x10, 0x1000, 0x20000, 0x8, 0x20000008, 0x20000000, 0x400, 0x400, 0x100000000}; +EXTERN_C __declspec(selectany) const UCHAR Microsoft_Windows_DotNETRuntimeLevels[31] = {4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 2, 4, 4, 0, 4, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 4, 4}; +EXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context = {0, 0, 0, 0, 0, 0, 0, 0, 31, Microsoft_Windows_DotNETRuntimeEnableBits, Microsoft_Windows_DotNETRuntimeKeywords, Microsoft_Windows_DotNETRuntimeLevels}; EXTERN_C __declspec(selectany) REGHANDLE Microsoft_Windows_DotNETRuntimeHandle = (REGHANDLE)0; @@ -2037,6 +2058,104 @@ Remarks: : ERROR_SUCCESS\ // +// Enablement check macro for ExceptionCatchStart +// + +#define EventEnabledExceptionCatchStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00008000) != 0) + +// +// Event Macro for ExceptionCatchStart +// +#define FireEtwExceptionCatchStart(EntryEIP, MethodID, MethodName, ClrInstanceID)\ + EventEnabledExceptionCatchStart() ?\ + CoTemplate_xxzh(Microsoft_Windows_DotNETRuntimeHandle, &ExceptionCatchStart, EntryEIP, MethodID, MethodName, ClrInstanceID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for ExceptionCatchStop +// + +#define EventEnabledExceptionCatchStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00008000) != 0) + +// +// Event Macro for ExceptionCatchStop +// +#define FireEtwExceptionCatchStop()\ + EventEnabledExceptionCatchStop() ?\ + CoTemplateEventDescriptor(Microsoft_Windows_DotNETRuntimeHandle, &ExceptionCatchStop)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for ExceptionFinallyStart +// + +#define EventEnabledExceptionFinallyStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00008000) != 0) + +// +// Event Macro for ExceptionFinallyStart +// +#define FireEtwExceptionFinallyStart(EntryEIP, MethodID, MethodName, ClrInstanceID)\ + EventEnabledExceptionFinallyStart() ?\ + CoTemplate_xxzh(Microsoft_Windows_DotNETRuntimeHandle, &ExceptionFinallyStart, EntryEIP, MethodID, MethodName, ClrInstanceID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for ExceptionFinallyStop +// + +#define EventEnabledExceptionFinallyStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00008000) != 0) + +// +// Event Macro for ExceptionFinallyStop +// +#define FireEtwExceptionFinallyStop()\ + EventEnabledExceptionFinallyStop() ?\ + CoTemplateEventDescriptor(Microsoft_Windows_DotNETRuntimeHandle, &ExceptionFinallyStop)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for ExceptionFilterStart +// + +#define EventEnabledExceptionFilterStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00008000) != 0) + +// +// Event Macro for ExceptionFilterStart +// +#define FireEtwExceptionFilterStart(EntryEIP, MethodID, MethodName, ClrInstanceID)\ + EventEnabledExceptionFilterStart() ?\ + CoTemplate_xxzh(Microsoft_Windows_DotNETRuntimeHandle, &ExceptionFilterStart, EntryEIP, MethodID, MethodName, ClrInstanceID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for ExceptionFilterStop +// + +#define EventEnabledExceptionFilterStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00008000) != 0) + +// +// Event Macro for ExceptionFilterStop +// +#define FireEtwExceptionFilterStop()\ + EventEnabledExceptionFilterStop() ?\ + CoTemplateEventDescriptor(Microsoft_Windows_DotNETRuntimeHandle, &ExceptionFilterStop)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for ExceptionThrownStop +// + +#define EventEnabledExceptionThrownStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00008000) != 0) + +// +// Event Macro for ExceptionThrownStop +// +#define FireEtwExceptionThrownStop()\ + EventEnabledExceptionThrownStop() ?\ + CoTemplateEventDescriptor(Microsoft_Windows_DotNETRuntimeHandle, &ExceptionThrownStop)\ + : ERROR_SUCCESS\ + +// // Enablement check macro for Contention // @@ -2054,7 +2173,7 @@ Remarks: // Enablement check macro for ContentionStart_V1 // -#define EventEnabledContentionStart_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00008000) != 0) +#define EventEnabledContentionStart_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00010000) != 0) // // Event Macro for ContentionStart_V1 @@ -2068,7 +2187,7 @@ Remarks: // Enablement check macro for ContentionStop // -#define EventEnabledContentionStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00008000) != 0) +#define EventEnabledContentionStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00010000) != 0) // // Event Macro for ContentionStop @@ -2082,7 +2201,7 @@ Remarks: // Enablement check macro for CLRStackWalk // -#define EventEnabledCLRStackWalk() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00010000) != 0) +#define EventEnabledCLRStackWalk() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00020000) != 0) // // Event Macro for CLRStackWalk @@ -2096,7 +2215,7 @@ Remarks: // Enablement check macro for AppDomainMemAllocated // -#define EventEnabledAppDomainMemAllocated() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00020000) != 0) +#define EventEnabledAppDomainMemAllocated() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00040000) != 0) // // Event Macro for AppDomainMemAllocated @@ -2110,7 +2229,7 @@ Remarks: // Enablement check macro for AppDomainMemSurvived // -#define EventEnabledAppDomainMemSurvived() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00020000) != 0) +#define EventEnabledAppDomainMemSurvived() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00040000) != 0) // // Event Macro for AppDomainMemSurvived @@ -2124,7 +2243,7 @@ Remarks: // Enablement check macro for ThreadCreated // -#define EventEnabledThreadCreated() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00040000) != 0) +#define EventEnabledThreadCreated() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00080000) != 0) // // Event Macro for ThreadCreated @@ -2138,7 +2257,7 @@ Remarks: // Enablement check macro for ThreadTerminated // -#define EventEnabledThreadTerminated() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00040000) != 0) +#define EventEnabledThreadTerminated() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00080000) != 0) // // Event Macro for ThreadTerminated @@ -2152,7 +2271,7 @@ Remarks: // Enablement check macro for ThreadDomainEnter // -#define EventEnabledThreadDomainEnter() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00040000) != 0) +#define EventEnabledThreadDomainEnter() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00080000) != 0) // // Event Macro for ThreadDomainEnter @@ -2166,7 +2285,7 @@ Remarks: // Enablement check macro for ILStubGenerated // -#define EventEnabledILStubGenerated() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00080000) != 0) +#define EventEnabledILStubGenerated() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) // // Event Macro for ILStubGenerated @@ -2180,7 +2299,7 @@ Remarks: // Enablement check macro for ILStubCacheHit // -#define EventEnabledILStubCacheHit() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00080000) != 0) +#define EventEnabledILStubCacheHit() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) // // Event Macro for ILStubCacheHit @@ -2194,7 +2313,7 @@ Remarks: // Enablement check macro for DCStartCompleteV2 // -#define EventEnabledDCStartCompleteV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledDCStartCompleteV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for DCStartCompleteV2 @@ -2208,7 +2327,7 @@ Remarks: // Enablement check macro for DCEndCompleteV2 // -#define EventEnabledDCEndCompleteV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledDCEndCompleteV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for DCEndCompleteV2 @@ -2222,7 +2341,7 @@ Remarks: // Enablement check macro for MethodDCStartV2 // -#define EventEnabledMethodDCStartV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodDCStartV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodDCStartV2 @@ -2236,7 +2355,7 @@ Remarks: // Enablement check macro for MethodDCEndV2 // -#define EventEnabledMethodDCEndV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodDCEndV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodDCEndV2 @@ -2250,7 +2369,7 @@ Remarks: // Enablement check macro for MethodDCStartVerboseV2 // -#define EventEnabledMethodDCStartVerboseV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodDCStartVerboseV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodDCStartVerboseV2 @@ -2264,7 +2383,7 @@ Remarks: // Enablement check macro for MethodDCEndVerboseV2 // -#define EventEnabledMethodDCEndVerboseV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodDCEndVerboseV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodDCEndVerboseV2 @@ -2278,7 +2397,7 @@ Remarks: // Enablement check macro for MethodLoad // -#define EventEnabledMethodLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodLoad @@ -2292,7 +2411,7 @@ Remarks: // Enablement check macro for MethodLoad_V1 // -#define EventEnabledMethodLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodLoad_V1 @@ -2306,7 +2425,7 @@ Remarks: // Enablement check macro for MethodLoad_V2 // -#define EventEnabledMethodLoad_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodLoad_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodLoad_V2 @@ -2320,7 +2439,7 @@ Remarks: // Enablement check macro for MethodUnload // -#define EventEnabledMethodUnload() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodUnload() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodUnload @@ -2334,7 +2453,7 @@ Remarks: // Enablement check macro for MethodUnload_V1 // -#define EventEnabledMethodUnload_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodUnload_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodUnload_V1 @@ -2348,7 +2467,7 @@ Remarks: // Enablement check macro for MethodUnload_V2 // -#define EventEnabledMethodUnload_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodUnload_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodUnload_V2 @@ -2362,7 +2481,7 @@ Remarks: // Enablement check macro for MethodLoadVerbose // -#define EventEnabledMethodLoadVerbose() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodLoadVerbose() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodLoadVerbose @@ -2376,7 +2495,7 @@ Remarks: // Enablement check macro for MethodLoadVerbose_V1 // -#define EventEnabledMethodLoadVerbose_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodLoadVerbose_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodLoadVerbose_V1 @@ -2390,7 +2509,7 @@ Remarks: // Enablement check macro for MethodLoadVerbose_V2 // -#define EventEnabledMethodLoadVerbose_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodLoadVerbose_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodLoadVerbose_V2 @@ -2404,7 +2523,7 @@ Remarks: // Enablement check macro for MethodUnloadVerbose // -#define EventEnabledMethodUnloadVerbose() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodUnloadVerbose() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodUnloadVerbose @@ -2418,7 +2537,7 @@ Remarks: // Enablement check macro for MethodUnloadVerbose_V1 // -#define EventEnabledMethodUnloadVerbose_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodUnloadVerbose_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodUnloadVerbose_V1 @@ -2432,7 +2551,7 @@ Remarks: // Enablement check macro for MethodUnloadVerbose_V2 // -#define EventEnabledMethodUnloadVerbose_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00100000) != 0) +#define EventEnabledMethodUnloadVerbose_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) // // Event Macro for MethodUnloadVerbose_V2 @@ -2446,7 +2565,7 @@ Remarks: // Enablement check macro for MethodJittingStarted // -#define EventEnabledMethodJittingStarted() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) +#define EventEnabledMethodJittingStarted() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00400000) != 0) // // Event Macro for MethodJittingStarted @@ -2460,7 +2579,7 @@ Remarks: // Enablement check macro for MethodJittingStarted_V1 // -#define EventEnabledMethodJittingStarted_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00200000) != 0) +#define EventEnabledMethodJittingStarted_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00400000) != 0) // // Event Macro for MethodJittingStarted_V1 @@ -2474,7 +2593,7 @@ Remarks: // Enablement check macro for MethodJitInliningSucceeded // -#define EventEnabledMethodJitInliningSucceeded() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00400000) != 0) +#define EventEnabledMethodJitInliningSucceeded() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00800000) != 0) // // Event Macro for MethodJitInliningSucceeded @@ -2488,7 +2607,7 @@ Remarks: // Enablement check macro for MethodJitInliningFailed // -#define EventEnabledMethodJitInliningFailed() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00400000) != 0) +#define EventEnabledMethodJitInliningFailed() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00800000) != 0) // // Event Macro for MethodJitInliningFailed @@ -2502,7 +2621,7 @@ Remarks: // Enablement check macro for MethodJitTailCallSucceeded // -#define EventEnabledMethodJitTailCallSucceeded() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00400000) != 0) +#define EventEnabledMethodJitTailCallSucceeded() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00800000) != 0) // // Event Macro for MethodJitTailCallSucceeded @@ -2516,7 +2635,7 @@ Remarks: // Enablement check macro for MethodJitTailCallFailed // -#define EventEnabledMethodJitTailCallFailed() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00400000) != 0) +#define EventEnabledMethodJitTailCallFailed() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00800000) != 0) // // Event Macro for MethodJitTailCallFailed @@ -2530,7 +2649,7 @@ Remarks: // Enablement check macro for MethodILToNativeMap // -#define EventEnabledMethodILToNativeMap() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x00800000) != 0) +#define EventEnabledMethodILToNativeMap() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) // // Event Macro for MethodILToNativeMap @@ -2544,7 +2663,7 @@ Remarks: // Enablement check macro for ModuleDCStartV2 // -#define EventEnabledModuleDCStartV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledModuleDCStartV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for ModuleDCStartV2 @@ -2558,7 +2677,7 @@ Remarks: // Enablement check macro for ModuleDCEndV2 // -#define EventEnabledModuleDCEndV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledModuleDCEndV2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for ModuleDCEndV2 @@ -2572,7 +2691,7 @@ Remarks: // Enablement check macro for DomainModuleLoad // -#define EventEnabledDomainModuleLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledDomainModuleLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for DomainModuleLoad @@ -2586,7 +2705,7 @@ Remarks: // Enablement check macro for DomainModuleLoad_V1 // -#define EventEnabledDomainModuleLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledDomainModuleLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for DomainModuleLoad_V1 @@ -2600,7 +2719,7 @@ Remarks: // Enablement check macro for ModuleLoad // -#define EventEnabledModuleLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledModuleLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for ModuleLoad @@ -2614,7 +2733,7 @@ Remarks: // Enablement check macro for ModuleLoad_V1 // -#define EventEnabledModuleLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) +#define EventEnabledModuleLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x04000000) != 0) // // Event Macro for ModuleLoad_V1 @@ -2628,7 +2747,7 @@ Remarks: // Enablement check macro for ModuleLoad_V2 // -#define EventEnabledModuleLoad_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) +#define EventEnabledModuleLoad_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x04000000) != 0) // // Event Macro for ModuleLoad_V2 @@ -2642,7 +2761,7 @@ Remarks: // Enablement check macro for ModuleUnload // -#define EventEnabledModuleUnload() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledModuleUnload() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for ModuleUnload @@ -2656,7 +2775,7 @@ Remarks: // Enablement check macro for ModuleUnload_V1 // -#define EventEnabledModuleUnload_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) +#define EventEnabledModuleUnload_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x04000000) != 0) // // Event Macro for ModuleUnload_V1 @@ -2670,7 +2789,7 @@ Remarks: // Enablement check macro for ModuleUnload_V2 // -#define EventEnabledModuleUnload_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) +#define EventEnabledModuleUnload_V2() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x04000000) != 0) // // Event Macro for ModuleUnload_V2 @@ -2684,7 +2803,7 @@ Remarks: // Enablement check macro for AssemblyLoad // -#define EventEnabledAssemblyLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledAssemblyLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for AssemblyLoad @@ -2698,7 +2817,7 @@ Remarks: // Enablement check macro for AssemblyLoad_V1 // -#define EventEnabledAssemblyLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledAssemblyLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for AssemblyLoad_V1 @@ -2712,7 +2831,7 @@ Remarks: // Enablement check macro for AssemblyUnload // -#define EventEnabledAssemblyUnload() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledAssemblyUnload() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for AssemblyUnload @@ -2726,7 +2845,7 @@ Remarks: // Enablement check macro for AssemblyUnload_V1 // -#define EventEnabledAssemblyUnload_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledAssemblyUnload_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for AssemblyUnload_V1 @@ -2740,7 +2859,7 @@ Remarks: // Enablement check macro for AppDomainLoad // -#define EventEnabledAppDomainLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledAppDomainLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for AppDomainLoad @@ -2754,7 +2873,7 @@ Remarks: // Enablement check macro for AppDomainLoad_V1 // -#define EventEnabledAppDomainLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledAppDomainLoad_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for AppDomainLoad_V1 @@ -2768,7 +2887,7 @@ Remarks: // Enablement check macro for AppDomainUnload // -#define EventEnabledAppDomainUnload() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledAppDomainUnload() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for AppDomainUnload @@ -2782,7 +2901,7 @@ Remarks: // Enablement check macro for AppDomainUnload_V1 // -#define EventEnabledAppDomainUnload_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x01000000) != 0) +#define EventEnabledAppDomainUnload_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x02000000) != 0) // // Event Macro for AppDomainUnload_V1 @@ -2796,7 +2915,7 @@ Remarks: // Enablement check macro for ModuleRangeLoad // -#define EventEnabledModuleRangeLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x04000000) != 0) +#define EventEnabledModuleRangeLoad() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x08000000) != 0) // // Event Macro for ModuleRangeLoad @@ -2810,7 +2929,7 @@ Remarks: // Enablement check macro for StrongNameVerificationStart // -#define EventEnabledStrongNameVerificationStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x08000000) != 0) +#define EventEnabledStrongNameVerificationStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x10000000) != 0) // // Event Macro for StrongNameVerificationStart @@ -2824,7 +2943,7 @@ Remarks: // Enablement check macro for StrongNameVerificationStart_V1 // -#define EventEnabledStrongNameVerificationStart_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x08000000) != 0) +#define EventEnabledStrongNameVerificationStart_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x10000000) != 0) // // Event Macro for StrongNameVerificationStart_V1 @@ -2838,7 +2957,7 @@ Remarks: // Enablement check macro for StrongNameVerificationStop // -#define EventEnabledStrongNameVerificationStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x10000000) != 0) +#define EventEnabledStrongNameVerificationStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x20000000) != 0) // // Event Macro for StrongNameVerificationStop @@ -2852,7 +2971,7 @@ Remarks: // Enablement check macro for StrongNameVerificationStop_V1 // -#define EventEnabledStrongNameVerificationStop_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x10000000) != 0) +#define EventEnabledStrongNameVerificationStop_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x20000000) != 0) // // Event Macro for StrongNameVerificationStop_V1 @@ -2866,7 +2985,7 @@ Remarks: // Enablement check macro for AuthenticodeVerificationStart // -#define EventEnabledAuthenticodeVerificationStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x08000000) != 0) +#define EventEnabledAuthenticodeVerificationStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x10000000) != 0) // // Event Macro for AuthenticodeVerificationStart @@ -2880,7 +2999,7 @@ Remarks: // Enablement check macro for AuthenticodeVerificationStart_V1 // -#define EventEnabledAuthenticodeVerificationStart_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x08000000) != 0) +#define EventEnabledAuthenticodeVerificationStart_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x10000000) != 0) // // Event Macro for AuthenticodeVerificationStart_V1 @@ -2894,7 +3013,7 @@ Remarks: // Enablement check macro for AuthenticodeVerificationStop // -#define EventEnabledAuthenticodeVerificationStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x10000000) != 0) +#define EventEnabledAuthenticodeVerificationStop() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x20000000) != 0) // // Event Macro for AuthenticodeVerificationStop @@ -2908,7 +3027,7 @@ Remarks: // Enablement check macro for AuthenticodeVerificationStop_V1 // -#define EventEnabledAuthenticodeVerificationStop_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x10000000) != 0) +#define EventEnabledAuthenticodeVerificationStop_V1() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x20000000) != 0) // // Event Macro for AuthenticodeVerificationStop_V1 @@ -3020,7 +3139,7 @@ Remarks: // Enablement check macro for DebugIPCEventStart // -#define EventEnabledDebugIPCEventStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x20000000) != 0) +#define EventEnabledDebugIPCEventStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x40000000) != 0) // // Event Macro for DebugIPCEventStart @@ -3034,7 +3153,7 @@ Remarks: // Enablement check macro for DebugIPCEventEnd // -#define EventEnabledDebugIPCEventEnd() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x20000000) != 0) +#define EventEnabledDebugIPCEventEnd() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x40000000) != 0) // // Event Macro for DebugIPCEventEnd @@ -3048,7 +3167,7 @@ Remarks: // Enablement check macro for DebugExceptionProcessingStart // -#define EventEnabledDebugExceptionProcessingStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x20000000) != 0) +#define EventEnabledDebugExceptionProcessingStart() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x40000000) != 0) // // Event Macro for DebugExceptionProcessingStart @@ -3062,7 +3181,7 @@ Remarks: // Enablement check macro for DebugExceptionProcessingEnd // -#define EventEnabledDebugExceptionProcessingEnd() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x20000000) != 0) +#define EventEnabledDebugExceptionProcessingEnd() ((Microsoft_Windows_DotNETRuntimeEnableBits[0] & 0x40000000) != 0) // // Event Macro for DebugExceptionProcessingEnd @@ -8727,6 +8846,50 @@ MCGEN_CALLOUT(RegHandle, #endif // +//Template from manifest : ExceptionHandling +// +#ifndef CoTemplate_xxzh_def +#define CoTemplate_xxzh_def +ETW_INLINE +ULONG +CoTemplate_xxzh( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ unsigned __int64 _Arg1, + _In_opt_ PCWSTR _Arg2, + _In_ const unsigned short _Arg3 + ) +{ +#define ARGUMENT_COUNT_xxzh 4 + ULONG Error = ERROR_SUCCESS; + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xxzh]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64) ); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(unsigned __int64) ); + + EventDataDescCreate(&EventData[2], + (_Arg2 != NULL) ? _Arg2 : L"NULL", + (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const unsigned short) ); + + Error = EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xxzh, EventData); + +#ifdef MCGEN_CALLOUT +MCGEN_CALLOUT(RegHandle, + Descriptor, + ARGUMENT_COUNT_xxzh, + EventData); +#endif + + return Error; +} +#endif + +// //Template from manifest : Contention // #ifndef CoTemplate_ch_def @@ -12274,6 +12437,7 @@ MCGEN_CALLOUT(RegHandle, #define MSG_RuntimePublisher_StackKeywordMessage 0x1000001FL #define MSG_RuntimePublisher_ThreadTransferKeywordMessage 0x10000020L #define MSG_RuntimePublisher_DebuggerKeywordMessage 0x10000021L +#define MSG_RuntimePublisher_MonitoringKeywordMessage 0x10000022L #define MSG_RundownPublisher_LoaderKeywordMessage 0x11000004L #define MSG_RundownPublisher_JitKeywordMessage 0x11000005L #define MSG_RundownPublisher_NGenKeywordMessage 0x11000006L @@ -12558,6 +12722,9 @@ MCGEN_CALLOUT(RegHandle, #define MSG_RuntimePublisher_ThreadTaskMessage 0x70000018L #define MSG_RuntimePublisher_DebugIPCEventTaskMessage 0x70000019L #define MSG_RuntimePublisher_DebugExceptionProcessingTaskMessage 0x7000001AL +#define MSG_RuntimePublisher_ExceptionCatchTaskMessage 0x7000001BL +#define MSG_RuntimePublisher_ExceptionFinallyTaskMessage 0x7000001CL +#define MSG_RuntimePublisher_ExceptionFilterTaskMessage 0x7000001DL #define MSG_RundownPublisher_MethodTaskMessage 0x71000001L #define MSG_RundownPublisher_LoaderTaskMessage 0x71000002L #define MSG_RundownPublisher_StackTaskMessage 0x7100000BL @@ -12679,6 +12846,8 @@ MCGEN_CALLOUT(RegHandle, #define MSG_RuntimePublisher_IncreaseMemoryPressureEventMessage 0xB00000C8L #define MSG_RuntimePublisher_DecreaseMemoryPressureEventMessage 0xB00000C9L #define MSG_RuntimePublisher_GCMarkWithTypeEventMessage 0xB00000CAL +#define MSG_RuntimePublisher_ExceptionExceptionHandlingEventMessage 0xB00000FAL +#define MSG_RuntimePublisher_ExceptionExceptionHandlingNoneEventMessage 0xB00000FBL #define MSG_RuntimePublisher_GCStart_V1EventMessage 0xB0010001L #define MSG_RuntimePublisher_GCEnd_V1EventMessage 0xB0010002L #define MSG_RuntimePublisher_GCRestartEEEnd_V1EventMessage 0xB0010003L diff --git a/src/pal/prebuilt/inc/clretwallmain.h b/src/pal/prebuilt/inc/clretwallmain.h index 57fca4aa80..a17e84cd15 100644 --- a/src/pal/prebuilt/inc/clretwallmain.h +++ b/src/pal/prebuilt/inc/clretwallmain.h @@ -9,7 +9,7 @@ #define MAX_BYTES_PER_ETW_PROVIDER 64 EXTERN_C __declspec(selectany) const BYTE etwStackSupportedEvents[NO_OF_ETW_PROVIDERS][MAX_BYTES_PER_ETW_PROVIDER] = { - {0, 4, 16, 192, 9, 255, 3, 241, 195, 0, 251, 3, 0, 0, 0, 0, 128, 31, 226, 63, 0, 0, 64, 65, 0, 43, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 16, 192, 9, 255, 3, 241, 195, 0, 251, 3, 0, 0, 0, 0, 128, 31, 226, 63, 0, 0, 64, 65, 0, 43, 0, 0, 0, 0, 15, 252, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, diff --git a/src/pal/prebuilt/inc/etmdummy.h b/src/pal/prebuilt/inc/etmdummy.h index 6a2456a12c..983bba67b3 100644 --- a/src/pal/prebuilt/inc/etmdummy.h +++ b/src/pal/prebuilt/inc/etmdummy.h @@ -88,6 +88,13 @@ #define FireEtwThreadRunning(ID, ClrInstanceID) 0 #define FireEtwExceptionThrown() 0 #define FireEtwExceptionThrown_V1(ExceptionType, ExceptionMessage, ExceptionEIP, ExceptionHRESULT, ExceptionFlags, ClrInstanceID) 0 +#define FireEtwExceptionCatchStart(EntryEIP, MethodID, MethodName, ClrInstanceID) 0 +#define FireEtwExceptionCatchStop() 0 +#define FireEtwExceptionFinallyStart(EntryEIP, MethodID, MethodName, ClrInstanceID) 0 +#define FireEtwExceptionFinallyStop() 0 +#define FireEtwExceptionFilterStart(EntryEIP, MethodID, MethodName, ClrInstanceID) 0 +#define FireEtwExceptionFilterStop() 0 +#define FireEtwExceptionThrownStop() 0 #define FireEtwContention() 0 #define FireEtwContentionStart_V1(ContentionFlags, ClrInstanceID) 0 #define FireEtwContentionStop(ContentionFlags, ClrInstanceID) 0 diff --git a/src/vm/ClrEtwAll.man b/src/vm/ClrEtwAll.man index ea3c4da935..71b7346878 100644 --- a/src/vm/ClrEtwAll.man +++ b/src/vm/ClrEtwAll.man @@ -71,6 +71,8 @@ message="$(string.RuntimePublisher.ThreadTransferKeywordMessage)" symbol="CLR_THREADTRANSFER_KEYWORD"/> <keyword name="DebuggerKeyword" mask="0x100000000" message="$(string.RuntimePublisher.DebuggerKeywordMessage)" symbol="CLR_DEBUGGER_KEYWORD" /> + <keyword name="MonitoringKeyword" mask="0x200000000" + message="$(string.RuntimePublisher.MonitoringKeywordMessage)" symbol="CLR_MONITORING_KEYWORD" /> </keywords> <!--Tasks--> <tasks> @@ -163,7 +165,28 @@ </opcodes> </task> - <task name="Contention" symbol="CLR_CONTENTION_TASK" + <task name="ExceptionCatch" symbol="CLR_EXCEPTION_CATCH_TASK" + value="27" eventGUID="{5BBF9499-1715-4658-88DC-AFD7690A8711}" + message="$(string.RuntimePublisher.ExceptionCatchTaskMessage)"> + <opcodes> + </opcodes> + </task> + + <task name="ExceptionFinally" symbol="CLR_EXCEPTION_FINALLY_TASK" + value="28" eventGUID="{9565BC31-300F-4EA2-A532-30BCE9A14199}" + message="$(string.RuntimePublisher.ExceptionFinallyTaskMessage)"> + <opcodes> + </opcodes> + </task> + + <task name="ExceptionFilter" symbol="CLR_EXCEPTION_FILTER_TASK" + value="29" eventGUID="{72E72606-BB71-4290-A242-D5F36CE5312E}" + message="$(string.RuntimePublisher.ExceptionFilterTaskMessage)"> + <opcodes> + </opcodes> + </task> + + <task name="Contention" symbol="CLR_CONTENTION_TASK" value="8" eventGUID="{561410f5-a138-4ab3-945e-516483cddfbc}" message="$(string.RuntimePublisher.ContentionTaskMessage)"> <opcodes> @@ -339,6 +362,7 @@ <opcodes> </opcodes> </task> + <!--Next available ID is 30--> </tasks> <!--Maps--> <maps> @@ -1326,6 +1350,21 @@ </UserData> </template> + <template tid="ExceptionHandling"> + <data name="EntryEIP" inType="win:UInt64" outType="win:HexInt64" /> + <data name="MethodID" inType="win:UInt64" outType="win:HexInt64" /> + <data name="MethodName" inType="win:UnicodeString" /> + <data name="ClrInstanceID" inType="win:UInt16" /> + <UserData> + <ExceptionHandling xmlns="myNs"> + <EntryEIP> %1 </EntryEIP> + <MethodID> %2 </MethodID> + <MethodName> %3 </MethodName> + <ClrInstanceID> %4 </ClrInstanceID> + </ExceptionHandling> + </UserData> + </template> + <template tid="Contention"> <data name="ContentionFlags" inType="win:UInt8" map="ContentionFlagsMap" /> <data name="ClrInstanceID" inType="win:UInt16" /> @@ -2660,10 +2699,45 @@ symbol="ExceptionThrown" message="$(string.RuntimePublisher.ExceptionExceptionThrownEventMessage)"/> <event value="80" version="1" level="win:Error" template="Exception" - keywords ="ExceptionKeyword" opcode="win:Start" + keywords ="ExceptionKeyword MonitoringKeyword" opcode="win:Start" task="Exception" symbol="ExceptionThrown_V1" message="$(string.RuntimePublisher.ExceptionExceptionThrown_V1EventMessage)"/> + <event value="250" version="0" level="win:Informational" template="ExceptionHandling" + keywords ="ExceptionKeyword" opcode="win:Start" + task="ExceptionCatch" + symbol="ExceptionCatchStart" message="$(string.RuntimePublisher.ExceptionExceptionHandlingEventMessage)"/> + + <event value="251" version="0" level="win:Informational" + keywords ="ExceptionKeyword" opcode="win:Stop" + task="ExceptionCatch" + symbol="ExceptionCatchStop" message="$(string.RuntimePublisher.ExceptionExceptionHandlingNoneEventMessage)"/> + + <event value="252" version="0" level="win:Informational" template="ExceptionHandling" + keywords ="ExceptionKeyword" opcode="win:Start" + task="ExceptionFinally" + symbol="ExceptionFinallyStart" message="$(string.RuntimePublisher.ExceptionExceptionHandlingEventMessage)"/> + + <event value="253" version="0" level="win:Informational" + keywords ="ExceptionKeyword" opcode="win:Stop" + task="ExceptionFinally" + symbol="ExceptionFinallyStop" message="$(string.RuntimePublisher.ExceptionExceptionHandlingNoneEventMessage)"/> + + <event value="254" version="0" level="win:Informational" template="ExceptionHandling" + keywords ="ExceptionKeyword" opcode="win:Start" + task="ExceptionFilter" + symbol="ExceptionFilterStart" message="$(string.RuntimePublisher.ExceptionExceptionHandlingEventMessage)"/> + + <event value="255" version="0" level="win:Informational" + keywords ="ExceptionKeyword" opcode="win:Stop" + task="ExceptionFilter" + symbol="ExceptionFilterStop" message="$(string.RuntimePublisher.ExceptionExceptionHandlingNoneEventMessage)"/> + + <event value="256" version="0" level="win:Informational" + keywords ="ExceptionKeyword" opcode="win:Stop" + task="Exception" + symbol="ExceptionThrownStop" message="$(string.RuntimePublisher.ExceptionExceptionHandlingNoneEventMessage)"/> + <!-- CLR Contention events --> <event value="81" version="0" level="win:Informational" opcode="win:Start" @@ -6118,6 +6192,8 @@ <string id="RuntimePublisher.ThreadRunningEventMessage" value="ID=%1;%nClrInstanceID=%s" /> <string id="RuntimePublisher.ExceptionExceptionThrownEventMessage" value="NONE" /> <string id="RuntimePublisher.ExceptionExceptionThrown_V1EventMessage" value="ExceptionType=%1;%nExceptionMessage=%2;%nExceptionEIP=%3;%nExceptionHRESULT=%4;%nExceptionFlags=%5;%nClrInstanceID=%6" /> + <string id="RuntimePublisher.ExceptionExceptionHandlingEventMessage" value="EntryEIP=%1;%nMethodID=%2;%nMethodName=%3;%nClrInstanceID=%4" /> + <string id="RuntimePublisher.ExceptionExceptionHandlingNoneEventMessage" value="NONE" /> <string id="RuntimePublisher.ContentionStartEventMessage" value="NONE" /> <string id="RuntimePublisher.ContentionStart_V1EventMessage" value="ContentionFlags=%1;%nClrInstanceID=%2"/> <string id="RuntimePublisher.ContentionStopEventMessage" value="ContentionFlags=%1;%nClrInstanceID=%2"/> @@ -6321,6 +6397,9 @@ <string id="RuntimePublisher.ThreadPoolWorkerThreadRetirementTaskMessage" value="ThreadPoolWorkerThreadRetirement" /> <string id="RuntimePublisher.ThreadPoolWorkerThreadAdjustmentTaskMessage" value="ThreadPoolWorkerThreadAdjustment" /> <string id="RuntimePublisher.ExceptionTaskMessage" value="Exception" /> + <string id="RuntimePublisher.ExceptionCatchTaskMessage" value="ExceptionCatch" /> + <string id="RuntimePublisher.ExceptionFinallyTaskMessage" value="ExceptionFinally" /> + <string id="RuntimePublisher.ExceptionFilterTaskMessage" value="ExceptionFilter" /> <string id="RuntimePublisher.ContentionTaskMessage" value="Contention" /> <string id="RuntimePublisher.MethodTaskMessage" value="Method" /> <string id="RuntimePublisher.LoaderTaskMessage" value="Loader" /> @@ -6609,6 +6688,7 @@ <string id="RuntimePublisher.GCHandleKeywordMessage" value="GCHandle" /> <string id="RuntimePublisher.ThreadTransferKeywordMessage" value="ThreadTransfer" /> <string id="RuntimePublisher.DebuggerKeywordMessage" value="Debugger" /> + <string id="RuntimePublisher.MonitoringKeywordMessage" value="Monitoring" /> <string id="RundownPublisher.LoaderKeywordMessage" value="Loader" /> <string id="RundownPublisher.JitKeywordMessage" value="Jit" /> <string id="RundownPublisher.JittedMethodILToNativeMapRundownKeywordMessage" value="JittedMethodILToNativeMapRundown" /> diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp index a48cafbac9..4be9dcc4b1 100644 --- a/src/vm/appdomain.hpp +++ b/src/vm/appdomain.hpp @@ -2032,6 +2032,7 @@ public: #ifndef FEATURE_CORECLR inline BOOL AppDomainManagerSetFromConfig(); Assembly *GetAppDomainManagerEntryAssembly(); + void ComputeTargetFrameworkName(); #endif // FEATURE_CORECLR #if defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP) @@ -4520,7 +4521,7 @@ public: #endif // DACCESS_COMPILE #ifndef FEATURE_CORECLR - static void ExecuteMainMethod(HMODULE hMod, __in_opt LPWSTR path = NULL); + static void ExecuteMainMethod(HMODULE hMod, __in_opt LPWSTR path = NULL); #endif static void ActivateApplication(int *pReturnValue); diff --git a/src/vm/assembly.cpp b/src/vm/assembly.cpp index 3c41c45ddb..ba65f13bfa 100644 --- a/src/vm/assembly.cpp +++ b/src/vm/assembly.cpp @@ -73,6 +73,10 @@ #include "eventmsg.h" #endif +#ifdef FEATURE_TRACELOGGING +#include "clrtracelogging.h" +#endif // FEATURE_TRACELOGGING + // Define these macro's to do strict validation for jit lock and class init entry leaks. // This defines determine if the asserts that verify for these leaks are defined or not. @@ -179,6 +183,43 @@ Assembly::Assembly(BaseDomain *pDomain, PEAssembly* pFile, DebuggerAssemblyContr // which is used in AssemblyBuilder.InitManifestModule #define REFEMIT_MANIFEST_MODULE_NAME W("RefEmit_InMemoryManifestModule") + +#ifdef FEATURE_TRACELOGGING +//---------------------------------------------------------------------------------------------- +// Reads and logs the TargetFramework attribute for an assembly. For example: [assembly: TargetFramework(".NETFramework,Version=v4.0")] +//---------------------------------------------------------------------------------------------- +void Assembly::TelemetryLogTargetFrameworkAttribute() +{ + const BYTE *pbAttr; // Custom attribute data as a BYTE*. + ULONG cbAttr; // Size of custom attribute data. + HRESULT hr = GetManifestImport()->GetCustomAttributeByName(GetManifestToken(), TARGET_FRAMEWORK_TYPE, (const void**)&pbAttr, &cbAttr); + bool dataLogged = false; + if (hr == S_OK) + { + CustomAttributeParser cap(pbAttr, cbAttr); + LPCUTF8 lpTargetFramework; + ULONG cbTargetFramework; + if (SUCCEEDED(cap.ValidateProlog())) + { + if (SUCCEEDED(cap.GetString(&lpTargetFramework, &cbTargetFramework))) + { + if ((lpTargetFramework != NULL) && (cbTargetFramework != 0)) + { + SString s(SString::Utf8, lpTargetFramework, cbTargetFramework); + CLRTraceLog::Logger::LogTargetFrameworkAttribute(s.GetUnicode(), GetSimpleName()); + dataLogged = true; + } + } + } + } + if (!dataLogged) + { + CLRTraceLog::Logger::LogTargetFrameworkAttribute(L"", GetSimpleName()); + } +} + +#endif // FEATURE_TRACELOGGING + //---------------------------------------------------------------------------------------------- // Does most Assembly initialization tasks. It can assume the ctor has already run // and the assembly is safely destructable. Whether this function throws or succeeds, @@ -252,6 +293,13 @@ void Assembly::Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocat ReportAssemblyUse(); #endif +#ifdef FEATURE_TRACELOGGING + + TelemetryLogTargetFrameworkAttribute(); + +#endif // FEATURE_TRACELOGGING + + // Check for the special System.Numerics.Vectors assembly. // If we encounter a non-trusted assembly by this name, we will simply not recognize any of its // methods as intrinsics. @@ -2610,7 +2658,7 @@ INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs) INJECT_FAULT(COMPlusThrowOM()); } CONTRACTL_END; - + // reset the error code for std C errno=0; @@ -2662,7 +2710,6 @@ INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs) AppDomain * pDomain = pThread->GetDomain(); pDomain->SetRootAssembly(pMeth->GetAssembly()); #endif - hr = RunMain(pMeth, 1, &iRetVal, stringArgs); } } diff --git a/src/vm/assembly.hpp b/src/vm/assembly.hpp index 812efb3c2b..1fdc655c02 100644 --- a/src/vm/assembly.hpp +++ b/src/vm/assembly.hpp @@ -126,6 +126,10 @@ public: Assembly(BaseDomain *pDomain, PEAssembly *pFile, DebuggerAssemblyControlFlags debuggerFlags, BOOL fIsCollectible); void Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocator); +#if defined(FEATURE_TRACELOGGING) + void TelemetryLogTargetFrameworkAttribute(); +#endif // FEATURE_TRACELOGGING + void StartUnload(); void Terminate( BOOL signalProfiler = TRUE ); diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index f5bf61c270..b379d94365 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -3756,7 +3756,7 @@ void Module::FreeClassTables() if (!th.IsTypeDesc()) { MethodTable *pMT = th.AsMethodTable(); - if (pMT->HasCCWTemplate()) + if (pMT->HasCCWTemplate() && (!pMT->IsZapped() || pMT->GetZapModule() == this)) { // code:MethodTable::GetComCallWrapperTemplate() may go through canonical methodtable indirection cell. // The module load could be aborted before completing code:FILE_LOAD_EAGER_FIXUPS phase that's responsible @@ -3786,7 +3786,7 @@ void Module::FreeClassTables() if (!th.IsTypeDesc()) { MethodTable * pMT = th.AsMethodTable(); - if (pMT->IsCanonicalMethodTable()) + if (pMT->IsCanonicalMethodTable() && (!pMT->IsZapped() || pMT->GetZapModule() == this)) pMT->GetClass()->Destruct(pMT); } } @@ -6502,6 +6502,12 @@ mdTypeRef Module::LookupTypeRefByMethodTable(MethodTable *pMT) #ifdef FEATURE_READYTORUN_COMPILER if (IsReadyToRunCompilation()) { + if (pMT->GetClass()->IsEquivalentType()) + { + GetSvcLogger()->Log(W("ReadyToRun: Type reference to equivalent type cannot be encoded\n")); + ThrowHR(E_NOTIMPL); + } + // FUTURE: Encoding of new cross-module references for ReadyToRun // This warning is hit for recursive cross-module inlining. It is commented out to avoid noise. // GetSvcLogger()->Log(W("ReadyToRun: Type reference outside of current version bubble cannot be encoded\n")); diff --git a/src/vm/clrtracelogging.cpp b/src/vm/clrtracelogging.cpp new file mode 100644 index 0000000000..089e1c43f7 --- /dev/null +++ b/src/vm/clrtracelogging.cpp @@ -0,0 +1,41 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +//***************************************************************************** +// clrttracelogging.cpp +// Telemetry Logging for clr.dll +// +//***************************************************************************** + +#include "common.h" +#include "clrtracelogging.h" +#include "TraceLoggingProvider.h" +#include "MicrosoftTelemetry.h" + +TRACELOGGING_DEFINE_PROVIDER(g_hClrProvider, CLR_PROVIDER_NAME, CLR_PROVIDER_ID, TraceLoggingOptionMicrosoftTelemetry()); + +// Used for initialization and deconstruction. +static CLRTraceLog::Provider g_clrTraceProvider(g_hClrProvider); + +//--- CLRTraceLogProvider + +// static +void CLRTraceLog::Logger::LogTargetFrameworkAttribute(LPCWSTR targetFrameworkAttribute, const char * assemblyName) +{ + STANDARD_VM_CONTRACT; + + EX_TRY + { + TraceLoggingWrite(g_hClrProvider,"CLR.AssemblyInfo", + TraceLoggingWideString(targetFrameworkAttribute, "TARGET_FRAMEWORK_ATTRIBUTE"), + TraceLoggingString(assemblyName, "ASSEMBLY_NAME"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)); + } + EX_CATCH{} + EX_END_CATCH(SwallowAllExceptions) + +} +//--- CLRTraceLog + diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp index dc6937f269..922dbcb7b8 100644 --- a/src/vm/codeman.cpp +++ b/src/vm/codeman.cpp @@ -1521,7 +1521,7 @@ BOOL EEJitManager::LoadJIT() // // See the document "RyuJIT Compatibility Fallback Specification.docx" for details. - bool fUseRyuJit = (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_UseRyuJit) == 1); // uncached access, since this code is run no more than one time + bool fUseRyuJit = UseRyuJit(); if ((!IsCompilationProcess() || !fUseRyuJit) && // Use RyuJIT for all NGEN, unless we're falling back to JIT64 for everything. (newJitCompiler != nullptr)) // the main JIT must successfully load before we try loading the fallback JIT diff --git a/src/vm/compile.cpp b/src/vm/compile.cpp index 7d7892b3c7..d77a285a04 100644 --- a/src/vm/compile.cpp +++ b/src/vm/compile.cpp @@ -1033,7 +1033,7 @@ HRESULT CEECompileInfo::SetCompilationTarget(CORINFO_ASSEMBLY_HANDLE assembl mscorlib.InitializeSpec(SystemDomain::SystemFile()); GetAppDomain()->BindAssemblySpec(&mscorlib,TRUE,FALSE); - if (!SystemDomain::SystemFile()->HasNativeImage()) + if (!IsReadyToRunCompilation() && !SystemDomain::SystemFile()->HasNativeImage()) { if (!CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenAllowMscorlibSoftbind)) { @@ -2527,6 +2527,11 @@ BOOL CEECompileInfo::NeedsTypeLayoutCheck(CORINFO_CLASS_HANDLE classHnd) if (!pMT->IsValueType()) return FALSE; + // Skip this check for equivalent types. Equivalent types are used for interop that ensures + // matching layout. + if (pMT->GetClass()->IsEquivalentType()) + return FALSE; + return !pMT->IsLayoutFixedInCurrentVersionBubble(); } @@ -8191,4 +8196,16 @@ HRESULT CompilationDomain::SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths) } #endif // CROSSGEN_COMPILE +#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR) +bool UseRyuJit() +{ +#ifdef CROSSGEN_COMPILE + return true; +#else + static ConfigDWORD useRyuJitValue; + return useRyuJitValue.val(CLRConfig::INTERNAL_UseRyuJit) == 1 || IsNgenOffline(); +#endif +} +#endif + #endif // FEATURE_PREJIT diff --git a/src/vm/coreassemblyspec.cpp b/src/vm/coreassemblyspec.cpp index be3d2841ed..238e359561 100644 --- a/src/vm/coreassemblyspec.cpp +++ b/src/vm/coreassemblyspec.cpp @@ -618,7 +618,7 @@ VOID AssemblySpec::Bind(AppDomain *pAppDomain, { SString sSimpleName(SString::Utf8, m_pAssemblyName); - fNativeImage = pAppDomain->ToCompilationDomain()->IsInHardBindList(sSimpleName); + fNativeImage = !IsReadyToRunCompilation() && pAppDomain->ToCompilationDomain()->IsInHardBindList(sSimpleName); SString sFileName(sSimpleName, fNativeImage ? W(".ni.dll") : W(".dll")); diff --git a/src/vm/crossgen/wks_crossgen.nativeproj b/src/vm/crossgen/wks_crossgen.nativeproj index a688b49304..205f2e2c95 100644 --- a/src/vm/crossgen/wks_crossgen.nativeproj +++ b/src/vm/crossgen/wks_crossgen.nativeproj @@ -157,7 +157,9 @@ <CppCompile Include="$(VmSourcesDir)\CrossgenRoParseTypeName.cpp" Condition="'$(FeatureCominterop)' == 'true'"/> <CppCompile Include="$(VmSourcesDir)\CrossgenRoResolveNamespace.cpp" Condition="'$(FeatureCominterop)' == 'true'"/> </ItemGroup> - + <ItemGroup> + <CppCompile Condition="'$(FeatureTraceLogging)' == 'true'" Include="$(VmSourcesDir)\clrtracelogging.cpp" /> + </ItemGroup> <Import Project="$(_NTDRIVE)$(_NTROOT)\ndp\clr\src\vm\vm.targets" /> </Project> diff --git a/src/vm/domainfile.cpp b/src/vm/domainfile.cpp index 5423ebe63f..a558ee3900 100644 --- a/src/vm/domainfile.cpp +++ b/src/vm/domainfile.cpp @@ -3365,6 +3365,13 @@ void DomainAssembly::GetCurrentVersionInfo(CORCOMPILE_VERSION_INFO *pNativeVersi pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_INSTRUMENTATION_NONE; } +#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR) + if (UseRyuJit()) + { + pNativeVersionInfo->wCodegenFlags |= CORCOMPILE_CODEGEN_USE_RYUJIT; + } +#endif + GetTimeStampsForNativeImage(pNativeVersionInfo); // Store signature of source assembly. diff --git a/src/vm/dwreport.cpp b/src/vm/dwreport.cpp index 210e08240c..ccf41ea953 100644 --- a/src/vm/dwreport.cpp +++ b/src/vm/dwreport.cpp @@ -2776,52 +2776,71 @@ DWORD WINAPI DoFaultReportWorkerCallback(LPVOID pParam) } EX_END_CATCH(SwallowAllExceptions); } - - SetupThread(); - - GCX_COOP(); - if (pData->pThread != NULL && pExceptionInfo != NULL && - pExceptionInfo->ContextRecord == NULL && - pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW && - pExceptionInfo->ExceptionRecord->ExceptionAddress == 0) + // The purpose of the loop below is to avoid deadlocks during the abnormal process termination. + // We will try to acquire the lock for 100 times to see whether we can successfully grap it. If we + // can, then we can setup the thread and report the fault without worrying about the deadlock. + // Otherwise we won't report the fault. It's still possible that we can enter the critical section + // and report the fault without having deadlocks after this spin, but compared to the risky of + // having deadlock, we still prefer not to report the fault if we can't get the lock after spin. + BOOL isThreadSetup = false; + for (int i = 0; i < 100; i++) + { + if (ThreadStore::CanAcquireLock()) + { + SetupThread(); + isThreadSetup = true; + break; + } + __SwitchToThread(30, CALLER_LIMITS_SPINNING); + } + + if (isThreadSetup) { - // In the case of a soft SO on a managed thread, we set the ExceptionAddress to one of the following - // - // 1. The first method on the stack that is in a non-system module. - // 2. Failing that, the first method on the stack that is in a system module + GCX_COOP(); + + if (pData->pThread != NULL && pExceptionInfo != NULL && + pExceptionInfo->ContextRecord == NULL && + pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW && + pExceptionInfo->ExceptionRecord->ExceptionAddress == 0) + { + // In the case of a soft SO on a managed thread, we set the ExceptionAddress to one of the following + // + // 1. The first method on the stack that is in a non-system module. + // 2. Failing that, the first method on the stack that is in a system module - CONTEXT ContextRecord; - memset(&ContextRecord, 0, sizeof(CONTEXT)); + CONTEXT ContextRecord; + memset(&ContextRecord, 0, sizeof(CONTEXT)); - ExceptionInfo.ContextRecord = &ContextRecord; // To display the "Send" button, dw20 wants a non-NULL pointer - ExceptionRecord = *(pExceptionInfo->ExceptionRecord); - ExceptionInfo.ExceptionRecord = &ExceptionRecord; - pExceptionInfo = &ExceptionInfo; + ExceptionInfo.ContextRecord = &ContextRecord; // To display the "Send" button, dw20 wants a non-NULL pointer + ExceptionRecord = *(pExceptionInfo->ExceptionRecord); + ExceptionInfo.ExceptionRecord = &ExceptionRecord; + pExceptionInfo = &ExceptionInfo; - WatsonSOExceptionAddress WatsonExceptionAddresses; + WatsonSOExceptionAddress WatsonExceptionAddresses; - pData->pThread->StackWalkFrames( - WatsonSOStackCrawlCallback, - &WatsonExceptionAddresses, - FUNCTIONSONLY|ALLOW_ASYNC_STACK_WALK); + pData->pThread->StackWalkFrames( + WatsonSOStackCrawlCallback, + &WatsonExceptionAddresses, + FUNCTIONSONLY|ALLOW_ASYNC_STACK_WALK); - if (WatsonExceptionAddresses.m_UserMethod != NULL) - { - pExceptionInfo->ExceptionRecord->ExceptionAddress = WatsonExceptionAddresses.m_UserMethod; - } - else if (WatsonExceptionAddresses.m_SystemMethod != NULL) - { - pExceptionInfo->ExceptionRecord->ExceptionAddress = WatsonExceptionAddresses.m_SystemMethod; - } + if (WatsonExceptionAddresses.m_UserMethod != NULL) + { + pExceptionInfo->ExceptionRecord->ExceptionAddress = WatsonExceptionAddresses.m_UserMethod; + } + else if (WatsonExceptionAddresses.m_SystemMethod != NULL) + { + pExceptionInfo->ExceptionRecord->ExceptionAddress = WatsonExceptionAddresses.m_SystemMethod; + } - } + } - pData->result = DoFaultReportWorker( - pExceptionInfo, - pData->tore, - pData->pThread, - pData->dwThreadID); + pData->result = DoFaultReportWorker( + pExceptionInfo, + pData->tore, + pData->pThread, + pData->dwThreadID); + } return 0; @@ -3162,6 +3181,11 @@ FaultReportResult DoFaultReport( // Was Watson attempted, successful? GCX_PREEMP(); if (!g_pDebugInterface || + // When GC is in progress and current thread is either a GC thread or a managed + // thread under Coop mode, this will let the new generated DoFaultReportCallBack + // thread trigger a deadlock. So in this case, we should directly abort the fault + // report to avoid the deadlock. + ((IsGCThread() || pThread->PreemptiveGCDisabled()) && GCHeap::IsGCInProgress()) || FAILED(g_pDebugInterface->RequestFavor(DoFaultReportFavorWorker, pData))) { // If we can't initialize the debugger helper thread or we are running on the debugger helper diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp index 84b267e806..5df7b6305a 100644 --- a/src/vm/eetwain.cpp +++ b/src/vm/eetwain.cpp @@ -4090,7 +4090,8 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext, EECodeInfo *pCodeInfo, unsigned flags, GCEnumCallback pCallBack, - LPVOID hCallBack) + LPVOID hCallBack, + DWORD relOffsetOverride) { CONTRACTL { NOTHROW; @@ -4731,7 +4732,8 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pRD, EECodeInfo *pCodeInfo, unsigned flags, GCEnumCallback pCallBack, - LPVOID hCallBack) + LPVOID hCallBack, + DWORD relOffsetOverride) { CONTRACTL { NOTHROW; @@ -4796,13 +4798,13 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pRD, #ifdef USE_GC_INFO_DECODER /* If we are not in the active method, we are currently pointing - * to the return address; at the return address stack variables - * can become dead if the call is the last instruction of a try block - * and the return address is the jump around the catch block. Therefore - * we simply assume an offset inside of call instruction. - * NOTE: The GcInfoDecoder depends on this; if you change it, you must - * revisit the GcInfoEncoder/Decoder - */ + * to the return address; at the return address stack variables + * can become dead if the call is the last instruction of a try block + * and the return address is the jump around the catch block. Therefore + * we simply assume an offset inside of call instruction. + * NOTE: The GcInfoDecoder depends on this; if you change it, you must + * revisit the GcInfoEncoder/Decoder + */ if (!(flags & ExecutionAborted)) { @@ -4827,6 +4829,34 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pRD, methodName, curOffs)); } } + + // Check if we have been given an override value for relOffset + if (relOffsetOverride != NO_OVERRIDE_OFFSET) + { + // We've been given an override offset for GC Info +#ifdef _DEBUG + GcInfoDecoder _gcInfoDecoder( + gcInfoAddr, + DECODE_CODE_LENGTH, + 0 + ); + + // We only use override offset for wantsReportOnlyLeaf + _ASSERTE(_gcInfoDecoder.WantsReportOnlyLeaf()); +#endif // _DEBUG + + curOffs = relOffsetOverride; + +#ifdef _TARGET_ARM_ + // On ARM, the low-order bit of an instruction pointer indicates Thumb vs. ARM mode. + // Mask this off; all instructions are two-byte aligned. + curOffs &= (~THUMB_CODE); +#endif // _TARGET_ARM_ + + LOG((LF_GCINFO, LL_INFO1000, "Adjusted GC reporting offset to provided override offset. Now reporting GC refs for %s at offset %04x.\n", + methodName, curOffs)); + } + #endif // USE_GC_INFO_DECODER #if defined(WIN64EXCEPTIONS) // funclets @@ -4948,7 +4978,8 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext, EECodeInfo *pCodeInfo, unsigned flags, GCEnumCallback pCallBack, - LPVOID hCallBack) + LPVOID hCallBack, + DWORD relOffsetOverride) { PORTABILITY_ASSERT("EECodeManager::EnumGcRefs is not implemented on this platform."); return false; diff --git a/src/vm/eventtrace.cpp b/src/vm/eventtrace.cpp index c55c378005..dab4436923 100644 --- a/src/vm/eventtrace.cpp +++ b/src/vm/eventtrace.cpp @@ -4599,6 +4599,145 @@ VOID ETW::ExceptionLog::ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownExcept } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions); } + +VOID ETW::ExceptionLog::ExceptionThrownEnd() +{ + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + if (!ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ExceptionThrownStop)) + { + return; + } + + FireEtwExceptionThrownStop(); +} + +/****************************************************************************/ +/* This is called by the runtime when an exception is handled by the runtime */ +/****************************************************************************/ +VOID ETW::ExceptionLog::ExceptionCatchBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) +{ + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + if (!ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ExceptionCatchStart)) + { + return; + } + + EX_TRY + { + SString methodName; + pMethodDesc->GetFullMethodInfo(methodName); + + FireEtwExceptionCatchStart((uint64_t)pEntryEIP, + (uint64_t)pMethodDesc, + methodName.GetUnicode(), + GetClrInstanceId()); + + } EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); +} + +VOID ETW::ExceptionLog::ExceptionCatchEnd() +{ + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + if (!ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ExceptionCatchStop)) + { + return; + } + + FireEtwExceptionCatchStop(); +} + +VOID ETW::ExceptionLog::ExceptionFinallyBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) +{ + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + if (!ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ExceptionFinallyStart)) + { + return; + } + + EX_TRY + { + SString methodName; + pMethodDesc->GetFullMethodInfo(methodName); + + FireEtwExceptionFinallyStart((uint64_t)pEntryEIP, + (uint64_t)pMethodDesc, + methodName.GetUnicode(), + GetClrInstanceId()); + + } EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); +} + +VOID ETW::ExceptionLog::ExceptionFinallyEnd() +{ + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + if (!ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ExceptionFinallyStop)) + { + return; + } + + FireEtwExceptionFinallyStop(); +} + +VOID ETW::ExceptionLog::ExceptionFilterBegin(MethodDesc * pMethodDesc, PVOID pEntryEIP) +{ + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + if (!ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ExceptionFilterStart)) + { + return; + } + + EX_TRY + { + SString methodName; + pMethodDesc->GetFullMethodInfo(methodName); + + FireEtwExceptionFilterStart((uint64_t)pEntryEIP, + (uint64_t)pMethodDesc, + methodName.GetUnicode(), + GetClrInstanceId()); + + } EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); +} + +VOID ETW::ExceptionLog::ExceptionFilterEnd() +{ + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + if (!ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ExceptionFilterStop)) + { + return; + } + + FireEtwExceptionFilterStop(); +} + /****************************************************************************/ /* This is called by the runtime when a domain is loaded */ /****************************************************************************/ diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp index 02f60915c4..37f1369c5d 100644 --- a/src/vm/exceptionhandling.cpp +++ b/src/vm/exceptionhandling.cpp @@ -2053,6 +2053,13 @@ bool ExceptionTracker::HandleNestedExceptionEscape(StackFrame sf, bool fIsFirstP if (!fIsFirstPass) { + + // During unwind, at each frame we collapse exception trackers only once i.e. there cannot be multiple + // exception trackers that are collapsed at each frame. Store the information of collapsed exception + // tracker in current tracker to be able to find the parent frame when nested exception escapes. + m_csfEHClauseOfCollapsedTracker = m_pPrevNestedInfo->m_EHClauseInfo.GetCallerStackFrameForEHClause(); + m_EnclosingClauseInfoOfCollapsedTracker = m_pPrevNestedInfo->m_EnclosingClauseInfoForGCReporting; + EH_LOG((LL_INFO100, " - removing previous tracker\n")); ExceptionTracker* pTrackerToFree = m_pPrevNestedInfo; @@ -3258,6 +3265,19 @@ DWORD_PTR ExceptionTracker::CallHandler( this->m_EHClauseInfo.SetManagedCodeEntered(TRUE); this->m_EHClauseInfo.SetCallerStackFrame(csfFunclet); + switch(funcletType) + { + case EHFuncletType::Filter: + ETW::ExceptionLog::ExceptionFilterBegin(pMD, (PVOID)uHandlerStartPC); + break; + case EHFuncletType::FaultFinally: + ETW::ExceptionLog::ExceptionFinallyBegin(pMD, (PVOID)uHandlerStartPC); + break; + case EHFuncletType::Catch: + ETW::ExceptionLog::ExceptionCatchBegin(pMD, (PVOID)uHandlerStartPC); + break; + } + #if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) // Invoke the funclet. We pass throwable only when invoking the catch block. // Since the actual caller of the funclet is the assembly helper, pass the reference @@ -3297,6 +3317,20 @@ DWORD_PTR ExceptionTracker::CallHandler( dwResumePC = pfnHandler(sf.SP, OBJECTREFToObject(throwable)); #endif // _TARGET_ARM_ + switch(funcletType) + { + case EHFuncletType::Filter: + ETW::ExceptionLog::ExceptionFilterEnd(); + break; + case EHFuncletType::FaultFinally: + ETW::ExceptionLog::ExceptionFinallyEnd(); + break; + case EHFuncletType::Catch: + ETW::ExceptionLog::ExceptionCatchEnd(); + ETW::ExceptionLog::ExceptionThrownEnd(); + break; + } + this->m_EHClauseInfo.SetManagedCodeEntered(FALSE); END_SO_TOLERANT_CODE; @@ -6213,7 +6247,11 @@ bool ExceptionTracker::HasFrameBeenUnwoundByAnyActiveException(CrawlFrame * pCF) // For case (2) above, sfLastUnwoundEstbalisherFrame would be the same as the managed frame's SP (or upper bound) // // For these scenarios, the frame is considered unwound. - if (GetRegdisplaySP(pCF->GetRegisterSet()) == sfUpperBound.SP) + + // For most cases which satisfy above condition GetRegdisplaySP(pCF->GetRegisterSet()) will be equal to sfUpperBound.SP. + // However, frames where Sp is modified after prolog ( eg. localloc) this might not be the case. For those scenarios, + // we need to check if sfUpperBound.SP is in between GetRegdisplaySP(pCF->GetRegisterSet()) & callerSp. + if (GetRegdisplaySP(pCF->GetRegisterSet()) <= sfUpperBound.SP && sfUpperBound < csfToCheck) { if (csfToCheck == sfCurrentEstablisherFrame) { @@ -6605,7 +6643,7 @@ StackFrame ExceptionTracker::FindParentStackFrameHelper(CrawlFrame* pCF, // Since the current frame is a non-filter funclet, determine if its caller is the same one // as was saved against the exception tracker before the funclet was invoked in ExceptionTracker::CallHandler. CallerStackFrame csfFunclet = pCurrentTracker->m_EHClauseInfo.GetCallerStackFrameForEHClause(); - if (csfCurrent == csfFunclet) + if (csfCurrent == csfFunclet) { // The EnclosingClauseCallerSP is initialized in ExceptionTracker::ProcessManagedCallFrame, just before // invoking the funclets. Basically, we are using the SP of the caller of the frame containing the funclet @@ -6636,6 +6674,17 @@ StackFrame ExceptionTracker::FindParentStackFrameHelper(CrawlFrame* pCF, break; } + // Check if this tracker was collapsed with another tracker and if caller of funclet clause for collapsed exception tracker matches. + else if (fForGCReporting && !(pCurrentTracker->m_csfEHClauseOfCollapsedTracker.IsNull()) && csfCurrent == pCurrentTracker->m_csfEHClauseOfCollapsedTracker) + { + EnclosingClauseInfo srcEnclosingClause = pCurrentTracker->m_EnclosingClauseInfoOfCollapsedTracker; + sfResult = (StackFrame)(CallerStackFrame(srcEnclosingClause.GetEnclosingClauseCallerSP())); + + _ASSERTE(!sfResult.IsNull()); + + break; + + } } lExit: ; diff --git a/src/vm/exceptionhandling.h b/src/vm/exceptionhandling.h index 72db3576a3..0f9e962ffe 100644 --- a/src/vm/exceptionhandling.h +++ b/src/vm/exceptionhandling.h @@ -108,6 +108,7 @@ public: m_sfLastUnwoundEstablisherFrame.Clear(); m_pInitialExplicitFrame = NULL; m_pLimitFrame = NULL; + m_csfEHClauseOfCollapsedTracker.Clear(); } ExceptionTracker(DWORD_PTR dwExceptionPc, @@ -166,6 +167,7 @@ public: m_sfCurrentEstablisherFrame.Clear(); m_sfLastUnwoundEstablisherFrame.Clear(); m_pInitialExplicitFrame = NULL; + m_csfEHClauseOfCollapsedTracker.Clear(); } ~ExceptionTracker() @@ -500,6 +502,11 @@ public: return m_uCatchToCallPC; } + EE_ILEXCEPTION_CLAUSE GetEHClauseForCatch() + { + return m_ClauseForCatch; + } + // Returns the topmost frame seen during the first pass. StackFrame GetTopmostStackFrameFromFirstPass() { @@ -757,6 +764,8 @@ private: ; StackFrame m_sfCurrentEstablisherFrame; StackFrame m_sfLastUnwoundEstablisherFrame; PTR_Frame m_pInitialExplicitFrame; + CallerStackFrame m_csfEHClauseOfCollapsedTracker; + EnclosingClauseInfo m_EnclosingClauseInfoOfCollapsedTracker; }; #if defined(WIN64EXCEPTIONS) diff --git a/src/vm/gcenv.cpp b/src/vm/gcenv.cpp index 68eee622f5..ea7d634ecf 100644 --- a/src/vm/gcenv.cpp +++ b/src/vm/gcenv.cpp @@ -146,6 +146,74 @@ inline bool SafeToReportGenericParamContext(CrawlFrame* pCF) return true; } +#if defined(WIN64EXCEPTIONS) + +struct FindFirstInterruptiblePointState +{ + unsigned offs; + unsigned endOffs; + unsigned returnOffs; +}; + +bool FindFirstInterruptiblePointStateCB( + UINT32 startOffset, + UINT32 stopOffset, + LPVOID hCallback) +{ + FindFirstInterruptiblePointState* pState = (FindFirstInterruptiblePointState*)hCallback; + + _ASSERTE(startOffset < stopOffset); + _ASSERTE(pState->offs < pState->endOffs); + + if (stopOffset <= pState->offs) + { + // The range ends before the requested offset. + return false; + } + + // The offset is in the range. + if (startOffset <= pState->offs && + pState->offs < stopOffset) + { + pState->returnOffs = pState->offs; + return true; + } + + // The range is completely after the desired offset. We use the range start offset, if + // it comes before the given endOffs. We assume that the callback is called with ranges + // in increasing order, so earlier ones are reported before later ones. That is, if we + // get to this case, it will be the closest interruptible range after the requested + // offset. + + _ASSERTE(pState->offs < startOffset); + if (startOffset < pState->endOffs) + { + pState->returnOffs = startOffset; + return true; + } + + return false; +} + +// Find the first interruptible point in the range [offs .. endOffs) (the beginning of the range is inclusive, +// the end is exclusive). Return -1 if no such point exists. +unsigned FindFirstInterruptiblePoint(CrawlFrame* pCF, unsigned offs, unsigned endOffs) +{ + PTR_BYTE gcInfoAddr = dac_cast<PTR_BYTE>(pCF->GetCodeInfo()->GetGCInfo()); + GcInfoDecoder gcInfoDecoder(gcInfoAddr, DECODE_FOR_RANGES_CALLBACK, 0); + + FindFirstInterruptiblePointState state; + state.offs = offs; + state.endOffs = endOffs; + state.returnOffs = -1; + + gcInfoDecoder.EnumerateInterruptibleRanges(&FindFirstInterruptiblePointStateCB, &state); + + return state.returnOffs; +} + +#endif // WIN64EXCEPTIONS + //----------------------------------------------------------------------------- StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData) { @@ -209,15 +277,47 @@ StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData) pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName)); #endif // _DEBUG -#if 0 - printf("Scanning Frame for method %s\n", pMD->m_pszDebugMethodName); -#endif // _DEBUG + DWORD relOffsetOverride = NO_OVERRIDE_OFFSET; +#if defined(WIN64EXCEPTIONS) + if (pCF->ShouldParentToFuncletUseUnwindTargetLocationForGCReporting()) + { + PTR_BYTE gcInfoAddr = dac_cast<PTR_BYTE>(pCF->GetCodeInfo()->GetGCInfo()); + GcInfoDecoder _gcInfoDecoder( + gcInfoAddr, + DECODE_CODE_LENGTH, + 0 + ); + + if(_gcInfoDecoder.WantsReportOnlyLeaf()) + { + // We're in a special case of unwinding from a funclet, and resuming execution in + // another catch funclet associated with same parent function. We need to report roots. + // Reporting at the original throw site gives incorrect liveness information. We choose to + // report the liveness information at the first interruptible instruction of the catch funclet + // that we are going to execute. We also only report stack slots, since no registers can be + // live at the first instruction of a handler, except the catch object, which the VM protects + // specially. If the catch funclet has not interruptible point, we fall back and just report + // what we used to: at the original throw instruction. This might lead to bad GC behavior + // if the liveness is not correct. + const EE_ILEXCEPTION_CLAUSE& ehClauseForCatch = pCF->GetEHClauseForCatch(); + relOffsetOverride = FindFirstInterruptiblePoint(pCF, ehClauseForCatch.HandlerStartPC, + ehClauseForCatch.HandlerEndPC); + _ASSERTE(relOffsetOverride != NO_OVERRIDE_OFFSET); + + STRESS_LOG3(LF_GCROOTS, LL_INFO1000, "Setting override offset = %u for method %pM ControlPC = %p\n", + relOffsetOverride, pMD, GetControlPC(pCF->GetRegisterSet())); + } + + } +#endif // WIN64EXCEPTIONS pCM->EnumGcRefs(pCF->GetRegisterSet(), pCF->GetCodeInfo(), flags, GcEnumObject, - pData); + pData, + relOffsetOverride); + } else { diff --git a/src/vm/i386/excepx86.cpp b/src/vm/i386/excepx86.cpp index ca7a18d8c3..6bf26a4790 100644 --- a/src/vm/i386/excepx86.cpp +++ b/src/vm/i386/excepx86.cpp @@ -1945,6 +1945,9 @@ LPVOID STDCALL COMPlusEndCatch(LPVOID ebp, DWORD ebx, DWORD edi, DWORD esi, LPVO STATIC_CONTRACT_MODE_COOPERATIVE; STATIC_CONTRACT_SO_INTOLERANT; + ETW::ExceptionLog::ExceptionCatchEnd(); + ETW::ExceptionLog::ExceptionThrownEnd(); + void* esp = COMPlusEndCatchWorker(GetThread()); // We are going to resume at a handler nesting level whose esp is dEsp. Pop off any SEH records below it. This @@ -3324,6 +3327,8 @@ void ResumeAtJitEH(CrawlFrame* pCf, // that the handle for the current ExInfo has been freed has been delivered pExInfo->m_EHClauseInfo.SetManagedCodeEntered(TRUE); + ETW::ExceptionLog::ExceptionCatchBegin(pCf->GetCodeInfo()->GetMethodDesc(), (PVOID)pCf->GetCodeInfo()->GetStartAddress()); + ResumeAtJitEHHelper(&context); UNREACHABLE_MSG("Should never return from ResumeAtJitEHHelper!"); @@ -3394,8 +3399,13 @@ int CallJitEHFilter(CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHCla // returning from UnwindFrames. FrameWithCookie<ExceptionFilterFrame> exceptionFilterFrame(pShadowSP); + + ETW::ExceptionLog::ExceptionFilterBegin(pCf->GetCodeInfo()->GetMethodDesc(), (PVOID)pCf->GetCodeInfo()->GetStartAddress()); + retVal = CallJitEHFilterWorker(pShadowSP, &context); + ETW::ExceptionLog::ExceptionFilterEnd(); + exceptionFilterFrame.Pop(); return retVal; @@ -3421,8 +3431,12 @@ void CallJitEHFinally(CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHC *pFinallyEnd = EHClausePtr->HandlerEndPC; } + ETW::ExceptionLog::ExceptionFinallyBegin(pCf->GetCodeInfo()->GetMethodDesc(), (PVOID)pCf->GetCodeInfo()->GetStartAddress()); + CallJitEHFinallyHelper(pShadowSP, &context); + ETW::ExceptionLog::ExceptionFinallyEnd(); + // // Update the registers using new context // diff --git a/src/vm/i386/stublinkerx86.cpp b/src/vm/i386/stublinkerx86.cpp index eb744615eb..e42f7d792f 100644 --- a/src/vm/i386/stublinkerx86.cpp +++ b/src/vm/i386/stublinkerx86.cpp @@ -5076,14 +5076,14 @@ VOID StubLinkerCPU::EmitArrayOpStub(const ArrayOpScript* pArrayOpScript) X86EmitOp(0x8b, kEAX, kValueReg, 0 AMD64_ARG(k64BitOp)); // mov EAX, [kValueReg] ; possibly trashes kValueReg // cmp EAX, [ESI/R10+m_ElementType] - X86_64BitOperands(); - X86EmitOp(0x3b, kEAX, kArrayMTReg, MethodTable::GetOffsetOfArrayElementTypeHandle()); + + X86EmitOp(0x3b, kEAX, kArrayMTReg, MethodTable::GetOffsetOfArrayElementTypeHandle() AMD64_ARG(k64BitOp)); X86EmitCondJump(CheckPassed, X86CondCode::kJZ); // Exact match is OK X86EmitRegLoad(kEAX, (UINT_PTR)g_pObjectClass); // mov EAX, g_pObjectMethodTable // cmp EAX, [ESI/R10+m_ElementType] - X86_64BitOperands(); - X86EmitOp(0x3b, kEAX, kArrayMTReg, MethodTable::GetOffsetOfArrayElementTypeHandle()); + + X86EmitOp(0x3b, kEAX, kArrayMTReg, MethodTable::GetOffsetOfArrayElementTypeHandle() AMD64_ARG(k64BitOp)); X86EmitCondJump(CheckPassed, X86CondCode::kJZ); // Assigning to array of object is OK // Try to call the fast helper first ( ObjIsInstanceOfNoGC ). diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 02846290f1..e1d2dbb2e5 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -11807,11 +11807,15 @@ BOOL MethodTableBuilder::NeedsAlignedBaseOffset() if (IsValueClass()) return FALSE; - // READYTORUN: TODO: This logic is not correct when NGen image depends on ReadyToRun image. In this case, - // GetModule()->IsReadyToRun() flag is going to be false at NGen time, but it is going to be true at runtime. - // Thus, the offsets between the two cases are going to be different. - if (!(IsReadyToRunCompilation() || GetModule()->IsReadyToRun())) - return FALSE; + // Always use the ReadyToRun field layout algorithm if the source IL image was ReadyToRun, independent on + // whether ReadyToRun is actually enabled for the module. It is required to allow mixing and matching + // ReadyToRun images with NGen. + if (!GetModule()->GetFile()->IsILImageReadyToRun()) + { + // Always use ReadyToRun field layout algorithm to produce ReadyToRun images + if (!IsReadyToRunCompilation()) + return FALSE; + } MethodTable * pParentMT = GetParentMethodTable(); diff --git a/src/vm/pefile.cpp b/src/vm/pefile.cpp index 815071c486..658d7f5ca6 100644 --- a/src/vm/pefile.cpp +++ b/src/vm/pefile.cpp @@ -1948,6 +1948,13 @@ static BOOL RuntimeVerifyNativeImageTimestamps(const CORCOMPILE_VERSION_INFO *in if (hMod == NULL) { + // Unless this is an NGen worker process, we don't want to load JIT compiler just to do a timestamp check. + // In an ideal case, all assemblies have native images, and JIT compiler never needs to be loaded at runtime. + // Loading JIT compiler just to check its timestamp would reduce the benefits of have native images. + // Since CLR and JIT are intended to be serviced together, the possibility of accidentally using native + // images created by an older JIT is very small, and is deemed an acceptable risk. + // Note that when multiple JIT compilers are used (e.g., clrjit.dll and compatjit.dll on x64 in .NET 4.6), + // they must all be in the same patch family. if (!IsCompilationProcess()) continue; @@ -2160,6 +2167,19 @@ BOOL RuntimeVerifyNativeImageVersion(const CORCOMPILE_VERSION_INFO *info, Loggab } #endif // CROSSGEN_COMPILE +#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR) + // + // Check the right JIT compiler + // + + bool nativeImageBuiltWithRyuJit = ((info->wCodegenFlags & CORCOMPILE_CODEGEN_USE_RYUJIT) != 0); + if (UseRyuJit() != nativeImageBuiltWithRyuJit) + { + RuntimeVerifyLog(LL_ERROR, pLogAsm, W("JIT compiler used to generate native image doesn't match current JIT compiler.")); + return FALSE; + } +#endif + // // The zap is up to date. // diff --git a/src/vm/pefile.h b/src/vm/pefile.h index 8f8a5f3588..4a64d9aec0 100644 --- a/src/vm/pefile.h +++ b/src/vm/pefile.h @@ -303,6 +303,7 @@ public: BOOL HasSecurityDirectory(); BOOL IsIbcOptimized(); + BOOL IsILImageReadyToRun(); WORD GetSubsystem(); mdToken GetEntryPointToken( #ifdef _DEBUG diff --git a/src/vm/pefile.inl b/src/vm/pefile.inl index d43d2b7ca2..07d42d5859 100644 --- a/src/vm/pefile.inl +++ b/src/vm/pefile.inl @@ -772,6 +772,28 @@ inline BOOL PEFile::IsIbcOptimized() return FALSE; } +inline BOOL PEFile::IsILImageReadyToRun() +{ + WRAPPER_NO_CONTRACT; + +#ifdef FEATURE_PREJIT + if (IsNativeLoaded()) + { + CONSISTENCY_CHECK(HasNativeImage()); + + return GetLoadedNative()->GetNativeILHasReadyToRunHeader(); + } + else +#endif // FEATURE_PREJIT + if (HasOpenedILimage()) + { + return GetLoadedIL()->HasReadyToRunHeader(); + } + else + { + return FALSE; + } +} inline WORD PEFile::GetSubsystem() { diff --git a/src/vm/peimage.cpp b/src/vm/peimage.cpp index 66f89db6e0..705f165d00 100644 --- a/src/vm/peimage.cpp +++ b/src/vm/peimage.cpp @@ -1547,7 +1547,14 @@ PTR_PEImageLayout PEImage::GetLayoutInternal(DWORD imageLayoutMask,DWORD flags) SetLayout(IMAGE_FLAT,pFlatLayout); pLoadLayout = new ConvertedImageLayout(pFlatLayout); } -#endif +#ifdef FEATURE_READYTORUN + else if (ReadyToRunInfo::IsReadyToRunEnabled() && IsFile()) + { + pLoadLayout = PEImageLayout::Load(this, FALSE, FALSE); + } +#endif // FEATURE_READYTORUN + +#endif // FEATURE_CORECLR if (pLoadLayout != NULL) { diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp index d39ce06ef4..3301dec092 100644 --- a/src/vm/stackwalk.cpp +++ b/src/vm/stackwalk.cpp @@ -1510,6 +1510,7 @@ void StackFrameIterator::ResetCrawlFrame() m_crawl.isFilterFunclet = false; m_crawl.isFilterFuncletCached = false; m_crawl.fShouldParentToFuncletSkipReportingGCReferences = false; + m_crawl.fShouldParentFrameUseUnwindTargetPCforGCReporting = false; #endif // WIN64EXCEPTIONS m_crawl.pThread = this->m_pThread; @@ -1669,6 +1670,10 @@ StackWalkAction StackFrameIterator::Filter(void) // CrawlFrame m_crawl.fShouldCrawlframeReportGCReferences = true; + // By default, assume that parent frame is going to report GC references from + // the actual location reported by the stack walk. + m_crawl.fShouldParentFrameUseUnwindTargetPCforGCReporting = false; + if (!m_sfParent.IsNull()) { // we are now skipping frames to get to the funclet's parent @@ -1887,7 +1892,7 @@ ProcessFuncletsForGCReporting: _ASSERTE(m_fDidFuncletReportGCReferences); m_fDidFuncletReportGCReferences = false; - + STRESS_LOG0(LF_GCROOTS, LL_INFO100, "Unwound funclet will skip reporting references\n"); } } @@ -1913,6 +1918,9 @@ ProcessFuncletsForGCReporting: if (m_sfParent.IsMaxVal() || ExceptionTracker::IsUnwoundToTargetParentFrame(&m_crawl, m_sfParent)) { + // Reset flag as we have reached target method frame so no more skipping required + fSkippingFunclet = false; + // We've finished skipping as told. Now check again. if ((m_fProcessIntermediaryNonFilterFunclet == true) || (m_fProcessNonFilterFunclet == true)) @@ -1997,6 +2005,23 @@ ProcessFuncletsForGCReporting: // now that we've found the parent that will report roots reset our state. m_fDidFuncletReportGCReferences = true; + + // After funclet gets unwound parent will begin to report gc references. Reporting GC references + // using the IP of throw in parent method can crash application. Parent could have locals objects + // which might not have been reported by funclet as live and would have already been collected + // when funclet was on stack. Now if parent starts using IP of throw to report gc references it + // would report garbage values as live objects. So instead parent can use the IP of the resume + // address of catch funclet to report live GC references. + m_crawl.fShouldParentFrameUseUnwindTargetPCforGCReporting = true; + // Store catch clause info. Helps retrieve IP of resume address. + m_crawl.ehClauseForCatch = pTracker->GetEHClauseForCatch(); + + STRESS_LOG3(LF_GCROOTS, LL_INFO100, + "STACKWALK: Parent of funclet which didn't report GC roots is handling an exception at 0x%p" + "(EH handler range [%x, %x) ), so we need to specially report roots to ensure variables alive" + " in its handler stay live.\n", + pTracker->GetCatchToCallPC(), m_crawl.ehClauseForCatch.HandlerStartPC, + m_crawl.ehClauseForCatch.HandlerEndPC); } else if (!m_crawl.IsFunclet()) { diff --git a/src/vm/stackwalk.h b/src/vm/stackwalk.h index 7fd882d3b6..d92cb9e374 100644 --- a/src/vm/stackwalk.h +++ b/src/vm/stackwalk.h @@ -405,6 +405,17 @@ public: return fShouldCrawlframeReportGCReferences; } + + bool ShouldParentToFuncletUseUnwindTargetLocationForGCReporting() + { + LIMITED_METHOD_CONTRACT; + return fShouldParentFrameUseUnwindTargetPCforGCReporting; + } + + const EE_ILEXCEPTION_CLAUSE& GetEHClauseForCatch() + { + return ehClauseForCatch; + } #endif // WIN64EXCEPTIONS @@ -452,6 +463,8 @@ private: bool isFilterFuncletCached; bool fShouldParentToFuncletSkipReportingGCReferences; bool fShouldCrawlframeReportGCReferences; + bool fShouldParentFrameUseUnwindTargetPCforGCReporting; + EE_ILEXCEPTION_CLAUSE ehClauseForCatch; #endif //WIN64EXCEPTIONS Thread* pThread; diff --git a/src/vm/threaddebugblockinginfo.cpp b/src/vm/threaddebugblockinginfo.cpp index a77c69b457..6ff0bab3e7 100644 --- a/src/vm/threaddebugblockinginfo.cpp +++ b/src/vm/threaddebugblockinginfo.cpp @@ -82,10 +82,17 @@ m_pThread(pThread) #endif //DACCESS_COMPILE // Holder destructor pops a blocking item off the blocking info stack +// NOTE: optimizations are disabled to work around a codegen bug on x86 #ifndef DACCESS_COMPILE +#ifdef _TARGET_X86_ +#pragma optimize( "", off ) +#endif // _TARGET_X86_ DebugBlockingItemHolder::~DebugBlockingItemHolder() { LIMITED_METHOD_CONTRACT; m_pThread->DebugBlockingInfo.PopBlockingItem(); } +#ifdef _TARGET_X86_ +#pragma optimize( "", on ) +#endif // _TARGET_X86_ #endif //DACCESS_COMPILE diff --git a/src/vm/threads.cpp b/src/vm/threads.cpp index 3fc78f1e8a..87ad9bc1f2 100644 --- a/src/vm/threads.cpp +++ b/src/vm/threads.cpp @@ -6309,6 +6309,21 @@ void ThreadStore::AddThread(Thread *newThread, BOOL bRequiresTSL) } } +// this function is just desgined to avoid deadlocks during abnormal process termination, and should not be used for any other purpose +BOOL ThreadStore::CanAcquireLock() +{ + WRAPPER_NO_CONTRACT; +#ifdef FEATURE_INCLUDE_ALL_INTERFACES + if (!s_pThreadStore->m_Crst.IsOSCritSec()) + { + return true; + } + else +#endif + { + return (s_pThreadStore->m_Crst.m_criticalsection.LockCount == -1 || (size_t)s_pThreadStore->m_Crst.m_criticalsection.OwningThread == (size_t)GetCurrentThreadId()); + } +} // Whenever one of the components of OtherThreadsComplete() has changed in the // correct direction, see whether we can now shutdown the EE because only background diff --git a/src/vm/threads.h b/src/vm/threads.h index b77c33bdda..28c593c103 100644 --- a/src/vm/threads.h +++ b/src/vm/threads.h @@ -5683,6 +5683,8 @@ public: // RemoveThread finds the thread in the ThreadStore and discards it. static BOOL RemoveThread(Thread *target); + static BOOL CanAcquireLock(); + // Transfer a thread from the unstarted to the started list. // WARNING : only GC calls this with bRequiresTSL set to FALSE. static void TransferStartedThread(Thread *target, BOOL bRequiresTSL=TRUE); diff --git a/src/vm/vm.settings b/src/vm/vm.settings index 5e7ac72cbe..b4799d1b37 100644 --- a/src/vm/vm.settings +++ b/src/vm/vm.settings @@ -26,6 +26,7 @@ $(ClrSrcDirectory)\debug\inc\dump; $(ClrSrcDirectory)\zap; $(ClrSrcDirectory)\strongname\inc; + $(ClrSrcDirectory)\TraceLog; $(ClrSrcDirectory)\gc </UserIncludes> diff --git a/src/vm/wks/wks.targets b/src/vm/wks/wks.targets index 55b404c0e7..5f2770b267 100644 --- a/src/vm/wks/wks.targets +++ b/src/vm/wks/wks.targets @@ -383,4 +383,7 @@ <AssembleArm64 Include="$(IntermediateOutputDirectory)\PInvokeStubs.i" /> <AssembleArm64 Include="$(IntermediateOutputDirectory)\crtHelpers.i" /> </ItemGroup> + <ItemGroup> + <CppCompile Condition="'$(FeatureTraceLogging)' == 'true'" Include="$(VmSourcesDir)\clrtracelogging.cpp" /> + </ItemGroup> </Project> diff --git a/src/zap/zapheaders.cpp b/src/zap/zapheaders.cpp index 7df102abf4..6a51605a8f 100644 --- a/src/zap/zapheaders.cpp +++ b/src/zap/zapheaders.cpp @@ -75,7 +75,7 @@ void ZapImage::SaveNativeHeader() if (m_ModuleDecoder.HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_SECURITY)) nativeHeader.Flags |= CORCOMPILE_HEADER_HAS_SECURITY_DIRECTORY; - nativeHeader.COR20Flags = m_ModuleDecoder.GetCorHeader()->Flags; + nativeHeader.COR20Flags = m_ModuleDecoder.GetCorHeader()->Flags; #ifdef CROSSGEN_COMPILE if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_CrossGenAssumeInputSigned)) @@ -91,24 +91,27 @@ void ZapImage::SaveNativeHeader() } #endif - if (m_ModuleDecoder.HasReadyToRunHeader()) - { - // Pretend that ready-to-run images are IL-only - nativeHeader.COR20Flags |= COMIMAGE_FLAGS_ILONLY; + if (m_ModuleDecoder.HasReadyToRunHeader()) + { + // Pretend that ready-to-run images are IL-only + nativeHeader.COR20Flags |= COMIMAGE_FLAGS_ILONLY; - // Pretend that ready-to-run images do not have native header - nativeHeader.COR20Flags &= ~COMIMAGE_FLAGS_IL_LIBRARY; - } + // Pretend that ready-to-run images do not have native header + nativeHeader.COR20Flags &= ~COMIMAGE_FLAGS_IL_LIBRARY; + + // Remember whether the source IL image had ReadyToRun header + nativeHeader.Flags |= CORCOMPILE_HEADER_IS_READY_TO_RUN; + } - if (m_fHaveProfileData) - nativeHeader.Flags |= CORCOMPILE_HEADER_IS_IBC_OPTIMIZED; + if (m_fHaveProfileData) + nativeHeader.Flags |= CORCOMPILE_HEADER_IS_IBC_OPTIMIZED; - DWORD dwPEKind, dwMachine; - m_ModuleDecoder.GetPEKindAndMachine(&dwPEKind, &dwMachine); - nativeHeader.PEKind = dwPEKind; - nativeHeader.Machine = (WORD)dwMachine; + DWORD dwPEKind, dwMachine; + m_ModuleDecoder.GetPEKindAndMachine(&dwPEKind, &dwMachine); + nativeHeader.PEKind = dwPEKind; + nativeHeader.Machine = (WORD)dwMachine; - nativeHeader.Characteristics = m_ModuleDecoder.GetCharacteristics(); + nativeHeader.Characteristics = m_ModuleDecoder.GetCharacteristics(); SetDirectoryData(&nativeHeader.EEInfoTable, m_pEEInfoTable); diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp index c31ca019e7..1bc1568a7e 100644 --- a/src/zap/zapimport.cpp +++ b/src/zap/zapimport.cpp @@ -1134,7 +1134,18 @@ ZapImport * ZapImportTable::GetClassHandleImport(CORINFO_CLASS_HANDLE handle, PV return GetImport<ZapClassHandleImport, ZapNodeType_Import_ClassHandle>(handle, pUniqueId); } - return GetImport<ZapClassHandleImport, ZapNodeType_Import_ClassHandle>(handle); + ZapImport * pImport = GetImport<ZapClassHandleImport, ZapNodeType_Import_ClassHandle>(handle); + + if (IsReadyToRunCompilation() && !pImport->HasBlob()) + { + SigBuilder sigBuilder; + + EncodeClass(ENCODE_TYPE_HANDLE, handle, &sigBuilder); + + pImport->SetBlob(GetBlob(&sigBuilder)); + } + + return pImport; } class ZapFieldHandleImport : public ZapImport diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp index 0f85157e38..cdbc225f8e 100644 --- a/src/zap/zapper.cpp +++ b/src/zap/zapper.cpp @@ -904,10 +904,7 @@ void Zapper::InitEE(BOOL fForceDebug, BOOL fForceProfile, BOOL fForceInstrument) // // Also see the code and comments in EEJitManager::LoadJIT(). - static ConfigDWORD useRyuJitValue; - bool fUseRyuJit = (useRyuJitValue.val(CLRConfig::INTERNAL_UseRyuJit) == 1); - - if (!fUseRyuJit) // Do we need to fall back to JIT64 for NGEN? + if (!UseRyuJit()) // Do we need to fall back to JIT64 for NGEN? { LPCWSTR pwzJitName = MAKEDLLNAME_W(L"compatjit"); @@ -2639,7 +2636,7 @@ HRESULT Zapper::Compile(LPCWSTR string, CORCOMPILE_NGEN_SIGNATURE * pNativeImage #endif #if defined(CROSSGEN_COMPILE) || defined(FEATURE_CORECLR) - if (fMscorlib) + if (fMscorlib || IsReadyToRunCompilation()) { // // Disallow use of native image to force a new native image generation for mscorlib |