summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2015-05-06 23:43:46 -0700
committerJan Kotas <jkotas@microsoft.com>2015-05-07 12:03:00 -0700
commit484a2cf0b0c4e304a5093ec26e07fe41f8896c3c (patch)
tree348b56df4cdb235bb87ba9bc9118711c8db13bfd
parentc6efc7047edb38075310cfef8ea28b91717b8108 (diff)
downloadcoreclr-484a2cf0b0c4e304a5093ec26e07fe41f8896c3c.tar.gz
coreclr-484a2cf0b0c4e304a5093ec26e07fe41f8896c3c.tar.bz2
coreclr-484a2cf0b0c4e304a5093ec26e07fe41f8896c3c.zip
Merge changes from parent branch
[tfs-changeset: 1466545]
-rw-r--r--src/debug/daccess/nidump.cpp1
-rw-r--r--src/inc/corcompile.h10
-rw-r--r--src/inc/eetwain.h8
-rw-r--r--src/inc/eventtracebase.h15
-rw-r--r--src/inc/pedecoder.h1
-rw-r--r--src/inc/pedecoder.inl15
-rw-r--r--src/jit/codegenxarch.cpp17
-rw-r--r--src/jit/flowgraph.cpp21
-rw-r--r--src/jit/gentree.cpp6
-rw-r--r--src/jit/lower.cpp71
-rw-r--r--src/jit/lower.h7
-rw-r--r--src/jit/lowerxarch.cpp25
-rw-r--r--src/jit/lsra.cpp25
-rw-r--r--src/jit/optimizer.cpp18
-rw-r--r--src/jit/simdcodegenxarch.cpp48
-rw-r--r--src/jit/ssabuilder.cpp19
-rw-r--r--src/jit/valuenum.cpp13
-rw-r--r--src/md/winmd/adapter.cpp55
-rw-r--r--src/md/winmd/inc/adapter.h11
-rw-r--r--src/md/winmd/winmdimport.cpp2
-rw-r--r--src/md/winmd/winmdinternalimportro.cpp6
-rw-r--r--src/mscorlib/src/System/AppDomain.cs22
-rw-r--r--src/mscorlib/src/System/AppDomainSetup.cs22
-rw-r--r--src/mscorlib/src/System/Globalization/CalendarData.cs16
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs6
-rw-r--r--src/pal/prebuilt/inc/clretwall.h311
-rw-r--r--src/pal/prebuilt/inc/clretwallmain.h2
-rw-r--r--src/pal/prebuilt/inc/etmdummy.h7
-rw-r--r--src/vm/ClrEtwAll.man84
-rw-r--r--src/vm/appdomain.hpp3
-rw-r--r--src/vm/assembly.cpp51
-rw-r--r--src/vm/assembly.hpp4
-rw-r--r--src/vm/ceeload.cpp10
-rw-r--r--src/vm/clrtracelogging.cpp41
-rw-r--r--src/vm/codeman.cpp2
-rw-r--r--src/vm/compile.cpp19
-rw-r--r--src/vm/coreassemblyspec.cpp2
-rw-r--r--src/vm/crossgen/wks_crossgen.nativeproj4
-rw-r--r--src/vm/domainfile.cpp7
-rw-r--r--src/vm/dwreport.cpp98
-rw-r--r--src/vm/eetwain.cpp51
-rw-r--r--src/vm/eventtrace.cpp139
-rw-r--r--src/vm/exceptionhandling.cpp53
-rw-r--r--src/vm/exceptionhandling.h9
-rw-r--r--src/vm/gcenv.cpp108
-rw-r--r--src/vm/i386/excepx86.cpp14
-rw-r--r--src/vm/i386/stublinkerx86.cpp8
-rw-r--r--src/vm/methodtablebuilder.cpp14
-rw-r--r--src/vm/pefile.cpp20
-rw-r--r--src/vm/pefile.h1
-rw-r--r--src/vm/pefile.inl22
-rw-r--r--src/vm/peimage.cpp9
-rw-r--r--src/vm/stackwalk.cpp27
-rw-r--r--src/vm/stackwalk.h13
-rw-r--r--src/vm/threaddebugblockinginfo.cpp7
-rw-r--r--src/vm/threads.cpp15
-rw-r--r--src/vm/threads.h2
-rw-r--r--src/vm/vm.settings1
-rw-r--r--src/vm/wks/wks.targets3
-rw-r--r--src/zap/zapheaders.cpp33
-rw-r--r--src/zap/zapimport.cpp13
-rw-r--r--src/zap/zapper.cpp7
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