summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/debug/debug-pal/unix/twowaypipe.cpp4
-rw-r--r--src/debug/shared/dbgtransportsession.cpp5
-rw-r--r--src/gc/gc.cpp8
-rw-r--r--src/gc/gc.h2
-rw-r--r--src/ildasm/dasm.cpp10
-rw-r--r--src/ildasm/dasm.rc22
-rw-r--r--src/ildasm/dis.cpp10
-rw-r--r--src/inc/formattype.cpp4
-rw-r--r--src/inc/formattype.h2
-rw-r--r--src/jit/lower.cpp18
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs3
-rw-r--r--src/mscorlib/model.xml4
-rw-r--r--src/mscorlib/mscorlib.shared.sources.props4
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs74
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventCounter.cs432
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventDescriptor.cs18
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs92
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs545
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventSourceException.cs10
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs223
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/StubEnvironment.cs34
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ArrayTypeInfo.cs25
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs8
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumHelper.cs26
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumerableTypeInfo.cs24
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldFormat.cs4
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs6
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs8
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/InvokeTypeInfo.cs40
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/NameInfo.cs4
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAccessor.cs157
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAnalysis.cs8
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs251
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleEventTypes.cs23
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs1003
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs354
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs303
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs95
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs6
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs8
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs33
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo_T.cs161
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TypeAnalysis.cs4
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/Winmeta.cs21
-rw-r--r--src/nativeresources/processrc.awk12
-rw-r--r--src/pal/inc/pal.h1
-rw-r--r--src/pal/inc/pal_mstypes.h3
-rw-r--r--src/scripts/Utilities.py6
-rw-r--r--src/scripts/genWinEtw.py20
-rw-r--r--src/scripts/genXplatEventing.py25
-rw-r--r--src/scripts/genXplatLttng.py68
-rw-r--r--src/vm/exceptionhandling.cpp8
-rw-r--r--src/vm/gcenv.ee.cpp19
-rw-r--r--src/vm/siginfo.cpp14
54 files changed, 1875 insertions, 2397 deletions
diff --git a/src/debug/debug-pal/unix/twowaypipe.cpp b/src/debug/debug-pal/unix/twowaypipe.cpp
index 18881616f2..41da7ff2a3 100644
--- a/src/debug/debug-pal/unix/twowaypipe.cpp
+++ b/src/debug/debug-pal/unix/twowaypipe.cpp
@@ -178,13 +178,13 @@ int TwoWayPipe::Write(const void *data, DWORD dataSize)
bool TwoWayPipe::Disconnect()
{
- if (m_outboundPipe != INVALID_PIPE)
+ if (m_outboundPipe != INVALID_PIPE && m_outboundPipe != 0)
{
close(m_outboundPipe);
m_outboundPipe = INVALID_PIPE;
}
- if (m_inboundPipe != INVALID_PIPE)
+ if (m_inboundPipe != INVALID_PIPE && m_inboundPipe != 0)
{
close(m_inboundPipe);
m_inboundPipe = INVALID_PIPE;
diff --git a/src/debug/shared/dbgtransportsession.cpp b/src/debug/shared/dbgtransportsession.cpp
index 2b17f6d6d8..01f4acbc66 100644
--- a/src/debug/shared/dbgtransportsession.cpp
+++ b/src/debug/shared/dbgtransportsession.cpp
@@ -57,6 +57,11 @@ HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB, AppDomainEnumer
// cleanup necessary.
memset(this, 0, sizeof(*this));
+ // Because of the above memset the embeded classes/structs need to be reinitialized especially
+ // the two way pipe; it expects the in/out handles to be -1 instead of 0.
+ m_pipe = TwoWayPipe();
+ m_sStateLock = DbgTransportLock();
+
// Initialize all per-session state variables.
InitSessionState();
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index c91d2a6baf..b329f894ed 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -21674,6 +21674,14 @@ void gc_heap::plan_phase (int condemned_gen_number)
(size_t)new_address + ps, ps,
(is_plug_padded (plug_start) ? 1 : 0)));
#endif //SIMPLE_DPRINTF
+
+#ifdef SHORT_PLUGS
+ if (is_plug_padded (plug_start))
+ {
+ dprintf (3, ("%Ix was padded", plug_start));
+ dd_padding_size (dd_active_old) += Align (min_obj_size);
+ }
+#endif //SHORT_PLUGS
}
}
}
diff --git a/src/gc/gc.h b/src/gc/gc.h
index 8c8645e089..94d2d5df2d 100644
--- a/src/gc/gc.h
+++ b/src/gc/gc.h
@@ -204,6 +204,7 @@ struct ScanContext
{
Thread* thread_under_crawl;
int thread_number;
+ uintptr_t stack_limit; // Lowest point on the thread stack that the scanning logic is permitted to read
BOOL promotion; //TRUE: Promotion, FALSE: Relocation.
BOOL concurrent; //TRUE: concurrent scanning
#if CHECK_APP_DOMAIN_LEAKS || defined (FEATURE_APPDOMAIN_RESOURCE_MONITORING) || defined (DACCESS_COMPILE)
@@ -225,6 +226,7 @@ struct ScanContext
thread_under_crawl = 0;
thread_number = -1;
+ stack_limit = 0;
promotion = FALSE;
concurrent = FALSE;
#ifdef GC_PROFILING
diff --git a/src/ildasm/dasm.cpp b/src/ildasm/dasm.cpp
index 8032af63d5..a220fa86bf 100644
--- a/src/ildasm/dasm.cpp
+++ b/src/ildasm/dasm.cpp
@@ -3447,7 +3447,7 @@ BOOL DumpMethod(mdToken FuncToken, const char *pszClassName, DWORD dwEntryPointT
ULONG ulArgs=0;
unsigned retParamIx = 0;
unsigned uStringLen = SZSTRING_SIZE;
- char szArgPrefix[32];
+ char szArgPrefix[MAX_PREFIX_SIZE];
char* szptr = NULL;
mdToken tkMVarOwner = g_tkMVarOwner;
@@ -3627,7 +3627,7 @@ lDone: ;
qbMemberSig.Shrink(0);
// Get the argument names, if any
- strcpy_s(szArgPrefix,32,(g_fThisIsInstanceMethod ? "A1": "A0"));
+ strcpy_s(szArgPrefix,MAX_PREFIX_SIZE,(g_fThisIsInstanceMethod ? "A1": "A0"));
{
PCCOR_SIGNATURE typePtr = pComSig;
unsigned ulCallConv = CorSigUncompressData(typePtr); // get the calling convention out of the way
@@ -3699,11 +3699,7 @@ lDone: ;
sprintf_s(pszArgname[j].name,16,"A_%d",g_fThisIsInstanceMethod ? j+1 : j);
}
}// end for( along the argnames)
-#ifdef _WIN64
- sprintf_s(szArgPrefix,32,"@%I64d0",(size_t)pszArgname);
-#else
- sprintf_s(szArgPrefix,32,"@%d0",(size_t)pszArgname);
-#endif //_WIN64
+ sprintf_s(szArgPrefix,MAX_PREFIX_SIZE,"@%Id0",(size_t)pszArgname);
} //end if (ulArgs)
g_pImport->EnumClose(&hArgEnum);
}
diff --git a/src/ildasm/dasm.rc b/src/ildasm/dasm.rc
index 9de2a73b64..cc45a895b6 100644
--- a/src/ildasm/dasm.rc
+++ b/src/ildasm/dasm.rc
@@ -297,10 +297,11 @@ BEGIN
IDS_USAGE_05 L"Options for GUI or file/console output (EXE and DLL files only):\n"
#else
IDS_USAGE_03 L" /OUT=<file name> Direct output to file rather than to console.\n"
+ IDS_USAGE_04 L""
IDS_USAGE_04A L" /HTML Output in HTML format (valid with /OUT option only).\n"
IDS_USAGE_04B L" /RTF Output in rich text format (valid with /OUT option only).\n"
IDS_USAGE_05 L"Options for file/console output:\n"
-#endif
+#endif // !FEATURE_PAL
#ifdef OWNER_OPTION_ENABLED
IDS_USAGE_06 L" /OWNER=<owner name> Set owner name to disassemble a protected PE file.\n"
#endif
@@ -326,7 +327,11 @@ BEGIN
IDS_USAGE_16 L" /NOBAR Suppress disassembly progress bar window pop-up.\n\n"
IDS_USAGE_17 L"The following options are valid for file/console output only:\n"
IDS_USAGE_18 L"Options for EXE and DLL files:\n"
-#endif
+#else
+ IDS_USAGE_16 L""
+ IDS_USAGE_17 L""
+ IDS_USAGE_18 L""
+#endif // !FEATURE_PAL
IDS_USAGE_19 L" /UTF8 Use UTF-8 encoding for output (default - ANSI).\n"
IDS_USAGE_20 L" /UNICODE Use UNICODE encoding for output.\n"
IDS_USAGE_21 L" /NOIL Suppress IL assembler code output.\n"
@@ -344,7 +349,9 @@ BEGIN
IDS_USAGE_26 L" /ALL Combination of /HEADER,/BYTES,/STATS,/CLASSLIST,/TOKENS\n\n"
#ifndef FEATURE_PAL
IDS_USAGE_27 L"Options for EXE,DLL,OBJ and LIB files:\n"
-#endif
+#else
+ IDS_USAGE_27 L""
+#endif // !FEATURE_PAL
IDS_USAGE_28 L" /METADATA[=<specifier>] Show MetaData, where <specifier> is:\n"
IDS_USAGE_29 L" MDHEADER Show MetaData header information and sizes.\n"
IDS_USAGE_30 L" HEX Show more things in hex as well as words.\n"
@@ -352,7 +359,9 @@ BEGIN
IDS_USAGE_32 L" UNREX Show unresolved externals.\n"
#ifndef FEATURE_PAL
IDS_USAGE_33 L" DEBUG Show debug information in addition to other MetaData.\n"
-#endif
+#else
+ IDS_USAGE_33 L""
+#endif // !FEATURE_PAL
IDS_USAGE_34 L" SCHEMA Show the MetaData header and schema information.\n"
IDS_USAGE_35 L" RAW Show the raw MetaData tables.\n"
IDS_USAGE_36 L" HEAPS Show the raw heaps.\n"
@@ -360,7 +369,10 @@ BEGIN
#ifndef FEATURE_PAL
IDS_USAGE_38 L"Options for LIB files only:\n"
IDS_USAGE_39 L" /OBJECTFILE=<obj_file_name> Show MetaData of a single object file in library\n"
-#endif
+#else
+ IDS_USAGE_38 L""
+ IDS_USAGE_39 L""
+#endif // !FEATURE_PAL
END
STRINGTABLE DISCARDABLE
diff --git a/src/ildasm/dis.cpp b/src/ildasm/dis.cpp
index 796271b356..48f4586ab9 100644
--- a/src/ildasm/dis.cpp
+++ b/src/ildasm/dis.cpp
@@ -915,7 +915,7 @@ BOOL Disassemble(IMDInternalImport *pImport, BYTE *ILHeader, void *GUICookie, md
LineCodeDescr* pLCD = NULL;
ParamDescriptor* pszLVname = NULL;
ULONG ulVars=0;
- char szVarPrefix[64];
+ char szVarPrefix[MAX_PREFIX_SIZE];
// scope handling:
DynamicArray<LexScope> daScope;
ULONG ulScopes=0;
@@ -928,7 +928,7 @@ BOOL Disassemble(IMDInternalImport *pImport, BYTE *ILHeader, void *GUICookie, md
ULONG32 ulMethodCol[2];
BOOL fHasRangeInfo = FALSE;
- strcpy_s(szVarPrefix,64,"V0");
+ strcpy_s(szVarPrefix,MAX_PREFIX_SIZE,"V0");
if(g_pSymReader)
{
g_pSymReader->GetMethod(FuncToken,&pSymMethod);
@@ -1048,11 +1048,7 @@ BOOL Disassemble(IMDInternalImport *pImport, BYTE *ILHeader, void *GUICookie, md
LoadScope(pRootScope,&daScope,&ulScopes);
qsort(&daScope[0],ulScopes,sizeof(LexScope),cmpLexScope);
OpenScope(pRootScope,pszLVname,ulVars);
-#ifdef _WIN64
- sprintf_s(szVarPrefix,64,"@%I64d0",(size_t)pszLVname);
-#else
- sprintf_s(szVarPrefix,64,"@%d0",(size_t)pszLVname);
-#endif //_WIN64
+ sprintf_s(szVarPrefix,MAX_PREFIX_SIZE,"@%Id0",(size_t)pszLVname);
#ifndef SHOW_LEXICAL_SCOPES
for(unsigned jjj = 0; jjj < ulScopes; jjj++)
diff --git a/src/inc/formattype.cpp b/src/inc/formattype.cpp
index 923ff3e9a1..b8960f48c6 100644
--- a/src/inc/formattype.cpp
+++ b/src/inc/formattype.cpp
@@ -206,14 +206,14 @@ const PCCOR_SIGNATURE PrettyPrintSignature(
PCCOR_SIGNATURE typeEnd = typePtr + typeLen;
unsigned ixArg= 0; //arg index
char argname[1024];
- char label[16];
+ char label[MAX_PREFIX_SIZE];
const char* openpar = "(";
const char* closepar = ")";
ParamDescriptor* pszArgName = NULL; // ptr to array of names (if provided by debug info)
if(inlabel && *inlabel) // check for *inlabel is totally unnecessary, added to pacify the PREFIX
{
- strcpy_s(label,COUNTOF(label),inlabel);
+ strcpy_s(label,MAX_PREFIX_SIZE,inlabel);
ixArg = label[strlen(label)-1] - '0';
label[strlen(label)-1] = 0;
if(label[0] == '@') // it's pointer!
diff --git a/src/inc/formattype.h b/src/inc/formattype.h
index 739bc89dd4..53ba4a115c 100644
--- a/src/inc/formattype.h
+++ b/src/inc/formattype.h
@@ -16,6 +16,8 @@
#endif
#endif
+#define MAX_PREFIX_SIZE 32
+
struct ParamDescriptor
{
char* name;
diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp
index 3dad01a71b..a932594720 100644
--- a/src/jit/lower.cpp
+++ b/src/jit/lower.cpp
@@ -3343,9 +3343,7 @@ Lowering::LowerArrElem(GenTree **ppTree, Compiler::fgWalkData* data)
GenTreePtr arrObjNode = arrElem->gtArrObj;
assert(arrObjNode->IsLocal());
- GenTreePtr nextNode = arrElem->gtNext;
- // ??? Can we have a top-level GT_ARR_ELEM ???
- noway_assert(nextNode != nullptr);
+ GenTreePtr nextNode = arrElem;
// We need to evaluate the index expressions up-front if they have side effects.
for (unsigned char dim = 0; dim < rank; dim++)
@@ -3371,7 +3369,6 @@ Lowering::LowerArrElem(GenTree **ppTree, Compiler::fgWalkData* data)
GenTree* prevArrOffs = new(comp, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, 0);
comp->fgInsertLinearNodeBefore(prevArrOffs, arrObjNode);
- comp->fgSnipInnerNode(arrElem);
for (unsigned char dim = 0; dim < rank; dim++)
{
GenTree* currIndexTree = arrElem->gtArrElem.gtArrInds[dim];
@@ -3450,6 +3447,19 @@ Lowering::LowerArrElem(GenTree **ppTree, Compiler::fgWalkData* data)
*ppTree = leaNode;
+ if (arrElem->gtNext != nullptr)
+ {
+ comp->fgSnipInnerNode(arrElem);
+ }
+ else
+ {
+ // We can have a top-level GT_ARR_ELEM. For example, a function call
+ // with a parameter of GT_ARR_ELEM can end up being simplified by the
+ // inliner to single GT_ARR_ELEM node if the function has an empty body.
+ arrElem->gtPrev->gtNext = nullptr;
+ curStmt->gtStmt.gtStmtExpr = *ppTree;
+ }
+
// Update the costs.
comp->gtSetStmtInfo(curStmt);
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
index a60707cb60..84ecfeab17 100644
--- a/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
@@ -88,7 +88,8 @@ namespace System.Globalization
private bool NeedsTurkishCasing(string localeName)
{
Contract.Assert(localeName != null);
- return CultureInfo.GetCultureInfo(localeName).CompareInfo.Compare("i", "I", CompareOptions.IgnoreCase) != 0;
+
+ return CultureInfo.GetCultureInfo(localeName).CompareInfo.Compare("\u0131", "I", CompareOptions.IgnoreCase) == 0;
}
private bool IsInvariant { get { return m_cultureName.Length == 0; } }
diff --git a/src/mscorlib/model.xml b/src/mscorlib/model.xml
index ecaa8f4c02..659d5be6dc 100644
--- a/src/mscorlib/model.xml
+++ b/src/mscorlib/model.xml
@@ -9762,10 +9762,6 @@
</Type>
<Type Status="ImplRoot" Name="System.Diagnostics.StackFrameHelper" />
- <Type Status="ImplRoot" Name="System.Diagnostics.Tracing.EnumHelper&lt;UnderlyingType&gt;">
- <Member Name="Identity(UnderlyingType)" />
- </Type>
-
<Type Name="System.Diagnostics.Tracing.EventAttribute">
<Member Name="#ctor(System.Int32)" />
<Member Name="get_EventId" />
diff --git a/src/mscorlib/mscorlib.shared.sources.props b/src/mscorlib/mscorlib.shared.sources.props
index 33189a138e..e14bdd6d8d 100644
--- a/src/mscorlib/mscorlib.shared.sources.props
+++ b/src/mscorlib/mscorlib.shared.sources.props
@@ -990,6 +990,7 @@
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventDescriptor.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventProvider.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventSource.cs" />
+ <DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventSource_CoreCLR.cs" />
<DiagnosticsSources Condition="'$(FeatureXplatEventSource)' == 'true'" Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\XplatEventLogger.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventSourceException.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\FrameworkEventSource.cs" />
@@ -1012,7 +1013,7 @@
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\FieldMetadata.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\InvokeTypeInfo.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\NameInfo.cs" />
- <DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\PropertyAccessor.cs" />
+ <DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\PropertyValue.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\PropertyAnalysis.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\SimpleEventTypes.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\SimpleTypeInfos.cs" />
@@ -1024,7 +1025,6 @@
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingEventTypes.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingMetadataCollector.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingTypeInfo.cs" />
- <DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingTypeInfo_T.cs" />
<DiagnosticsSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TypeAnalysis.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs b/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs
index 54f7b47d28..dcd3f70376 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs
@@ -12,7 +12,7 @@ using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
#if ES_BUILD_STANDALONE
namespace Microsoft.Diagnostics.Tracing
-#else
+#else
using System.Threading.Tasks;
namespace System.Diagnostics.Tracing
#endif
@@ -47,7 +47,7 @@ namespace System.Diagnostics.Tracing
/// Called on work item begins. The activity name = providerName + activityName without 'Start' suffix.
/// It updates CurrentActivityId to track.
///
- /// It returns true if the Start should be logged, otherwise (if it is illegal recurision) it return false.
+ /// It returns true if the Start should be logged, otherwise (if it is illegal recursion) it return false.
///
/// The start event should use as its activity ID the CurrentActivityId AFTER calling this routine and its
/// RelatedActivityID the CurrentActivityId BEFORE calling this routine (the creator).
@@ -64,12 +64,10 @@ namespace System.Diagnostics.Tracing
if (m_checkedForEnable)
return;
m_checkedForEnable = true;
-#if ES_BUILD_STANDALONE
- Enable(); // Enable it unconditionally.
-#else
- if (System.Threading.Tasks.TplEtwProvider.Log.IsEnabled(EventLevel.Informational, System.Threading.Tasks.TplEtwProvider.Keywords.TasksFlowActivityIds))
- Enable();
-#endif
+ if (TplEtwProvider.Log.IsEnabled(EventLevel.Informational, TplEtwProvider.Keywords.TasksFlowActivityIds))
+ Enable();
+ if (m_current == null)
+ return;
}
@@ -124,7 +122,7 @@ namespace System.Diagnostics.Tracing
// Remember the current ID so we can log it
activityId = newActivity.ActivityId;
-
+
if (etwLog.Debug)
{
etwLog.DebugFacilityMessage("OnStartRetActivityState", ActivityInfo.LiveActivities(newActivity));
@@ -144,7 +142,7 @@ namespace System.Diagnostics.Tracing
return;
var fullActivityName = NormalizeActivityName(providerName, activityName, task);
-
+
var etwLog = TplEtwProvider.Log;
if (etwLog.Debug)
{
@@ -215,7 +213,7 @@ namespace System.Diagnostics.Tracing
}
return;
}
- // We failed to stop it. We must have hit a race condition to stop it. Just start over and try again.
+ // We failed to stop it. We must have hit a race to stop it. Just start over and try again.
}
}
@@ -227,7 +225,17 @@ namespace System.Diagnostics.Tracing
{
if (m_current == null)
{
- m_current = new AsyncLocal<ActivityInfo>(ActivityChanging);
+ // Catch the not Implemented
+ try
+ {
+ m_current = new AsyncLocal<ActivityInfo>(ActivityChanging);
+ }
+ catch (NotImplementedException) {
+#if (!ES_BUILD_PCL && ! PROJECTN)
+ // send message to debugger without delay
+ System.Diagnostics.Debugger.Log(0, null, "Activity Enabled() called but AsyncLocals Not Supported (pre V4.6). Ignoring Enable");
+#endif
+ }
}
}
@@ -375,10 +383,10 @@ namespace System.Diagnostics.Tracing
{
// TODO FIXME - differentiate between AD inside PCL
int appDomainID = 0;
-#if !ES_BUILD_STANDALONE
+#if (!ES_BUILD_STANDALONE && !PROJECTN)
appDomainID = System.Threading.Thread.GetDomainID();
#endif
- // We start with the appdomain number to make this unique among appdomains.
+ // We start with the appdomain number to make this unique among appdomains.
activityPathGuidOffsetStart = AddIdToGuid(outPtr, activityPathGuidOffsetStart, (uint)appDomainID);
}
@@ -608,7 +616,7 @@ namespace System.Diagnostics.Tracing
#endregion
}
-#if ES_BUILD_STANDALONE
+#if ES_BUILD_STANDALONE || PROJECTN
/******************************** SUPPORT *****************************/
/// <summary>
/// This is supplied by the framework. It is has the semantics that the value is copied to any new Tasks that is created
@@ -617,12 +625,17 @@ namespace System.Diagnostics.Tracing
/// only get your thread local copy which means that you never have races.
/// </summary>
///
- [EventSource(Name="Microsoft.Tasks.Nuget")]
+#if ES_BUILD_STANDALONE
+ [EventSource(Name = "Microsoft.Tasks.Nuget")]
+#else
+ [EventSource(Name = "System.Diagnostics.Tracing.TplEtwProvider")]
+#endif
internal class TplEtwProvider : EventSource
{
public class Keywords
{
- public const EventKeywords Debug = (EventKeywords) 1;
+ public const EventKeywords TasksFlowActivityIds = (EventKeywords)0x80;
+ public const EventKeywords Debug = (EventKeywords)0x20000;
}
public static TplEtwProvider Log = new TplEtwProvider();
@@ -635,13 +648,9 @@ namespace System.Diagnostics.Tracing
#endif
#if ES_BUILD_AGAINST_DOTNET_V35 || ES_BUILD_PCL || NO_ASYNC_LOCAL
-
+ // In these cases we don't have any Async local support. Do nothing.
internal sealed class AsyncLocalValueChangedArgs<T>
{
- public AsyncLocalValueChangedArgs()
- {
- }
-
public T PreviousValue { get { return default(T); } }
public T CurrentValue { get { return default(T); } }
@@ -649,26 +658,13 @@ namespace System.Diagnostics.Tracing
internal sealed class AsyncLocal<T>
{
- public AsyncLocal()
- {
- }
-
- public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler)
- {
-
+ public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler) {
+ throw new NotImplementedException("AsyncLocal only available on V4.6 and above");
}
-
public T Value
{
- get
- {
- object obj = null; // TODO FIX
- return (obj == null) ? default(T) : (T)obj;
- }
- set
- {
- // TODO FIX
- }
+ get { return default(T); }
+ set { }
}
}
#endif
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventCounter.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventCounter.cs
new file mode 100644
index 0000000000..cad47eeb5b
--- /dev/null
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventCounter.cs
@@ -0,0 +1,432 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+#if ES_BUILD_PCL
+ using System.Threading.Tasks;
+#endif
+
+#if ES_BUILD_STANDALONE
+namespace Microsoft.Diagnostics.Tracing
+#else
+namespace System.Diagnostics.Tracing
+#endif
+{
+ /// <summary>
+ /// Provides the ability to collect statistics through EventSource
+ /// </summary>
+ public class EventCounter
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EventCounter"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="eventSource">The event source.</param>
+ public EventCounter(string name, EventSource eventSource)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ if (eventSource == null)
+ {
+ throw new ArgumentNullException("eventSource");
+ }
+
+ InitializeBuffer();
+ _name = name;
+ EventCounterGroup.AddEventCounter(eventSource, this);
+ }
+
+ /// <summary>
+ /// Writes the metric.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ public void WriteMetric(float value)
+ {
+ Enqueue(value);
+ }
+
+ #region private implementation
+
+ private readonly string _name;
+
+ #region Buffer Management
+
+ // Values buffering
+ private const int BufferedSize = 10;
+ private const float UnusedBufferSlotValue = float.NegativeInfinity;
+ private const int UnsetIndex = -1;
+ private volatile float[] _bufferedValues;
+ private volatile int _bufferedValuesIndex;
+
+ private void InitializeBuffer()
+ {
+ _bufferedValues = new float[BufferedSize];
+ for (int i = 0; i < _bufferedValues.Length; i++)
+ {
+ _bufferedValues[i] = UnusedBufferSlotValue;
+ }
+ }
+
+ private void Enqueue(float value)
+ {
+ // It is possible that two threads read the same bufferedValuesIndex, but only one will be able to write the slot, so that is okay.
+ int i = _bufferedValuesIndex;
+ while (true)
+ {
+ float result = Interlocked.CompareExchange(ref _bufferedValues[i], value, UnusedBufferSlotValue);
+ i++;
+ if (_bufferedValues.Length <= i)
+ {
+ // It is possible that two threads both think the buffer is full, but only one get to actually flush it, the other
+ // will eventually enter this code path and potentially calling Flushing on a buffer that is not full, and that's okay too.
+ lock (_bufferedValues)
+ {
+ Flush();
+ }
+ i = 0;
+ }
+
+ if (result == UnusedBufferSlotValue)
+ {
+ // CompareExchange succeeded
+ _bufferedValuesIndex = i;
+ return;
+ }
+ }
+ }
+
+ private void Flush()
+ {
+ for (int i = 0; i < _bufferedValues.Length; i++)
+ {
+ var value = Interlocked.Exchange(ref _bufferedValues[i], UnusedBufferSlotValue);
+ if (value != UnusedBufferSlotValue)
+ {
+ OnMetricWritten(value);
+ }
+ }
+
+ _bufferedValuesIndex = 0;
+ }
+
+ #endregion // Buffer Management
+
+ #region Statistics Calculation
+
+ // Statistics
+ private int _count;
+ private float _sum;
+ private float _sumSquared;
+ private float _min;
+ private float _max;
+
+ private void OnMetricWritten(float value)
+ {
+ _sum += value;
+ _sumSquared += value * value;
+ if (_count == 0 || value > _max)
+ {
+ _max = value;
+ }
+
+ if (_count == 0 || value < _min)
+ {
+ _min = value;
+ }
+
+ _count++;
+ }
+
+ internal EventCounterPayload GetEventCounterPayload()
+ {
+ lock (_bufferedValues)
+ {
+ Flush();
+ EventCounterPayload result = new EventCounterPayload();
+ result.Name = _name;
+ result.Count = _count;
+ result.Mean = _sum / _count;
+ result.StandardDerivation = (float)Math.Sqrt(_sumSquared / _count - _sum * _sum / _count / _count);
+ result.Min = _min;
+ result.Max = _max;
+ ResetStatistics();
+ return result;
+ }
+ }
+
+ private void ResetStatistics()
+ {
+ _count = 0;
+ _sum = 0;
+ _sumSquared = 0;
+ _min = 0;
+ _max = 0;
+ }
+
+ #endregion // Statistics Calculation
+
+ #endregion // private implementation
+ }
+
+ #region internal supporting classes
+
+ [EventData]
+ internal class EventCounterPayload : IEnumerable<KeyValuePair<string, object>>
+ {
+ public string Name { get; set; }
+
+ public float Mean { get; set; }
+
+ public float StandardDerivation { get; set; }
+
+ public int Count { get; set; }
+
+ public float Min { get; set; }
+
+ public float Max { get; set; }
+
+ public float IntervalSec { get; internal set; }
+
+ #region Implementation of the IEnumerable interface
+
+ public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
+ {
+ return ForEnumeration.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ForEnumeration.GetEnumerator();
+ }
+
+ private IEnumerable<KeyValuePair<string, object>> ForEnumeration
+ {
+ get
+ {
+ yield return new KeyValuePair<string, object>("Name", Name);
+ yield return new KeyValuePair<string, object>("Mean", Mean);
+ yield return new KeyValuePair<string, object>("StandardDerivation", StandardDerivation);
+ yield return new KeyValuePair<string, object>("Count", Count);
+ yield return new KeyValuePair<string, object>("Min", Min);
+ yield return new KeyValuePair<string, object>("Max", Max);
+ }
+ }
+
+ #endregion // Implementation of the IEnumerable interface
+ }
+
+ internal class EventCounterGroup : IDisposable
+ {
+ private readonly EventSource _eventSource;
+ private readonly int _eventSourceIndex;
+ private readonly List<EventCounter> _eventCounters;
+
+ internal EventCounterGroup(EventSource eventSource, int eventSourceIndex)
+ {
+ _eventSource = eventSource;
+ _eventSourceIndex = eventSourceIndex;
+ _eventCounters = new List<EventCounter>();
+ RegisterCommandCallback();
+ }
+
+ private void Add(EventCounter eventCounter)
+ {
+ _eventCounters.Add(eventCounter);
+ }
+
+ #region EventSource Command Processing
+
+ private void RegisterCommandCallback()
+ {
+ _eventSource.EventCommandExecuted += OnEventSourceCommand;
+ }
+
+ private void OnEventSourceCommand(object sender, EventCommandEventArgs e)
+ {
+ if (e.Command == EventCommand.Enable || e.Command == EventCommand.Update)
+ {
+ string valueStr;
+ float value;
+ if (e.Arguments.TryGetValue("EventCounterIntervalSec", out valueStr) && float.TryParse(valueStr, out value))
+ {
+ EnableTimer(value);
+ }
+ }
+ }
+
+ #endregion // EventSource Command Processing
+
+ #region Global EventCounterGroup Array management
+
+ private static EventCounterGroup[] s_eventCounterGroups;
+
+ internal static void AddEventCounter(EventSource eventSource, EventCounter eventCounter)
+ {
+ int eventSourceIndex = EventListener.EventSourceIndex(eventSource);
+
+ EventCounterGroup.EnsureEventSourceIndexAvailable(eventSourceIndex);
+ EventCounterGroup eventCounterGroup = GetEventCounterGroup(eventSource);
+ eventCounterGroup.Add(eventCounter);
+ }
+
+ private static void EnsureEventSourceIndexAvailable(int eventSourceIndex)
+ {
+ if (EventCounterGroup.s_eventCounterGroups == null)
+ {
+ EventCounterGroup.s_eventCounterGroups = new EventCounterGroup[eventSourceIndex + 1];
+ }
+ else if (eventSourceIndex >= EventCounterGroup.s_eventCounterGroups.Length)
+ {
+ EventCounterGroup[] newEventCounterGroups = new EventCounterGroup[eventSourceIndex + 1];
+ Array.Copy(EventCounterGroup.s_eventCounterGroups, newEventCounterGroups, EventCounterGroup.s_eventCounterGroups.Length);
+ EventCounterGroup.s_eventCounterGroups = newEventCounterGroups;
+ }
+ }
+
+ private static EventCounterGroup GetEventCounterGroup(EventSource eventSource)
+ {
+ int eventSourceIndex = EventListener.EventSourceIndex(eventSource);
+ EventCounterGroup result = EventCounterGroup.s_eventCounterGroups[eventSourceIndex];
+ if (result == null)
+ {
+ result = new EventCounterGroup(eventSource, eventSourceIndex);
+ EventCounterGroup.s_eventCounterGroups[eventSourceIndex] = result;
+ }
+
+ return result;
+ }
+
+ #endregion // Global EventCounterGroup Array management
+
+ #region Timer Processing
+
+ private DateTime _timeStampSinceCollectionStarted;
+ private int _pollingIntervalInMilliseconds;
+ private Timer _pollingTimer;
+
+ private void EnableTimer(float pollingIntervalInSeconds)
+ {
+ if (pollingIntervalInSeconds == 0)
+ {
+ if (_pollingTimer != null)
+ {
+ _pollingTimer.Dispose();
+ _pollingTimer = null;
+ }
+
+ _pollingIntervalInMilliseconds = 0;
+ }
+ else if (_pollingIntervalInMilliseconds == 0 || pollingIntervalInSeconds < _pollingIntervalInMilliseconds)
+ {
+ _pollingIntervalInMilliseconds = (int)(pollingIntervalInSeconds * 1000);
+ if (_pollingTimer != null)
+ {
+ _pollingTimer.Dispose();
+ _pollingTimer = null;
+ }
+
+ _timeStampSinceCollectionStarted = DateTime.Now;
+ _pollingTimer = new Timer(OnTimer, null, _pollingIntervalInMilliseconds, _pollingIntervalInMilliseconds);
+ }
+ }
+
+ private void OnTimer(object state)
+ {
+ if (_eventSource.IsEnabled())
+ {
+ DateTime now = DateTime.Now;
+ TimeSpan elapsed = now - _timeStampSinceCollectionStarted;
+ lock (_pollingTimer)
+ {
+ foreach (var eventCounter in _eventCounters)
+ {
+ EventCounterPayload payload = eventCounter.GetEventCounterPayload();
+ payload.IntervalSec = (float)elapsed.TotalSeconds;
+ _eventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new { Payload = payload });
+ }
+
+
+ _timeStampSinceCollectionStarted = now;
+ }
+ }
+ else
+ {
+ _pollingTimer.Dispose();
+ _pollingTimer = null;
+ EventCounterGroup.s_eventCounterGroups[_eventSourceIndex] = null;
+ }
+ }
+
+ #region PCL timer hack
+
+#if ES_BUILD_PCL
+ internal delegate void TimerCallback(object state);
+
+ internal sealed class Timer : CancellationTokenSource, IDisposable
+ {
+ private int _period;
+ private TimerCallback _callback;
+ private object _state;
+
+ internal Timer(TimerCallback callback, object state, int dueTime, int period)
+ {
+ _callback = callback;
+ _state = state;
+ _period = period;
+ Schedule(dueTime);
+ }
+
+ private void Schedule(int dueTime)
+ {
+ Task.Delay(dueTime, Token).ContinueWith(OnTimer, null, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
+ }
+
+ private void OnTimer(Task t, object s)
+ {
+ Schedule(_period);
+ _callback(_state);
+ }
+
+ public new void Dispose() { base.Cancel(); }
+ }
+#endif
+ #endregion // PCL timer hack
+
+ #endregion // Timer Processing
+
+ #region Implementation of the IDisposable interface
+
+ private bool _disposed = false;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ if (disposing)
+ {
+ if (_pollingTimer != null)
+ {
+ _pollingTimer.Dispose();
+ _pollingTimer = null;
+ }
+ }
+
+ _disposed = true;
+ }
+
+ #endregion // Implementation of the IDisposable interface
+ }
+
+ #endregion // internal supporting classes
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventDescriptor.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventDescriptor.cs
index 643bc88623..7df8150e2e 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventDescriptor.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventDescriptor.cs
@@ -72,12 +72,12 @@ namespace System.Diagnostics.Tracing
{
if (id < 0)
{
- throw new ArgumentOutOfRangeException("id", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException("id", Resources.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (id > ushort.MaxValue)
{
- throw new ArgumentOutOfRangeException("id", Environment.GetResourceString("ArgumentOutOfRange_NeedValidId", 1, ushort.MaxValue));
+ throw new ArgumentOutOfRangeException("id", Resources.GetResourceString("ArgumentOutOfRange_NeedValidId", 1, ushort.MaxValue));
}
m_traceloggingId = 0;
@@ -90,19 +90,21 @@ namespace System.Diagnostics.Tracing
if (task < 0)
{
- throw new ArgumentOutOfRangeException("task", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException("task", Resources.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (task > ushort.MaxValue)
{
- throw new ArgumentOutOfRangeException("task", Environment.GetResourceString("ArgumentOutOfRange_NeedValidId", 1, ushort.MaxValue));
+ throw new ArgumentOutOfRangeException("task", Resources.GetResourceString("ArgumentOutOfRange_NeedValidId", 1, ushort.MaxValue));
}
m_task = (ushort)task;
}
- public int EventId {
- get {
+ public int EventId
+ {
+ get
+ {
return m_id;
}
}
@@ -159,7 +161,7 @@ namespace System.Diagnostics.Tracing
public override int GetHashCode()
{
- return m_id ^ m_version ^ m_channel ^ m_level ^ m_opcode ^ m_task ^ (int)m_keywords;
+ return m_id ^ m_version ^ m_channel ^ m_level ^ m_opcode ^ m_task ^ (int)m_keywords;
}
public bool Equals(EventDescriptor other)
@@ -185,6 +187,6 @@ namespace System.Diagnostics.Tracing
public static bool operator !=(EventDescriptor event1, EventDescriptor event2)
{
return !event1.Equals(event2);
- }
+ }
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
index cd5b35ed06..4ffeed3099 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Win32;
+
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
@@ -18,6 +19,12 @@ using Contract = System.Diagnostics.Contracts.Contract;
using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
#endif
+#if ES_BUILD_STANDALONE
+using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
+using EventDescriptor = Microsoft.Diagnostics.Tracing.EventDescriptor;
+#endif
+
+
#if ES_BUILD_AGAINST_DOTNET_V35
using Microsoft.Internal; // for Tuple (can't define alias for open generic types so we "use" the whole namespace)
#endif
@@ -44,7 +51,7 @@ namespace System.Diagnostics.Tracing
/// controller callback)
/// </summary>
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
- internal class EventProvider : IDisposable
+ internal partial class EventProvider : IDisposable
{
// This is the windows EVENT_DATA_DESCRIPTOR structure. We expose it because this is what
// subclasses of EventProvider use when creating efficient (but unsafe) version of
@@ -80,7 +87,9 @@ namespace System.Diagnostics.Tracing
private byte m_level; // Tracing Level
private long m_anyKeywordMask; // Trace Enable Flags
private long m_allKeywordMask; // Match all keyword
+#if ES_SESSION_INFO || FEATURE_ACTIVITYSAMPLING
private List<SessionInfo> m_liveSessions; // current live sessions (Tuple<sessionIdBit, etwSessionId>)
+#endif
private bool m_enabled; // Enabled flag from Trace callback
private Guid m_providerId; // Control Guid
internal bool m_disposed; // when true provider has unregistered
@@ -104,12 +113,12 @@ namespace System.Diagnostics.Tracing
EventTooBig = 2,
NullInput = 3,
TooManyArgs = 4,
- Other = 5,
+ Other = 5,
};
// Because callbacks happen on registration, and we need the callbacks for those setup
// we can't call Register in the constructor.
- //
+ //
// Note that EventProvider should ONLY be used by EventSource. In particular because
// it registers a callback from native code you MUST dispose it BEFORE shutdown, otherwise
// you may get native callbacks during shutdown when we have destroyed the delegate.
@@ -135,40 +144,13 @@ namespace System.Diagnostics.Tracing
uint status;
m_etwCallback = new UnsafeNativeMethods.ManifestEtw.EtwEnableCallback(EtwEnableCallBack);
- status = EventRegister(ref m_providerId, m_etwCallback);
+ status = EventRegister(ref m_providerId, m_etwCallback);
if (status != 0)
{
throw new ArgumentException(Win32Native.GetMessage(unchecked((int)status)));
}
}
- [System.Security.SecurityCritical]
- internal unsafe int SetInformation(
- UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS eventInfoClass,
- void* data,
- int dataSize)
- {
- int status = UnsafeNativeMethods.ManifestEtw.ERROR_NOT_SUPPORTED;
-
- if (!m_setInformationMissing)
- {
- try
- {
- status = UnsafeNativeMethods.ManifestEtw.EventSetInformation(
- m_regHandle,
- eventInfoClass,
- data,
- dataSize);
- }
- catch (TypeLoadException)
- {
- m_setInformationMissing = true;
- }
- }
-
- return status;
- }
-
//
// implement Dispose Pattern to early deregister from ETW insted of waiting for
// the finalizer to call deregistration.
@@ -249,20 +231,16 @@ namespace System.Diagnostics.Tracing
m_regHandle = 0;
}
}
-
- // <SecurityKernel Critical="True" Ring="0">
- // <UsesUnsafeCode Name="Parameter filterData of type: Void*" />
- // <UsesUnsafeCode Name="Parameter callbackContext of type: Void*" />
- // </SecurityKernel>
+
[System.Security.SecurityCritical]
unsafe void EtwEnableCallBack(
- [In] ref System.Guid sourceId,
- [In] int controlCode,
- [In] byte setLevel,
- [In] long anyKeyword,
- [In] long allKeyword,
- [In] UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData,
- [In] void* callbackContext
+ ref System.Guid sourceId,
+ int controlCode,
+ byte setLevel,
+ long anyKeyword,
+ long allKeyword,
+ UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData,
+ void* callbackContext
)
{
// This is an optional callback API. We will therefore ignore any failures that happen as a
@@ -273,6 +251,7 @@ namespace System.Diagnostics.Tracing
ControllerCommand command = ControllerCommand.Update;
IDictionary<string, string> args = null;
bool skipFinalOnControllerCommand = false;
+
if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_ENABLE_PROVIDER)
{
m_enabled = true;
@@ -285,7 +264,7 @@ namespace System.Diagnostics.Tracing
// today we use FEATURE_ACTIVITYSAMPLING to determine if this code is there or not.
// However we put it in the #if so that we don't lose the fact that this feature
// switch is at least partially independent of FEATURE_ACTIVITYSAMPLING
-
+#if ES_SESSION_INFO || FEATURE_ACTIVITYSAMPLING
List<Tuple<SessionInfo, bool>> sessionsChanged = GetSessions();
foreach (var session in sessionsChanged)
{
@@ -326,6 +305,7 @@ namespace System.Diagnostics.Tracing
// execute OnControllerCommand once for every session that has changed.
OnControllerCommand(command, args, (bEnabling ? sessionChanged : -sessionChanged), etwSessionId);
}
+#endif
}
else if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_DISABLE_PROVIDER)
{
@@ -333,7 +313,9 @@ namespace System.Diagnostics.Tracing
m_level = 0;
m_anyKeywordMask = 0;
m_allKeywordMask = 0;
+#if ES_SESSION_INFO || FEATURE_ACTIVITYSAMPLING
m_liveSessions = null;
+#endif
}
else if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_CAPTURE_STATE)
{
@@ -365,6 +347,7 @@ namespace System.Diagnostics.Tracing
return idx;
}
+#if ES_SESSION_INFO || FEATURE_ACTIVITYSAMPLING
/// <summary>
/// Determines the ETW sessions that have been added and/or removed to the set of
/// sessions interested in the current provider. It does so by (1) enumerating over all
@@ -563,6 +546,7 @@ namespace System.Diagnostics.Tracing
return -1;
}
+#endif
/// <summary>
/// Gets any data to be passed from the controller to the provider. It starts with what is passed
@@ -573,14 +557,15 @@ namespace System.Diagnostics.Tracing
/// starts, and the command being issued associated with that data.
/// </summary>
[System.Security.SecurityCritical]
- private unsafe bool GetDataFromController(int etwSessionId,
- UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[] data, out int dataStart)
+ private unsafe bool GetDataFromController(int etwSessionId,
+ UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData,
+ out ControllerCommand command, out byte[] data, out int dataStart)
{
data = null;
dataStart = 0;
if (filterData == null)
{
-#if !ES_BUILD_PCL && !FEATURE_PAL
+#if (!ES_BUILD_PCL && !PROJECTN && !FEATURE_PAL)
string regKey = @"\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + m_providerId + "}";
if (System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)) == 8)
regKey = @"HKEY_LOCAL_MACHINE\Software" + @"\Wow6432Node" + regKey;
@@ -729,7 +714,7 @@ namespace System.Diagnostics.Tracing
--*/
{
- Again:
+ Again:
dataDescriptor->Reserved = 0;
string sRet = data as string;
@@ -1042,7 +1027,7 @@ namespace System.Diagnostics.Tracing
dataRefObj.Add(null);
++refObjIndex;
}
-
+
//
// now fix any string arguments and set the pointer on the data descriptor
//
@@ -1162,7 +1147,7 @@ namespace System.Diagnostics.Tracing
(EventOpcode)eventDescriptor.Opcode == EventOpcode.Start ||
(EventOpcode)eventDescriptor.Opcode == EventOpcode.Stop);
}
-
+
int status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, activityID, childActivityID, dataCount, (EventData*)data);
if (status != 0)
@@ -1182,9 +1167,7 @@ namespace System.Diagnostics.Tracing
int dataCount,
IntPtr data)
{
- int status;
-
- status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(
+ int status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(
m_regHandle,
ref eventDescriptor,
activityID,
@@ -1200,7 +1183,6 @@ namespace System.Diagnostics.Tracing
return true;
}
-
// These are look-alikes to the Manifest based ETW OS APIs that have been shimmed to work
// either with Manifest ETW or Classic ETW (if Manifest based ETW is not available).
[SecurityCritical]
@@ -1210,7 +1192,7 @@ namespace System.Diagnostics.Tracing
m_etwCallback = enableCallback;
return UnsafeNativeMethods.ManifestEtw.EventRegister(ref providerId, enableCallback, null, ref m_regHandle);
}
-
+
[SecurityCritical]
private uint EventUnregister()
{
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
index f6fe526ea5..54bdc41715 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
@@ -187,16 +187,15 @@ using System.Reflection;
using System.Resources;
using System.Security;
using System.Security.Permissions;
+
using System.Text;
using System.Threading;
using Microsoft.Win32;
#if ES_BUILD_STANDALONE
-using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
using EventDescriptor = Microsoft.Diagnostics.Tracing.EventDescriptor;
#else
using System.Threading.Tasks;
-using EventDescriptor = System.Diagnostics.Tracing.EventDescriptor;
#endif
using Microsoft.Reflection;
@@ -428,8 +427,9 @@ namespace System.Diagnostics.Tracing
}
if (name == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeName"), "eventSourceType");
-
+ {
+ throw new ArgumentException(Resources.GetResourceString("Argument_InvalidTypeName"), "eventSourceType");
+ }
return GenerateGuidFromName(name.ToUpperInvariant()); // Make it case insensitive.
}
/// <summary>
@@ -514,115 +514,11 @@ namespace System.Diagnostics.Tracing
// User-defined EventCommands should not conflict with the reserved commands.
if ((int)command <= (int)EventCommand.Update && (int)command != (int)EventCommand.SendManifest)
- throw new ArgumentException(Environment.GetResourceString("EventSource_InvalidCommand"), "command");
-
- eventSource.SendCommand(null, 0, 0, command, true, EventLevel.LogAlways, EventKeywords.None, commandArguments);
- }
-
- // ActivityID support (see also WriteEventWithRelatedActivityIdCore)
- /// <summary>
- /// When a thread starts work that is on behalf of 'something else' (typically another
- /// thread or network request) it should mark the thread as working on that other work.
- /// This API marks the current thread as working on activity 'activityID'. This API
- /// should be used when the caller knows the thread's current activity (the one being
- /// overwritten) has completed. Otherwise, callers should prefer the overload that
- /// return the oldActivityThatWillContinue (below).
- ///
- /// All events created with the EventSource on this thread are also tagged with the
- /// activity ID of the thread.
- ///
- /// It is common, and good practice after setting the thread to an activity to log an event
- /// with a 'start' opcode to indicate that precise time/thread where the new activity
- /// started.
- /// </summary>
- /// <param name="activityId">A Guid that represents the new activity with which to mark
- /// the current thread</param>
- [System.Security.SecuritySafeCritical]
- public static void SetCurrentThreadActivityId(Guid activityId)
- {
-#if FEATURE_MANAGED_ETW
-#if FEATURE_ACTIVITYSAMPLING
- Guid newId = activityId;
-#endif // FEATURE_ACTIVITYSAMPLING
- // We ignore errors to keep with the convention that EventSources do not throw errors.
- // Note we can't access m_throwOnWrites because this is a static method.
- if (UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
- UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID,
- ref activityId) == 0)
{
-#if FEATURE_ACTIVITYSAMPLING
- var activityDying = s_activityDying;
- if (activityDying != null && newId != activityId)
- {
- if (activityId == Guid.Empty)
- {
- activityId = FallbackActivityId;
- }
- // OutputDebugString(string.Format("Activity dying: {0} -> {1}", activityId, newId));
- activityDying(activityId); // This is actually the OLD activity ID.
- }
-#endif // FEATURE_ACTIVITYSAMPLING
+ throw new ArgumentException(Resources.GetResourceString("EventSource_InvalidCommand"), "command");
}
-#endif // FEATURE_MANAGED_ETW
- if (TplEtwProvider.Log != null)
- TplEtwProvider.Log.SetActivityId(activityId);
- }
-
- /// <summary>
- /// When a thread starts work that is on behalf of 'something else' (typically another
- /// thread or network request) it should mark the thread as working on that other work.
- /// This API marks the current thread as working on activity 'activityID'. It returns
- /// whatever activity the thread was previously marked with. There is a convention that
- /// callers can assume that callees restore this activity mark before the callee returns.
- /// To encourage this this API returns the old activity, so that it can be restored later.
- ///
- /// All events created with the EventSource on this thread are also tagged with the
- /// activity ID of the thread.
- ///
- /// It is common, and good practice after setting the thread to an activity to log an event
- /// with a 'start' opcode to indicate that precise time/thread where the new activity
- /// started.
- /// </summary>
- /// <param name="activityId">A Guid that represents the new activity with which to mark
- /// the current thread</param>
- /// <param name="oldActivityThatWillContinue">The Guid that represents the current activity
- /// which will continue at some point in the future, on the current thread</param>
- [System.Security.SecuritySafeCritical]
- public static void SetCurrentThreadActivityId(Guid activityId, out Guid oldActivityThatWillContinue)
- {
- oldActivityThatWillContinue = activityId;
-#if FEATURE_MANAGED_ETW
- // We ignore errors to keep with the convention that EventSources do not throw errors.
- // Note we can't access m_throwOnWrites because this is a static method.
- UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
- UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID,
- ref oldActivityThatWillContinue);
-#endif // FEATURE_MANAGED_ETW
-
- // We don't call the activityDying callback here because the caller has declared that
- // it is not dying.
- if (TplEtwProvider.Log != null)
- TplEtwProvider.Log.SetActivityId(activityId);
- }
- /// <summary>
- /// Retrieves the ETW activity ID associated with the current thread.
- /// </summary>
- public static Guid CurrentThreadActivityId
- {
- [System.Security.SecuritySafeCritical]
- get
- {
- // We ignore errors to keep with the convention that EventSources do not throw
- // errors. Note we can't access m_throwOnWrites because this is a static method.
- Guid retVal = new Guid();
-#if FEATURE_MANAGED_ETW
- UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
- UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_ID,
- ref retVal);
-#endif // FEATURE_MANAGED_ETW
- return retVal;
- }
+ eventSource.SendCommand(null, 0, 0, command, true, EventLevel.LogAlways, EventKeywords.None, commandArguments);
}
#if !ES_BUILD_STANDALONE
@@ -650,9 +546,11 @@ namespace System.Diagnostics.Tracing
get
{
#pragma warning disable 612, 618
+ int threadID = AppDomain.GetCurrentThreadId();
+
// Managed thread IDs are more aggressively re-used than native thread IDs,
// so we'll use the latter...
- return new Guid(unchecked((uint)AppDomain.GetCurrentThreadId()),
+ return new Guid(unchecked((uint)threadID),
unchecked((ushort)s_currentPid), unchecked((ushort)(s_currentPid >> 16)),
0x94, 0x1b, 0x87, 0xd5, 0xa6, 0x5c, 0x36, 0x64);
#pragma warning restore 612, 618
@@ -696,7 +594,10 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// Displays the name and GUID for the eventSource for debugging purposes.
/// </summary>
- public override string ToString() { return Environment.GetResourceString("EventSource_ToString", Name, Guid); }
+ public override string ToString()
+ {
+ return Resources.GetResourceString("EventSource_ToString", Name, Guid);
+ }
/// <summary>
/// Fires when a Command (e.g. Enable) comes from a an EventListener.
@@ -705,11 +606,8 @@ namespace System.Diagnostics.Tracing
{
add
{
- lock (this)
- {
- m_eventCommandExecuted += value;
- }
-
+ m_eventCommandExecuted += value;
+
// If we have an EventHandler<EventCommandEventArgs> attached to the EventSource before the first command arrives
// It should get a chance to handle the deferred commands.
EventCommandEventArgs deferredCommands = m_deferredCommands;
@@ -721,10 +619,7 @@ namespace System.Diagnostics.Tracing
}
remove
{
- lock (this)
- {
- m_eventCommandExecuted -= value;
- }
+ m_eventCommandExecuted -= value;
}
}
@@ -774,10 +669,43 @@ namespace System.Diagnostics.Tracing
protected EventSource(EventSourceSettings settings, params string[] traits)
{
m_config = ValidateSettings(settings);
- var myType = this.GetType();
- Initialize(GetGuid(myType), GetName(myType), traits);
+
+ Guid eventSourceGuid;
+ string eventSourceName;
+
+ EventMetadata[] eventDescriptors;
+ byte[] manifest;
+ GetMetadata(out eventSourceGuid, out eventSourceName, out eventDescriptors, out manifest);
+
+ if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null)
+ {
+ var myType = this.GetType();
+ eventSourceGuid = GetGuid(myType);
+ eventSourceName = GetName(myType);
+ }
+
+ Initialize(eventSourceGuid, eventSourceName, traits);
}
+ internal virtual void GetMetadata(out Guid eventSourceGuid, out string eventSourceName, out EventMetadata[] eventData, out byte[] manifestBytes)
+ {
+ //
+ // In ProjectN subclasses need to override this method, and return the data from their EventSourceAttribute and EventAttribute annotations.
+ // On other architectures it is a no-op.
+ //
+ // eventDescriptors needs to contain one EventDescriptor for each event; the event's ID should be the same as its index in this array.
+ // manifestBytes is a UTF-8 encoding of the ETW manifest for the type.
+ //
+ // This will be implemented by an IL rewriter, so we can't make this method abstract or the initial build of the subclass would fail.
+ //
+ eventSourceGuid = Guid.Empty;
+ eventSourceName = null;
+ eventData = null;
+ manifestBytes = null;
+
+ return;
+ }
+
/// <summary>
/// This method is called when the eventSource is updated by the controller.
/// </summary>
@@ -1222,7 +1150,7 @@ namespace System.Diagnostics.Tracing
{
Contract.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
if (relatedActivityId != null)
- ValidateEventOpcodeForTransfer(ref m_eventData[eventId]);
+ ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name);
#if FEATURE_MANAGED_ETW
if (m_eventData[eventId].EnabledForETW)
@@ -1272,7 +1200,7 @@ namespace System.Diagnostics.Tracing
// mask set to 0x0f so, when all ETW sessions want the event we don't need to
// synthesize a new one
if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
- ThrowEventSourceException();
+ ThrowEventSourceException(m_eventData[eventId].Name);
}
else
{
@@ -1292,7 +1220,7 @@ namespace System.Diagnostics.Tracing
unchecked((long)etwSessions.ToEventKeywords() | origKwd));
if (!m_provider.WriteEvent(ref desc, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
- ThrowEventSourceException();
+ ThrowEventSourceException(m_eventData[eventId].Name);
}
}
else
@@ -1322,7 +1250,7 @@ namespace System.Diagnostics.Tracing
if (!SelfDescribingEvents)
{
if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
- ThrowEventSourceException();
+ ThrowEventSourceException(m_eventData[eventId].Name);
}
else
{
@@ -1356,7 +1284,7 @@ namespace System.Diagnostics.Tracing
if (ex is EventSourceException)
throw;
else
- ThrowEventSourceException(ex);
+ ThrowEventSourceException(m_eventData[eventId].Name, ex);
}
}
}
@@ -1471,8 +1399,10 @@ namespace System.Diagnostics.Tracing
}
}
#endif
+
[SecurityCritical]
private unsafe void WriteEventRaw(
+ string eventName,
ref EventDescriptor eventDescriptor,
Guid* activityID,
Guid* relatedActivityID,
@@ -1482,12 +1412,12 @@ namespace System.Diagnostics.Tracing
#if FEATURE_MANAGED_ETW
if (m_provider == null)
{
- ThrowEventSourceException();
+ ThrowEventSourceException(eventName);
}
else
{
if (!m_provider.WriteEventRaw(ref eventDescriptor, activityID, relatedActivityID, dataCount, data))
- ThrowEventSourceException();
+ ThrowEventSourceException(eventName);
}
#endif // FEATURE_MANAGED_ETW
}
@@ -1519,13 +1449,19 @@ namespace System.Diagnostics.Tracing
{
m_traits = traits;
if (m_traits != null && m_traits.Length % 2 != 0)
- throw new ArgumentException(Environment.GetResourceString("TraitEven"), "traits");
+ {
+ throw new ArgumentException(Resources.GetResourceString("TraitEven"), "traits");
+ }
if (eventSourceGuid == Guid.Empty)
- throw new ArgumentException(Environment.GetResourceString("EventSource_NeedGuid"));
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_NeedGuid"));
+ }
if (eventSourceName == null)
- throw new ArgumentException(Environment.GetResourceString("EventSource_NeedName"));
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_NeedName"));
+ }
m_name = eventSourceName;
m_guid = eventSourceGuid;
@@ -1555,7 +1491,7 @@ namespace System.Diagnostics.Tracing
// Set m_provider, which allows this.
m_provider = provider;
-#if !ES_BUILD_STANDALONE
+#if (!ES_BUILD_STANDALONE && !PROJECTN)
// API available on OS >= Win 8 and patched Win 7.
// Disable only for FrameworkEventSource to avoid recursion inside exception handling.
var osVer = Environment.OSVersion.Version.Major * 10 + Environment.OSVersion.Version.Minor;
@@ -1563,13 +1499,16 @@ namespace System.Diagnostics.Tracing
#endif
{
int setInformationResult;
- fixed (void* providerMetadata = this.providerMetadata)
- {
- setInformationResult = m_provider.SetInformation(
- UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS.SetTraits,
- providerMetadata,
- this.providerMetadata.Length);
- }
+ System.Runtime.InteropServices.GCHandle metadataHandle =
+ System.Runtime.InteropServices.GCHandle.Alloc(this.providerMetadata, System.Runtime.InteropServices.GCHandleType.Pinned);
+ IntPtr providerMetadata = metadataHandle.AddrOfPinnedObject();
+
+ setInformationResult = m_provider.SetInformation(
+ UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS.SetTraits,
+ providerMetadata,
+ (uint)this.providerMetadata.Length);
+
+ metadataHandle.Free();
}
#endif // FEATURE_MANAGED_ETW
@@ -1812,7 +1751,7 @@ namespace System.Diagnostics.Tracing
// advance to next EventData in array
++data;
- Type dataType = m_eventData[eventId].Parameters[parameterId].ParameterType;
+ Type dataType = GetDataType(m_eventData[eventId], parameterId);
Again:
if (dataType == typeof(IntPtr))
@@ -1906,19 +1845,32 @@ namespace System.Diagnostics.Tracing
}
else
{
- if (dataType.IsEnum())
+ if (m_EventSourcePreventRecursion && m_EventSourceInDecodeObject)
{
- dataType = Enum.GetUnderlyingType(dataType);
- goto Again;
+ return null;
}
- // TODO FIX NOW Assuming that it is a string at this point is really likely to be fragile
- // We should do something better.
+ try
+ {
+ m_EventSourceInDecodeObject = true;
- // Everything else is marshaled as a string.
- // ETW strings are NULL-terminated, so marshal everything up to the first
- // null in the string.
- return System.Runtime.InteropServices.Marshal.PtrToStringUni(dataPointer);
+ if (dataType.IsEnum())
+ {
+ dataType = Enum.GetUnderlyingType(dataType);
+ goto Again;
+ }
+
+
+ // Everything else is marshaled as a string.
+ // ETW strings are NULL-terminated, so marshal everything up to the first
+ // null in the string.
+ return System.Runtime.InteropServices.Marshal.PtrToStringUni(dataPointer);
+
+ }
+ finally
+ {
+ m_EventSourceInDecodeObject = false;
+ }
}
}
@@ -1946,7 +1898,7 @@ namespace System.Diagnostics.Tracing
Contract.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
if (childActivityID != null)
{
- ValidateEventOpcodeForTransfer(ref m_eventData[eventId]);
+ ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name);
// If you use WriteEventWithRelatedActivityID you MUST declare the first argument to be a GUID
// with the name 'relatedActivityID, and NOT pass this argument to the WriteEvent method.
@@ -1958,7 +1910,7 @@ namespace System.Diagnostics.Tracing
// which would cause a cryptic IndexOutOfRangeException later if we don't catch it here.
if (!m_eventData[eventId].HasRelatedActivityID)
{
- throw new ArgumentException(Environment.GetResourceString("EventSource_NoRelatedActivityId"));
+ throw new ArgumentException(Resources.GetResourceString("EventSource_NoRelatedActivityId"));
}
}
@@ -2007,7 +1959,7 @@ namespace System.Diagnostics.Tracing
// mask set to 0x0f so, when all ETW sessions want the event we don't need to
// synthesize a new one
if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, childActivityID, args))
- ThrowEventSourceException();
+ ThrowEventSourceException(m_eventData[eventId].Name);
}
else
{
@@ -2024,7 +1976,7 @@ namespace System.Diagnostics.Tracing
unchecked((long)(ulong)etwSessions | origKwd));
if (!m_provider.WriteEvent(ref desc, pActivityId, childActivityID, args))
- ThrowEventSourceException();
+ ThrowEventSourceException(m_eventData[eventId].Name);
}
}
else
@@ -2054,7 +2006,7 @@ namespace System.Diagnostics.Tracing
if (!SelfDescribingEvents)
{
if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, childActivityID, args))
- ThrowEventSourceException();
+ ThrowEventSourceException(m_eventData[eventId].Name);
}
else
{
@@ -2082,7 +2034,7 @@ namespace System.Diagnostics.Tracing
#endif // FEATURE_MANAGED_ETW
if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener)
{
-#if !ES_BUILD_STANDALONE
+#if (!ES_BUILD_STANDALONE && !PROJECTN)
// Maintain old behavior - object identity is preserved
if (AppContextSwitches.PreserveEventListnerObjectIdentity)
{
@@ -2101,7 +2053,7 @@ namespace System.Diagnostics.Tracing
if (ex is EventSourceException)
throw;
else
- ThrowEventSourceException(ex);
+ ThrowEventSourceException(m_eventData[eventId].Name, ex);
}
}
}
@@ -2133,7 +2085,7 @@ namespace System.Diagnostics.Tracing
/// <param name="args"></param>
private void LogEventArgsMismatches(ParameterInfo[] infos, object[] args)
{
-#if !ES_BUILD_PCL
+#if (!ES_BUILD_PCL && !PROJECTN)
// It would be nice to have this on PCL builds, but it would be pointless since there isn't support for
// writing to the debugger log on PCL.
bool typesMatch = args.Length == infos.Length;
@@ -2159,7 +2111,7 @@ namespace System.Diagnostics.Tracing
if (!typesMatch)
{
- System.Diagnostics.Debugger.Log(0, null, Environment.GetResourceString("EventSource_VarArgsParameterMismatch") + "\r\n");
+ System.Diagnostics.Debugger.Log(0, null, Resources.GetResourceString("EventSource_VarArgsParameterMismatch") + "\r\n");
}
#endif //!ES_BUILD_PCL
}
@@ -2167,10 +2119,11 @@ namespace System.Diagnostics.Tracing
[SecurityCritical]
unsafe private void WriteToAllListeners(int eventId, Guid* childActivityID, int eventDataCount, EventSource.EventData* data)
{
- int paramCount = m_eventData[eventId].Parameters.Length;
+ int paramCount = GetParameterCount(m_eventData[eventId]);
+
if (eventDataCount != paramCount)
{
- ReportOutOfBandMessage(Environment.GetResourceString("EventSource_EventParametersMismatch", eventId, eventDataCount, paramCount), true);
+ ReportOutOfBandMessage(Resources.GetResourceString("EventSource_EventParametersMismatch", eventId, eventDataCount, paramCount), true);
paramCount = Math.Min(paramCount, eventDataCount);
}
@@ -2238,7 +2191,7 @@ namespace System.Diagnostics.Tracing
throw new EventSourceException(lastThrownException);
}
}
-
+
[SecuritySafeCritical]
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
private unsafe void WriteEventString(EventLevel level, long keywords, string msgString)
@@ -2443,7 +2396,7 @@ namespace System.Diagnostics.Tracing
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- private void ThrowEventSourceException(Exception innerEx = null)
+ private void ThrowEventSourceException(string eventName, Exception innerEx = null)
{
// If we fail during out of band logging we may end up trying
// to throw another EventSourceException, thus hitting a StackOverflowException.
@@ -2453,31 +2406,37 @@ namespace System.Diagnostics.Tracing
try
{
m_EventSourceExceptionRecurenceCount++;
+
+ string errorPrefix = "EventSourceException";
+ if(eventName != null)
+ {
+ errorPrefix += " while processing event \"" + eventName + "\"";
+ }
// TODO Create variations of EventSourceException that indicate more information using the error code.
switch (EventProvider.GetLastWriteEventError())
{
case EventProvider.WriteEventErrorCode.EventTooBig:
- ReportOutOfBandMessage("EventSourceException: " + Environment.GetResourceString("EventSource_EventTooBig"), true);
- if (ThrowOnEventWriteErrors) throw new EventSourceException(Environment.GetResourceString("EventSource_EventTooBig"), innerEx);
+ ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_EventTooBig"), true);
+ if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_EventTooBig"), innerEx);
break;
case EventProvider.WriteEventErrorCode.NoFreeBuffers:
- ReportOutOfBandMessage("EventSourceException: " + Environment.GetResourceString("EventSource_NoFreeBuffers"), true);
- if (ThrowOnEventWriteErrors) throw new EventSourceException(Environment.GetResourceString("EventSource_NoFreeBuffers"), innerEx);
+ ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_NoFreeBuffers"), true);
+ if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_NoFreeBuffers"), innerEx);
break;
case EventProvider.WriteEventErrorCode.NullInput:
- ReportOutOfBandMessage("EventSourceException: " + Environment.GetResourceString("EventSource_NullInput"), true);
- if (ThrowOnEventWriteErrors) throw new EventSourceException(Environment.GetResourceString("EventSource_NullInput"), innerEx);
+ ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_NullInput"), true);
+ if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_NullInput"), innerEx);
break;
case EventProvider.WriteEventErrorCode.TooManyArgs:
- ReportOutOfBandMessage("EventSourceException: " + Environment.GetResourceString("EventSource_TooManyArgs"), true);
- if (ThrowOnEventWriteErrors) throw new EventSourceException(Environment.GetResourceString("EventSource_TooManyArgs"), innerEx);
+ ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_TooManyArgs"), true);
+ if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_TooManyArgs"), innerEx);
break;
default:
if (innerEx != null)
- ReportOutOfBandMessage("EventSourceException: " + innerEx.GetType() + ":" + innerEx.Message, true);
+ ReportOutOfBandMessage(errorPrefix + ": " + innerEx.GetType() + ":" + innerEx.Message, true);
else
- ReportOutOfBandMessage("EventSourceException", true);
+ ReportOutOfBandMessage(errorPrefix, true);
if (ThrowOnEventWriteErrors) throw new EventSourceException(innerEx);
break;
}
@@ -2488,13 +2447,13 @@ namespace System.Diagnostics.Tracing
}
}
- private void ValidateEventOpcodeForTransfer(ref EventMetadata eventData)
+ private void ValidateEventOpcodeForTransfer(ref EventMetadata eventData, string eventName)
{
if ((EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Send &&
(EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Receive &&
(EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Start)
{
- ThrowEventSourceException();
+ ThrowEventSourceException(eventName);
}
}
@@ -2502,11 +2461,11 @@ namespace System.Diagnostics.Tracing
{
if (opcode == EventOpcode.Info && eventName != null)
{
- if (eventName.EndsWith(s_ActivityStartSuffix))
+ if (eventName.EndsWith(s_ActivityStartSuffix, StringComparison.Ordinal))
{
return EventOpcode.Start;
}
- else if (eventName.EndsWith(s_ActivityStopSuffix))
+ else if (eventName.EndsWith(s_ActivityStopSuffix, StringComparison.Ordinal))
{
return EventOpcode.Stop;
}
@@ -2542,7 +2501,7 @@ namespace System.Diagnostics.Tracing
/// descriptor as well as some stuff we added specifically for EventSource. see the
/// code:m_eventData for where we use this.
/// </summary>
- internal struct EventMetadata
+ internal partial struct EventMetadata
{
public EventDescriptor Descriptor;
public EventTags Tags;
@@ -2563,6 +2522,10 @@ namespace System.Diagnostics.Tracing
public TraceLoggingEventTypes TraceLoggingEventTypes;
public EventActivityOptions ActivityOptions;
+
+#if PROJECTN
+ public EventParameterType[] ParameterTypes;
+#endif
};
// This is the internal entry point that code:EventListeners call when wanting to send a command to a
@@ -2642,7 +2605,9 @@ namespace System.Diagnostics.Tracing
// Find the per-EventSource dispatcher corresponding to registered dispatcher
commandArgs.dispatcher = GetDispatcher(commandArgs.listener);
if (commandArgs.dispatcher == null && commandArgs.listener != null) // dispatcher == null means ETW dispatcher
- throw new ArgumentException(Environment.GetResourceString("EventSource_ListenerNotFound"));
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_ListenerNotFound"));
+ }
if (commandArgs.Arguments == null)
commandArgs.Arguments = new Dictionary<string, string>();
@@ -2720,7 +2685,7 @@ namespace System.Diagnostics.Tracing
if (commandArgs.listener == null && commandArgs.Arguments.Count > 0 && commandArgs.perEventSourceSessionId != sessionIdBit)
{
- throw new ArgumentException(Environment.GetResourceString("EventSource_SessionIdError",
+ throw new ArgumentException(Resources.GetResourceString("EventSource_SessionIdError",
commandArgs.perEventSourceSessionId + SessionMask.SHIFT_SESSION_TO_KEYWORD,
sessionIdBit + SessionMask.SHIFT_SESSION_TO_KEYWORD));
}
@@ -3042,10 +3007,31 @@ namespace System.Diagnostics.Tracing
#endif
if (m_eventData == null)
{
- Contract.Assert(m_rawManifest == null);
- m_rawManifest = CreateManifestAndDescriptors(this.GetType(), Name, this);
- Contract.Assert(m_eventData != null);
+ Guid eventSourceGuid = Guid.Empty;
+ string eventSourceName = null;
+ EventMetadata[] eventData = null;
+ byte[] manifest = null;
+
+ // Try the GetMetadata provided by the ILTransform in ProjectN. The default sets all to null, and in that case we fall back
+ // to the reflection approach.
+ GetMetadata(out eventSourceGuid, out eventSourceName, out eventData, out manifest);
+ if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null || eventData == null || manifest == null)
+ {
+ // GetMetadata failed, so we have to set it via reflection.
+ Contract.Assert(m_rawManifest == null);
+ m_rawManifest = CreateManifestAndDescriptors(this.GetType(), Name, this);
+ Contract.Assert(m_eventData != null);
+
+ }
+ else
+ {
+ // GetMetadata worked, so set the fields as appropriate.
+ m_name = eventSourceName;
+ m_guid = eventSourceGuid;
+ m_eventData = eventData;
+ m_rawManifest = manifest;
+ }
// TODO Enforce singleton pattern
foreach (WeakReference eventSourceRef in EventListener.s_EventSources)
{
@@ -3053,7 +3039,9 @@ namespace System.Diagnostics.Tracing
if (eventSource != null && eventSource.Guid == m_guid && !eventSource.IsDisposed)
{
if (eventSource != this)
- throw new ArgumentException(Environment.GetResourceString("EventSource_EventSourceGuidInUse", m_guid));
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_EventSourceGuidInUse", m_guid));
+ }
}
}
@@ -3104,6 +3092,7 @@ namespace System.Diagnostics.Tracing
envelope.ChunkNumber = 0;
EventProvider.EventData* dataDescrs = stackalloc EventProvider.EventData[2];
+
dataDescrs[0].Ptr = (ulong)&envelope;
dataDescrs[0].Size = (uint)sizeof(ManifestEnvelope);
dataDescrs[0].Reserved = 0;
@@ -3134,7 +3123,7 @@ namespace System.Diagnostics.Tracing
}
success = false;
if (ThrowOnEventWriteErrors)
- ThrowEventSourceException();
+ ThrowEventSourceException("SendManifest");
break;
}
}
@@ -3147,7 +3136,7 @@ namespace System.Diagnostics.Tracing
return success;
}
-#if ES_BUILD_PCL
+#if (ES_BUILD_PCL || PROJECTN)
internal static Attribute GetCustomAttributeHelper(Type type, Type attributeType, EventManifestOptions flags = EventManifestOptions.None)
{
return GetCustomAttributeHelper(type.GetTypeInfo(), attributeType, flags);
@@ -3170,7 +3159,7 @@ namespace System.Diagnostics.Tracing
return firstAttribute;
}
-#if !ES_BUILD_PCL
+#if (!ES_BUILD_PCL && !PROJECTN)
// In the reflection only context, we have to do things by hand.
string fullTypeNameToFind = attributeType.FullName;
@@ -3218,8 +3207,8 @@ namespace System.Diagnostics.Tracing
}
return null;
-#else // ES_BUILD_PCL
- throw new ArgumentException(Environment.GetResourceString("EventSource", "EventSource_PCLPlatformNotSupportedReflection"));
+#else // ES_BUILD_PCL && PROJECTN
+ throw new ArgumentException(Resources.GetResourceString("EventSource", "EventSource_PCLPlatformNotSupportedReflection"));
#endif
}
@@ -3335,9 +3324,13 @@ namespace System.Diagnostics.Tracing
bool typeMatch = GetEventSourceBaseType(eventSourceType, (flags & EventManifestOptions.AllowEventSourceOverride) != 0, eventSourceType.Assembly().ReflectionOnly()) != null;
if (!typeMatch)
- manifest.ManifestError(Environment.GetResourceString("EventSource_TypeMustDeriveFromEventSource"));
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_TypeMustDeriveFromEventSource"));
+ }
if (!eventSourceType.IsAbstract() && !eventSourceType.IsSealed())
- manifest.ManifestError(Environment.GetResourceString("EventSource_TypeMustBeSealedOrAbstract"));
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_TypeMustBeSealedOrAbstract"));
+ }
}
// Collect task, opcode, keyword and channel information
@@ -3352,7 +3345,7 @@ namespace System.Diagnostics.Tracing
{
if (eventSourceType.IsAbstract())
{
- manifest.ManifestError(Environment.GetResourceString("EventSource_AbstractMustNotDeclareKTOC", nestedType.Name));
+ manifest.ManifestError(Resources.GetResourceString("EventSource_AbstractMustNotDeclareKTOC", nestedType.Name));
}
else
{
@@ -3394,7 +3387,9 @@ namespace System.Diagnostics.Tracing
if (eventSourceType.IsAbstract())
{
if (eventAttribute != null)
- manifest.ManifestError(Environment.GetResourceString("EventSource_AbstractMustNotDeclareEventMethods", method.Name, eventAttribute.EventId));
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_AbstractMustNotDeclareEventMethods", method.Name, eventAttribute.EventId));
+ }
continue;
}
else if (eventAttribute == null)
@@ -3422,11 +3417,13 @@ namespace System.Diagnostics.Tracing
}
else if (eventAttribute.EventId <= 0)
{
- manifest.ManifestError(Environment.GetResourceString("EventSource_NeedPositiveId", method.Name), true);
+ manifest.ManifestError(Resources.GetResourceString("EventSource_NeedPositiveId", method.Name), true);
continue; // don't validate anything else for this event
}
if (method.Name.LastIndexOf('.') >= 0)
- manifest.ManifestError(Environment.GetResourceString("EventSource_EventMustNotBeExplicitImplementation", method.Name, eventAttribute.EventId));
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EventMustNotBeExplicitImplementation", method.Name, eventAttribute.EventId));
+ }
eventId++;
string eventName = method.Name;
@@ -3480,7 +3477,9 @@ namespace System.Diagnostics.Tracing
}
}
if (noTask && (flags & EventManifestOptions.Strict) != 0) // Throw an error if we can compatibly.
- throw new ArgumentException(Environment.GetResourceString("EventSource_StopsFollowStarts"));
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_StopsFollowStarts"));
+ }
}
}
}
@@ -3632,7 +3631,7 @@ namespace System.Diagnostics.Tracing
#endif
return;
Error:
- manifest.ManifestError(Environment.GetResourceString("EventSource_EnumKindMismatch", staticField.Name, staticField.FieldType.Name, providerEnumKind));
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EnumKindMismatch", staticField.Name, staticField.FieldType.Name, providerEnumKind));
}
// Helper used by code:CreateManifestAndDescriptors to add a code:EventData descriptor for a method
@@ -3655,9 +3654,9 @@ namespace System.Diagnostics.Tracing
#if FEATURE_MANAGED_ETW_CHANNELS
(byte)eventAttribute.Channel,
#else
- (byte)0,
+ (byte)0,
#endif
- (byte)eventAttribute.Level,
+ (byte)eventAttribute.Level,
(byte)eventAttribute.Opcode,
(int)eventAttribute.Task,
unchecked((long)((ulong)eventAttribute.Keywords | SessionMask.All.ToEventKeywords())));
@@ -3688,7 +3687,7 @@ namespace System.Diagnostics.Tracing
eventData = newValues;
}
}
-
+
// Helper used by code:EventListener.AddEventSource and code:EventListener.EventListener
// when a listener gets attached to a eventSource
internal void AddListener(EventListener listener)
@@ -3714,12 +3713,12 @@ namespace System.Diagnostics.Tracing
int eventArg = GetHelperCallFirstArg(method);
if (eventArg >= 0 && evtId != eventArg)
{
- manifest.ManifestError(Environment.GetResourceString("EventSource_MismatchIdToWriteEvent", evtName, evtId, eventArg), true);
+ manifest.ManifestError(Resources.GetResourceString("EventSource_MismatchIdToWriteEvent", evtName, evtId, eventArg), true);
}
if (evtId < eventData.Length && eventData[evtId].Descriptor.EventId != 0)
{
- manifest.ManifestError(Environment.GetResourceString("EventSource_EventIdReused", evtName, evtId, eventData[evtId].Name), true);
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EventIdReused", evtName, evtId, eventData[evtId].Name), true);
}
// We give a task to things if they don't have one.
@@ -3733,9 +3732,8 @@ namespace System.Diagnostics.Tracing
if (eventData[idx].Descriptor.Task == (int)eventAttribute.Task && eventData[idx].Descriptor.Opcode == (int)eventAttribute.Opcode)
{
- manifest.ManifestError(Environment.GetResourceString("EventSource_TaskOpcodePairReused",
+ manifest.ManifestError(Resources.GetResourceString("EventSource_TaskOpcodePairReused",
evtName, evtId, eventData[idx].Name, idx));
-
// If we are not strict stop on first error. We have had problems with really large providers taking forever. because of many errors.
if ((options & EventManifestOptions.Strict) == 0)
break;
@@ -3758,7 +3756,9 @@ namespace System.Diagnostics.Tracing
failure = true;
}
if (failure)
- manifest.ManifestError(Environment.GetResourceString("EventSource_EventMustHaveTaskIfNonDefaultOpcode", evtName, evtId));
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EventMustHaveTaskIfNonDefaultOpcode", evtName, evtId));
+ }
}
// If we ever want to enforce the rule: MethodName = TaskName + OpcodeName here's how:
@@ -3767,14 +3767,16 @@ namespace System.Diagnostics.Tracing
// taskName & opcodeName could be passed in by the caller which has opTab & taskTab handy
// if (!(((int)eventAttribute.Opcode == 0 && evtName == taskName) || (evtName == taskName+opcodeName)))
// {
- // throw new WarningException(Environment.GetResourceString("EventSource_EventNameDoesNotEqualTaskPlusOpcode"));
+ // throw new WarningException(Resources.GetResourceString("EventSource_EventNameDoesNotEqualTaskPlusOpcode"));
// }
if (eventsByName == null)
eventsByName = new Dictionary<string, string>();
if (eventsByName.ContainsKey(evtName))
- manifest.ManifestError(Environment.GetResourceString("EventSource_EventNameReused", evtName), true);
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EventNameReused", evtName), true);
+ }
eventsByName[evtName] = evtName;
}
@@ -3795,7 +3797,7 @@ namespace System.Diagnostics.Tracing
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Switch statement is clearer than alternatives")]
static private int GetHelperCallFirstArg(MethodInfo method)
{
-#if !ES_BUILD_PCL
+#if (!ES_BUILD_PCL && !PROJECTN)
// Currently searches for the following pattern
//
// ... // CAN ONLY BE THE INSTRUCTIONS BELOW
@@ -3936,9 +3938,9 @@ namespace System.Diagnostics.Tracing
{
try
{
-#if !ES_BUILD_PCL
+#if (!ES_BUILD_PCL && !PROJECTN)
// send message to debugger without delay
- System.Diagnostics.Debugger.Log(0, null, msg + "\r\n");
+ System.Diagnostics.Debugger.Log(0, null, String.Format("EventSource Error: {0}{1}", msg , Environment.NewLine));
#endif
// Send it to all listeners.
@@ -3963,7 +3965,9 @@ namespace System.Diagnostics.Tracing
var evtFormatMask = EventSourceSettings.EtwManifestEventFormat |
EventSourceSettings.EtwSelfDescribingEventFormat;
if ((settings & evtFormatMask) == evtFormatMask)
- throw new ArgumentException(Environment.GetResourceString("EventSource_InvalidEventFormat"), "settings");
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_InvalidEventFormat"), "settings");
+ }
// If you did not explicitly ask for manifest, you get self-describing.
if ((settings & evtFormatMask) == 0)
@@ -4080,6 +4084,9 @@ namespace System.Diagnostics.Tracing
[ThreadStatic]
private static byte m_EventSourceExceptionRecurenceCount = 0; // current recursion count inside ThrowEventSourceException
+ [ThreadStatic]
+ private static bool m_EventSourceInDecodeObject = false;
+
#if FEATURE_MANAGED_ETW_CHANNELS
internal volatile ulong[] m_channelData;
#endif
@@ -4177,7 +4184,7 @@ namespace System.Diagnostics.Tracing
/// created.
/// </para>
/// </summary>
- public abstract class EventListener : IDisposable
+ public class EventListener : IDisposable
{
private event EventHandler<EventSourceCreatedEventArgs> _EventSourceCreated;
@@ -4217,7 +4224,7 @@ namespace System.Diagnostics.Tracing
/// Create a new EventListener in which all events start off turned off (use EnableEvents to turn
/// them on).
/// </summary>
- protected EventListener()
+ public EventListener()
{
// This will cause the OnEventSourceCreated callback to fire.
CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener(this) );
@@ -4409,7 +4416,7 @@ namespace System.Diagnostics.Tracing
if (!s_EventSourceShutdownRegistered)
{
s_EventSourceShutdownRegistered = true;
-#if !ES_BUILD_PCL && !FEATURE_CORECLR
+#if (!ES_BUILD_PCL && !FEATURE_CORECLR && !PROJECTN)
AppDomain.CurrentDomain.ProcessExit += DisposeOnShutdown;
AppDomain.CurrentDomain.DomainUnload += DisposeOnShutdown;
#endif
@@ -4585,7 +4592,9 @@ namespace System.Diagnostics.Tracing
{
// Disallow creating EventListener reentrancy.
if (s_CreatingListener)
- throw new InvalidOperationException(Environment.GetResourceString("EventSource_ListenerCreatedInsideCallback"));
+ {
+ throw new InvalidOperationException(Resources.GetResourceString("EventSource_ListenerCreatedInsideCallback"));
+ }
try
{
@@ -5931,8 +5940,8 @@ namespace System.Diagnostics.Tracing
private uint m_mask;
internal const int SHIFT_SESSION_TO_KEYWORD = 44; // bits 44-47 inclusive are reserved
- internal const uint MASK = 0x0fU; // the mask of 4 reserved bits
- internal const uint MAX = 4; // maximum number of simultaneous ETW sessions supported
+ internal const uint MASK = 0x0fU; // the mask of 4 reserved bits
+ internal const uint MAX = 4; // maximum number of simultaneous ETW sessions supported
}
/// <summary>
@@ -6004,7 +6013,7 @@ namespace System.Diagnostics.Tracing
/// ManifestBuilder is designed to isolate the details of the message of the event from the
/// rest of EventSource. This one happens to create XML.
/// </summary>
- internal class ManifestBuilder
+ internal partial class ManifestBuilder
{
/// <summary>
/// Build a manifest for 'providerName' with the given GUID, which will be packaged into 'dllName'.
@@ -6045,10 +6054,14 @@ namespace System.Diagnostics.Tracing
if ((flags & EventManifestOptions.Strict) != 0)
{
if (value <= 10 || value >= 239)
- ManifestError(Environment.GetResourceString("EventSource_IllegalOpcodeValue", name, value));
+ {
+ ManifestError(Resources.GetResourceString("EventSource_IllegalOpcodeValue", name, value));
+ }
string prevName;
if (opcodeTab.TryGetValue(value, out prevName) && !name.Equals(prevName, StringComparison.Ordinal))
- ManifestError(Environment.GetResourceString("EventSource_OpcodeCollision", name, prevName, value));
+ {
+ ManifestError(Resources.GetResourceString("EventSource_OpcodeCollision", name, prevName, value));
+ }
}
opcodeTab[value] = name;
}
@@ -6057,10 +6070,14 @@ namespace System.Diagnostics.Tracing
if ((flags & EventManifestOptions.Strict) != 0)
{
if (value <= 0 || value >= 65535)
- ManifestError(Environment.GetResourceString("EventSource_IllegalTaskValue", name, value));
+ {
+ ManifestError(Resources.GetResourceString("EventSource_IllegalTaskValue", name, value));
+ }
string prevName;
if (taskTab != null && taskTab.TryGetValue(value, out prevName) && !name.Equals(prevName, StringComparison.Ordinal))
- ManifestError(Environment.GetResourceString("EventSource_TaskCollision", name, prevName, value));
+ {
+ ManifestError(Resources.GetResourceString("EventSource_TaskCollision", name, prevName, value));
+ }
}
if (taskTab == null)
taskTab = new Dictionary<int, string>();
@@ -6069,14 +6086,20 @@ namespace System.Diagnostics.Tracing
public void AddKeyword(string name, ulong value)
{
if ((value & (value - 1)) != 0) // Is it a power of 2?
- ManifestError(Environment.GetResourceString("EventSource_KeywordNeedPowerOfTwo", "0x" + value.ToString("x", CultureInfo.CurrentCulture), name), true);
+ {
+ ManifestError(Resources.GetResourceString("EventSource_KeywordNeedPowerOfTwo", "0x" + value.ToString("x", CultureInfo.CurrentCulture), name), true);
+ }
if ((flags & EventManifestOptions.Strict) != 0)
{
if (value >= 0x0000100000000000UL && !name.StartsWith("Session", StringComparison.Ordinal))
- ManifestError(Environment.GetResourceString("EventSource_IllegalKeywordsValue", name, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
+ {
+ ManifestError(Resources.GetResourceString("EventSource_IllegalKeywordsValue", name, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
+ }
string prevName;
if (keywordTab != null && keywordTab.TryGetValue(value, out prevName) && !name.Equals(prevName, StringComparison.Ordinal))
- ManifestError(Environment.GetResourceString("EventSource_KeywordCollision", name, prevName, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
+ {
+ ManifestError(Resources.GetResourceString("EventSource_KeywordCollision", name, prevName, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
+ }
}
if (keywordTab == null)
keywordTab = new Dictionary<ulong, string>();
@@ -6091,13 +6114,13 @@ namespace System.Diagnostics.Tracing
{
EventChannel chValue = (EventChannel)value;
if (value < (int)EventChannel.Admin || value > 255)
- ManifestError(Environment.GetResourceString("EventSource_EventChannelOutOfRange", name, value));
+ ManifestError(Resources.GetResourceString("EventSource_EventChannelOutOfRange", name, value));
else if (chValue >= EventChannel.Admin && chValue <= EventChannel.Debug &&
channelAttribute != null && EventChannelToChannelType(chValue) != channelAttribute.EventChannelType)
{
// we want to ensure developers do not define EventChannels that conflict with the builtin ones,
// but we want to allow them to override the default ones...
- ManifestError(Environment.GetResourceString("EventSource_ChannelTypeDoesNotMatchEventChannelValue",
+ ManifestError(Resources.GetResourceString("EventSource_ChannelTypeDoesNotMatchEventChannelValue",
name, ((EventChannel)value).ToString()));
}
@@ -6264,7 +6287,7 @@ namespace System.Diagnostics.Tracing
}
if (channelTab.Count == MaxCountChannels)
- ManifestError(Environment.GetResourceString("EventSource_MaxChannelExceeded"));
+ ManifestError(Resources.GetResourceString("EventSource_MaxChannelExceeded"));
ulong channelKeyword;
ChannelInfo info;
@@ -6489,7 +6512,7 @@ namespace System.Diagnostics.Tracing
cultures = new List<CultureInfo>();
cultures.Add(CultureInfo.CurrentUICulture);
}
-#if ES_BUILD_STANDALONE
+#if ES_BUILD_STANDALONE || PROJECTN
var sortedStrings = new List<string>(stringTab.Keys);
sortedStrings.Sort();
#else
@@ -6544,7 +6567,7 @@ namespace System.Diagnostics.Tracing
string prevValue;
if (stringTab.TryGetValue(key, out prevValue) && !prevValue.Equals(value))
{
- ManifestError(Environment.GetResourceString("EventSource_DuplicateStringKey", key), true);
+ ManifestError(Resources.GetResourceString("EventSource_DuplicateStringKey", key), true);
return;
}
@@ -6582,7 +6605,7 @@ namespace System.Diagnostics.Tracing
private static List<CultureInfo> GetSupportedCultures(ResourceManager resources)
{
var cultures = new List<CultureInfo>();
-#if !ES_BUILD_PCL && !FEATURE_CORECLR
+#if !ES_BUILD_PCL && !FEATURE_CORECLR && !PROJECTN
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.SpecificCultures /*| CultureTypes.NeutralCultures*/))
{
if (resources.GetResourceSet(ci, true, false) != null)
@@ -6606,26 +6629,26 @@ namespace System.Diagnostics.Tracing
if (channelTab == null || !channelTab.TryGetValue((int)channel, out info))
{
if (channel < EventChannel.Admin) // || channel > EventChannel.Debug)
- ManifestError(Environment.GetResourceString("EventSource_UndefinedChannel", channel, eventName));
+ ManifestError(Resources.GetResourceString("EventSource_UndefinedChannel", channel, eventName));
// allow channels to be auto-defined. The well known ones get their well known names, and the
// rest get names Channel<N>. This allows users to modify the Manifest if they want more advanced features.
if (channelTab == null)
channelTab = new Dictionary<int, ChannelInfo>(4);
-
+
string channelName = channel.ToString(); // For well know channels this is a nice name, otherwise a number
if (EventChannel.Debug < channel)
channelName = "Channel" + channelName; // Add a 'Channel' prefix for numbers.
AddChannel(channelName, (int)channel, GetDefaultChannelAttribute(channel));
if (!channelTab.TryGetValue((int)channel, out info))
- ManifestError(Environment.GetResourceString("EventSource_UndefinedChannel", channel, eventName));
+ ManifestError(Resources.GetResourceString("EventSource_UndefinedChannel", channel, eventName));
}
// events that specify admin channels *must* have non-null "Message" attributes
if (resources != null && eventMessage == null)
eventMessage = resources.GetString("event_" + eventName, CultureInfo.InvariantCulture);
if (info.Attribs.EventChannelType == EventChannelType.Admin && eventMessage == null)
- ManifestError(Environment.GetResourceString("EventSource_EventWithAdminChannelMustHaveMessage", eventName, info.Name));
+ ManifestError(Resources.GetResourceString("EventSource_EventWithAdminChannelMustHaveMessage", eventName, info.Name));
return info.Name;
}
#endif
@@ -6641,6 +6664,7 @@ namespace System.Diagnostics.Tracing
ret = taskTab[(int)task] = eventName;
return ret;
}
+
private string GetOpcodeName(EventOpcode opcode, string eventName)
{
switch (opcode)
@@ -6672,11 +6696,12 @@ namespace System.Diagnostics.Tracing
string ret;
if (opcodeTab == null || !opcodeTab.TryGetValue((int)opcode, out ret))
{
- ManifestError(Environment.GetResourceString("EventSource_UndefinedOpcode", opcode, eventName), true);
+ ManifestError(Resources.GetResourceString("EventSource_UndefinedOpcode", opcode, eventName), true);
ret = null;
}
return ret;
}
+
private string GetKeywords(ulong keywords, string eventName)
{
string ret = "";
@@ -6694,7 +6719,7 @@ namespace System.Diagnostics.Tracing
}
if (keyword == null)
{
- ManifestError(Environment.GetResourceString("EventSource_UndefinedKeyword", "0x" + bit.ToString("x", CultureInfo.CurrentCulture), eventName), true);
+ ManifestError(Resources.GetResourceString("EventSource_UndefinedKeyword", "0x" + bit.ToString("x", CultureInfo.CurrentCulture), eventName), true);
keyword = string.Empty;
}
if (ret.Length != 0 && keyword.Length != 0)
@@ -6704,6 +6729,7 @@ namespace System.Diagnostics.Tracing
}
return ret;
}
+
private string GetTypeName(Type type)
{
if (type.IsEnum())
@@ -6712,45 +6738,8 @@ namespace System.Diagnostics.Tracing
var typeName = GetTypeName(fields[0].FieldType);
return typeName.Replace("win:Int", "win:UInt"); // ETW requires enums to be unsigned.
}
- switch (type.GetTypeCode())
- {
- case TypeCode.Boolean:
- return "win:Boolean";
- case TypeCode.Byte:
- return "win:UInt8";
- case TypeCode.Char:
- case TypeCode.UInt16:
- return "win:UInt16";
- case TypeCode.UInt32:
- return "win:UInt32";
- case TypeCode.UInt64:
- return "win:UInt64";
- case TypeCode.SByte:
- return "win:Int8";
- case TypeCode.Int16:
- return "win:Int16";
- case TypeCode.Int32:
- return "win:Int32";
- case TypeCode.Int64:
- return "win:Int64";
- case TypeCode.String:
- return "win:UnicodeString";
- case TypeCode.Single:
- return "win:Float";
- case TypeCode.Double:
- return "win:Double";
- case TypeCode.DateTime:
- return "win:FILETIME";
- default:
- if (type == typeof(Guid))
- return "win:GUID";
- else if (type == typeof(IntPtr))
- return "win:Pointer";
- else if ((type.IsArray || type.IsPointer) && type.GetElementType() == typeof(byte))
- return "win:Binary";
- ManifestError(Environment.GetResourceString("EventSource_UnsupportedEventTypeInManifest", type.Name), true);
- return string.Empty;
- }
+
+ return GetTypeNameHelper(type);
}
private static void UpdateStringBuilder(ref StringBuilder stringBuilder, string eventMessage, int startIndex, int count)
@@ -6822,7 +6811,7 @@ namespace System.Diagnostics.Tracing
}
else
{
- ManifestError(Environment.GetResourceString("EventSource_UnsupportedMessageProperty", evtName, eventMessage));
+ ManifestError(Resources.GetResourceString("EventSource_UnsupportedMessageProperty", evtName, eventMessage));
}
}
else if ((chIdx = "&<>'\"\r\n\t".IndexOf(eventMessage[i])) >= 0)
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventSourceException.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventSourceException.cs
index f950c6f702..4e11c802ee 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventSourceException.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventSourceException.cs
@@ -17,7 +17,7 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// Exception that is thrown when an error occurs during EventSource operation.
/// </summary>
-#if !ES_BUILD_PCL
+#if (!ES_BUILD_PCL && !PROJECTN)
[Serializable]
#endif
public class EventSourceException : Exception
@@ -25,7 +25,8 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// Initializes a new instance of the EventSourceException class.
/// </summary>
- public EventSourceException() : base(Environment.GetResourceString("EventSource_ListenerWriteFailure")) { }
+ public EventSourceException() :
+ base(Resources.GetResourceString("EventSource_ListenerWriteFailure")) { }
/// <summary>
/// Initializes a new instance of the EventSourceException class with a specified error message.
@@ -38,13 +39,14 @@ namespace System.Diagnostics.Tracing
/// </summary>
public EventSourceException(string message, Exception innerException) : base(message, innerException) { }
-#if !ES_BUILD_PCL
+#if (!ES_BUILD_PCL && !PROJECTN)
/// <summary>
/// Initializes a new instance of the EventSourceException class with serialized data.
/// </summary>
protected EventSourceException(SerializationInfo info, StreamingContext context) : base(info, context) { }
#endif
- internal EventSourceException(Exception innerException) : base(Environment.GetResourceString("EventSource_ListenerWriteFailure"), innerException) { }
+ internal EventSourceException(Exception innerException) :
+ base(Resources.GetResourceString("EventSource_ListenerWriteFailure"), innerException) { }
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs
new file mode 100644
index 0000000000..43c87529d2
--- /dev/null
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs
@@ -0,0 +1,223 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using Microsoft.Reflection;
+using Microsoft.Win32;
+
+namespace System.Diagnostics.Tracing
+{
+ public partial class EventSource
+ {
+ // ActivityID support (see also WriteEventWithRelatedActivityIdCore)
+ /// <summary>
+ /// When a thread starts work that is on behalf of 'something else' (typically another
+ /// thread or network request) it should mark the thread as working on that other work.
+ /// This API marks the current thread as working on activity 'activityID'. This API
+ /// should be used when the caller knows the thread's current activity (the one being
+ /// overwritten) has completed. Otherwise, callers should prefer the overload that
+ /// return the oldActivityThatWillContinue (below).
+ ///
+ /// All events created with the EventSource on this thread are also tagged with the
+ /// activity ID of the thread.
+ ///
+ /// It is common, and good practice after setting the thread to an activity to log an event
+ /// with a 'start' opcode to indicate that precise time/thread where the new activity
+ /// started.
+ /// </summary>
+ /// <param name="activityId">A Guid that represents the new activity with which to mark
+ /// the current thread</param>
+ [System.Security.SecuritySafeCritical]
+ public static void SetCurrentThreadActivityId(Guid activityId)
+ {
+ if (TplEtwProvider.Log != null)
+ TplEtwProvider.Log.SetActivityId(activityId);
+#if FEATURE_MANAGED_ETW
+#if FEATURE_ACTIVITYSAMPLING
+ Guid newId = activityId;
+#endif // FEATURE_ACTIVITYSAMPLING
+ // We ignore errors to keep with the convention that EventSources do not throw errors.
+ // Note we can't access m_throwOnWrites because this is a static method.
+
+ if (UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
+ UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID,
+ ref activityId) == 0)
+ {
+#if FEATURE_ACTIVITYSAMPLING
+ var activityDying = s_activityDying;
+ if (activityDying != null && newId != activityId)
+ {
+ if (activityId == Guid.Empty)
+ {
+ activityId = FallbackActivityId;
+ }
+ // OutputDebugString(string.Format("Activity dying: {0} -> {1}", activityId, newId));
+ activityDying(activityId); // This is actually the OLD activity ID.
+ }
+#endif // FEATURE_ACTIVITYSAMPLING
+ }
+#endif // FEATURE_MANAGED_ETW
+ }
+
+ /// <summary>
+ /// When a thread starts work that is on behalf of 'something else' (typically another
+ /// thread or network request) it should mark the thread as working on that other work.
+ /// This API marks the current thread as working on activity 'activityID'. It returns
+ /// whatever activity the thread was previously marked with. There is a convention that
+ /// callers can assume that callees restore this activity mark before the callee returns.
+ /// To encourage this this API returns the old activity, so that it can be restored later.
+ ///
+ /// All events created with the EventSource on this thread are also tagged with the
+ /// activity ID of the thread.
+ ///
+ /// It is common, and good practice after setting the thread to an activity to log an event
+ /// with a 'start' opcode to indicate that precise time/thread where the new activity
+ /// started.
+ /// </summary>
+ /// <param name="activityId">A Guid that represents the new activity with which to mark
+ /// the current thread</param>
+ /// <param name="oldActivityThatWillContinue">The Guid that represents the current activity
+ /// which will continue at some point in the future, on the current thread</param>
+ [System.Security.SecuritySafeCritical]
+ public static void SetCurrentThreadActivityId(Guid activityId, out Guid oldActivityThatWillContinue)
+ {
+ oldActivityThatWillContinue = activityId;
+#if FEATURE_MANAGED_ETW
+ // We ignore errors to keep with the convention that EventSources do not throw errors.
+ // Note we can't access m_throwOnWrites because this is a static method.
+
+ UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
+ UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_SET_ID,
+ ref oldActivityThatWillContinue);
+#endif // FEATURE_MANAGED_ETW
+
+ // We don't call the activityDying callback here because the caller has declared that
+ // it is not dying.
+ if (TplEtwProvider.Log != null)
+ TplEtwProvider.Log.SetActivityId(activityId);
+ }
+
+ /// <summary>
+ /// Retrieves the ETW activity ID associated with the current thread.
+ /// </summary>
+ public static Guid CurrentThreadActivityId
+ {
+ [System.Security.SecuritySafeCritical]
+ get
+ {
+ // We ignore errors to keep with the convention that EventSources do not throw
+ // errors. Note we can't access m_throwOnWrites because this is a static method.
+ Guid retVal = new Guid();
+#if FEATURE_MANAGED_ETW
+ UnsafeNativeMethods.ManifestEtw.EventActivityIdControl(
+ UnsafeNativeMethods.ManifestEtw.ActivityControl.EVENT_ACTIVITY_CTRL_GET_ID,
+ ref retVal);
+#endif // FEATURE_MANAGED_ETW
+ return retVal;
+ }
+ }
+
+ private int GetParameterCount(EventMetadata eventData)
+ {
+ return eventData.Parameters.Length;
+ }
+
+ private Type GetDataType(EventMetadata eventData, int parameterId)
+ {
+ return eventData.Parameters[parameterId].ParameterType;
+ }
+
+ private static string GetResourceString(string key, params object[] args)
+ {
+ return Environment.GetResourceString(key, args);
+ }
+
+ private static readonly bool m_EventSourcePreventRecursion = false;
+ }
+
+ internal partial class ManifestBuilder
+ {
+ private string GetTypeNameHelper(Type type)
+ {
+ switch (type.GetTypeCode())
+ {
+ case TypeCode.Boolean:
+ return "win:Boolean";
+ case TypeCode.Byte:
+ return "win:UInt8";
+ case TypeCode.Char:
+ case TypeCode.UInt16:
+ return "win:UInt16";
+ case TypeCode.UInt32:
+ return "win:UInt32";
+ case TypeCode.UInt64:
+ return "win:UInt64";
+ case TypeCode.SByte:
+ return "win:Int8";
+ case TypeCode.Int16:
+ return "win:Int16";
+ case TypeCode.Int32:
+ return "win:Int32";
+ case TypeCode.Int64:
+ return "win:Int64";
+ case TypeCode.String:
+ return "win:UnicodeString";
+ case TypeCode.Single:
+ return "win:Float";
+ case TypeCode.Double:
+ return "win:Double";
+ case TypeCode.DateTime:
+ return "win:FILETIME";
+ default:
+ if (type == typeof(Guid))
+ return "win:GUID";
+ else if (type == typeof(IntPtr))
+ return "win:Pointer";
+ else if ((type.IsArray || type.IsPointer) && type.GetElementType() == typeof(byte))
+ return "win:Binary";
+
+ ManifestError(Environment.GetResourceString("EventSource_UnsupportedEventTypeInManifest", type.Name), true);
+ return string.Empty;
+ }
+ }
+ }
+
+ internal partial class EventProvider
+ {
+ [System.Security.SecurityCritical]
+ internal unsafe int SetInformation(
+ UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS eventInfoClass,
+ IntPtr data,
+ uint dataSize)
+ {
+ int status = UnsafeNativeMethods.ManifestEtw.ERROR_NOT_SUPPORTED;
+
+ if (!m_setInformationMissing)
+ {
+ try
+ {
+ status = UnsafeNativeMethods.ManifestEtw.EventSetInformation(
+ m_regHandle,
+ eventInfoClass,
+ (void *)data,
+ (int)dataSize);
+ }
+ catch (TypeLoadException)
+ {
+ m_setInformationMissing = true;
+ }
+ }
+
+ return status;
+ }
+ }
+
+ internal static class Resources
+ {
+ internal static string GetResourceString(string key, params object[] args)
+ {
+ return Environment.GetResourceString(key, args);
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/StubEnvironment.cs b/src/mscorlib/src/System/Diagnostics/Eventing/StubEnvironment.cs
index a6d10506e7..4768baa744 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/StubEnvironment.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/StubEnvironment.cs
@@ -36,7 +36,7 @@ namespace System.Diagnostics.Tracing.Internal
sargs += ", ";
sargs += arg.ToString();
}
-
+
return key + " (" + sargs + ")";
}
@@ -163,7 +163,7 @@ namespace Microsoft.Reflection
{
using System.Reflection;
-#if ES_BUILD_PCL
+#if (ES_BUILD_PCL || PROJECTN)
[Flags]
public enum BindingFlags
{
@@ -197,14 +197,16 @@ namespace Microsoft.Reflection
#endif
static class ReflectionExtensions
{
-#if !ES_BUILD_PCL
-
+#if (!ES_BUILD_PCL && !PROJECTN)
+
//
// Type extension methods
//
public static bool IsEnum(this Type type) { return type.IsEnum; }
public static bool IsAbstract(this Type type) { return type.IsAbstract; }
public static bool IsSealed(this Type type) { return type.IsSealed; }
+ public static bool IsValueType(this Type type) { return type.IsValueType; }
+ public static bool IsGenericType(this Type type) { return type.IsGenericType; }
public static Type BaseType(this Type type) { return type.BaseType; }
public static Assembly Assembly(this Type type) { return type.Assembly; }
public static TypeCode GetTypeCode(this Type type) { return Type.GetTypeCode(type); }
@@ -219,9 +221,14 @@ namespace Microsoft.Reflection
public static bool IsEnum(this Type type) { return type.GetTypeInfo().IsEnum; }
public static bool IsAbstract(this Type type) { return type.GetTypeInfo().IsAbstract; }
public static bool IsSealed(this Type type) { return type.GetTypeInfo().IsSealed; }
+ public static bool IsValueType(this Type type) { return type.GetTypeInfo().IsValueType; }
+ public static bool IsGenericType(this Type type) { return type.IsConstructedGenericType; }
public static Type BaseType(this Type type) { return type.GetTypeInfo().BaseType; }
public static Assembly Assembly(this Type type) { return type.GetTypeInfo().Assembly; }
-
+ public static IEnumerable<PropertyInfo> GetProperties(this Type type) { return type.GetTypeInfo().DeclaredProperties; }
+ public static MethodInfo GetGetMethod(this PropertyInfo propInfo) { return propInfo.GetMethod; }
+ public static Type[] GetGenericArguments(this Type type) { return type.GenericTypeArguments; }
+
public static MethodInfo[] GetMethods(this Type type, BindingFlags flags)
{
// Minimal implementation to cover only the cases we need
@@ -333,7 +340,7 @@ namespace Microsoft.Reflection
}
// Defining some no-ops in PCL builds
-#if ES_BUILD_PCL
+#if ES_BUILD_PCL || PROJECTN
namespace System.Security
{
class SuppressUnmanagedCodeSecurityAttribute : Attribute { }
@@ -349,4 +356,17 @@ namespace System.Security.Permissions
public bool Unrestricted { get; set; }
}
}
-#endif \ No newline at end of file
+#endif
+
+#if PROJECTN
+namespace System
+{
+ public static class AppDomain
+ {
+ public static int GetCurrentThreadId()
+ {
+ return (int)Interop.mincore.GetCurrentThreadId();
+ }
+ }
+}
+#endif
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ArrayTypeInfo.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ArrayTypeInfo.cs
index ce98e38bf2..88d04e360e 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ArrayTypeInfo.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ArrayTypeInfo.cs
@@ -10,12 +10,12 @@ namespace Microsoft.Diagnostics.Tracing
namespace System.Diagnostics.Tracing
#endif
{
- internal sealed class ArrayTypeInfo<ElementType>
- : TraceLoggingTypeInfo<ElementType[]>
+ internal sealed class ArrayTypeInfo : TraceLoggingTypeInfo
{
- private readonly TraceLoggingTypeInfo<ElementType> elementInfo;
+ private readonly TraceLoggingTypeInfo elementInfo;
- public ArrayTypeInfo(TraceLoggingTypeInfo<ElementType> elementInfo)
+ public ArrayTypeInfo(Type type, TraceLoggingTypeInfo elementInfo)
+ : base(type)
{
this.elementInfo = elementInfo;
}
@@ -30,19 +30,18 @@ namespace System.Diagnostics.Tracing
collector.EndBufferedArray();
}
- public override void WriteData(
- TraceLoggingDataCollector collector,
- ref ElementType[] value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
var bookmark = collector.BeginBufferedArray();
var count = 0;
- if (value != null)
+ Array array = (Array)value.ReferenceValue;
+ if (array != null)
{
- count = value.Length;
- for (int i = 0; i < value.Length; i++)
+ count = array.Length;
+ for (int i = 0; i < array.Length; i++)
{
- this.elementInfo.WriteData(collector, ref value[i]);
+ this.elementInfo.WriteData(collector, elementInfo.PropertyValueFactory(array.GetValue(i)));
}
}
@@ -51,11 +50,11 @@ namespace System.Diagnostics.Tracing
public override object GetData(object value)
{
- var array = (ElementType[])value;
+ var array = (Array)value;
var serializedArray = new object[array.Length];
for (int i = 0; i < array.Length; i++)
{
- serializedArray[i] = this.elementInfo.GetData(array[i]);
+ serializedArray[i] = this.elementInfo.GetData(array.GetValue(i));
}
return serializedArray;
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs
index 238a0d8293..1cbc942cd8 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs
@@ -85,7 +85,7 @@ namespace System.Diagnostics.Tracing
var scratchNew = scratchOld + size;
if (this.scratchEnd < scratchNew)
{
- throw new IndexOutOfRangeException(Environment.GetResourceString("EventSource_AddScalarOutOfRange"));
+ throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_AddScalarOutOfRange"));
}
this.ScalarsBegin();
@@ -272,13 +272,13 @@ namespace System.Diagnostics.Tracing
var pinsTemp = this.pins;
if (this.pinsEnd <= pinsTemp)
{
- throw new IndexOutOfRangeException(Environment.GetResourceString("EventSource_PinArrayOutOfRange"));
+ throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_PinArrayOutOfRange"));
}
var datasTemp = this.datas;
if (this.datasEnd <= datasTemp)
{
- throw new IndexOutOfRangeException(Environment.GetResourceString("EventSource_DataDescriptorsOutOfRange"));
+ throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_DataDescriptorsOutOfRange"));
}
this.pins = pinsTemp + 1;
@@ -296,7 +296,7 @@ namespace System.Diagnostics.Tracing
var datasTemp = this.datas;
if (this.datasEnd <= datasTemp)
{
- throw new IndexOutOfRangeException(Environment.GetResourceString("EventSource_DataDescriptorsOutOfRange"));
+ throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_DataDescriptorsOutOfRange"));
}
datasTemp->m_Ptr = (long)(ulong)(UIntPtr)this.scratch;
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumHelper.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumHelper.cs
index 12e05845e0..095a0cd287 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumHelper.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumHelper.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
+#if EVENTSOURCE_GENERICS
+?using System;
using System.Reflection;
#if ES_BUILD_STANDALONE
@@ -19,27 +19,11 @@ namespace System.Diagnostics.Tracing
/// </typeparam>
internal static class EnumHelper<UnderlyingType>
{
- private delegate UnderlyingType Transformer<ValueType>(ValueType value);
-
- private static readonly MethodInfo IdentityInfo =
- Statics.GetDeclaredStaticMethod(typeof(EnumHelper<UnderlyingType>), "Identity");
-
public static UnderlyingType Cast<ValueType>(ValueType value)
{
- return Caster<ValueType>.Instance(value);
- }
-
- internal static UnderlyingType Identity(UnderlyingType value)
- {
- return value;
- }
-
- private static class Caster<ValueType>
- {
- public static readonly Transformer<ValueType> Instance =
- (Transformer<ValueType>)Statics.CreateDelegate(
- typeof(Transformer<ValueType>),
- IdentityInfo);
+ return (UnderlyingType)(object)value;
}
}
+
}
+#endif
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumerableTypeInfo.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumerableTypeInfo.cs
index af5e60baaf..8f3605eeac 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumerableTypeInfo.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumerableTypeInfo.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
+using System.Collections;
using System.Collections.Generic;
#if ES_BUILD_STANDALONE
@@ -10,13 +11,12 @@ namespace Microsoft.Diagnostics.Tracing
namespace System.Diagnostics.Tracing
#endif
{
- internal sealed class EnumerableTypeInfo<IterableType, ElementType>
- : TraceLoggingTypeInfo<IterableType>
- where IterableType : IEnumerable<ElementType>
+ internal sealed class EnumerableTypeInfo : TraceLoggingTypeInfo
{
- private readonly TraceLoggingTypeInfo<ElementType> elementInfo;
+ private readonly TraceLoggingTypeInfo elementInfo;
- public EnumerableTypeInfo(TraceLoggingTypeInfo<ElementType> elementInfo)
+ public EnumerableTypeInfo(Type type, TraceLoggingTypeInfo elementInfo)
+ : base(type)
{
this.elementInfo = elementInfo;
}
@@ -31,19 +31,17 @@ namespace System.Diagnostics.Tracing
collector.EndBufferedArray();
}
- public override void WriteData(
- TraceLoggingDataCollector collector,
- ref IterableType value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
var bookmark = collector.BeginBufferedArray();
var count = 0;
- if (value != null)
+ IEnumerable enumerable = (IEnumerable)value.ReferenceValue;
+ if (enumerable != null)
{
- foreach (var element in value)
+ foreach (var element in enumerable)
{
- var el = element;
- this.elementInfo.WriteData(collector, ref el);
+ this.elementInfo.WriteData(collector, elementInfo.PropertyValueFactory(element));
count++;
}
}
@@ -53,7 +51,7 @@ namespace System.Diagnostics.Tracing
public override object GetData(object value)
{
- var iterType = (IterableType)value;
+ var iterType = (IEnumerable)value;
List<object> serializedEnumerable = new List<object>();
foreach (var element in iterType)
{
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldFormat.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldFormat.cs
index 409535287e..7e6ed763a7 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldFormat.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldFormat.cs
@@ -24,7 +24,7 @@ namespace System.Diagnostics.Tracing
/// Field should not be displayed.
/// </summary>
NoPrint = 1,
-#endif
+#endif
/// <summary>
/// Field should be formatted as character or string data.
/// Typically applied to 8-bit or 16-bit integers.
@@ -77,7 +77,7 @@ namespace System.Diagnostics.Tracing
/// Field should be formatted as a SOCKADDR. Typically applied to byte[] types.
/// </summary>
SocketAddress = 10,
-#endif
+#endif
/// <summary>
/// Field should be formatted as XML string data. Typically applied to
/// strings or arrays of 8-bit or 16-bit integers.
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs
index 3279a76642..dcaa9fd266 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs
@@ -256,7 +256,7 @@ namespace System.Diagnostics.Tracing
newActivity.startStopOptions.Opcode = EventOpcode.Start;
this.eventSource.Write(eventName, ref newActivity.startStopOptions, ref newActivity.activityId, ref relatedActivityId, ref data);
}
- else
+ else
{
// If we are not active, we don't set the eventName, which basically also turns off the Stop event as well.
newActivity.activityId = this.Id;
@@ -305,11 +305,11 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// If eventName is non-null then we logged a start event
/// </summary>
- private bool StartEventWasFired { get { return eventName != null; }}
+ private bool StartEventWasFired { get { return eventName != null; } }
private readonly EventSource eventSource;
private EventSourceOptions startStopOptions;
- internal Guid activityId;
+ internal Guid activityId;
// internal Guid relatedActivityId;
private State state;
private string eventName;
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs
index b64940ac7a..404b0a7c46 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs
@@ -127,17 +127,17 @@ namespace System.Diagnostics.Tracing
{
if (coreType == (int)TraceLoggingDataType.Nil)
{
- throw new NotSupportedException(Environment.GetResourceString("EventSource_NotSupportedArrayOfNil"));
+ throw new NotSupportedException(Resources.GetResourceString("EventSource_NotSupportedArrayOfNil"));
}
if (coreType == (int)TraceLoggingDataType.Binary)
{
- throw new NotSupportedException(Environment.GetResourceString("EventSource_NotSupportedArrayOfBinary"));
+ throw new NotSupportedException(Resources.GetResourceString("EventSource_NotSupportedArrayOfBinary"));
}
#if !BROKEN_UNTIL_M3
if (coreType == (int)TraceLoggingDataType.Utf16String ||
coreType == (int)TraceLoggingDataType.MbcsString)
{
- throw new NotSupportedException(Environment.GetResourceString("EventSource_NotSupportedArrayOfNullTerminatedString"));
+ throw new NotSupportedException(Resources.GetResourceString("EventSource_NotSupportedArrayOfNullTerminatedString"));
}
#endif
}
@@ -159,7 +159,7 @@ namespace System.Diagnostics.Tracing
this.outType++;
if ((this.outType & Statics.OutTypeMask) == 0)
{
- throw new NotSupportedException(Environment.GetResourceString("EventSource_TooManyFields"));
+ throw new NotSupportedException(Resources.GetResourceString("EventSource_TooManyFields"));
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/InvokeTypeInfo.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/InvokeTypeInfo.cs
index 903114f10d..653f605a17 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/InvokeTypeInfo.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/InvokeTypeInfo.cs
@@ -13,20 +13,20 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// TraceLogging: An implementation of TraceLoggingTypeInfo that works
/// for arbitrary types. It writes all public instance properties of
- /// the type. Implemented using Delegate.CreateDelegate(property.Getter).
+ /// the type.
/// </summary>
/// <typeparam name="ContainerType">
/// Type from which to read values.
/// </typeparam>
- internal sealed class InvokeTypeInfo<ContainerType>
- : TraceLoggingTypeInfo<ContainerType>
+ internal sealed class InvokeTypeInfo : TraceLoggingTypeInfo
{
private readonly PropertyAnalysis[] properties;
- private readonly PropertyAccessor<ContainerType>[] accessors;
public InvokeTypeInfo(
+ Type type,
TypeAnalysis typeAnalysis)
: base(
+ type,
typeAnalysis.name,
typeAnalysis.level,
typeAnalysis.opcode,
@@ -34,14 +34,7 @@ namespace System.Diagnostics.Tracing
typeAnalysis.tags)
{
if (typeAnalysis.properties.Length != 0)
- {
this.properties = typeAnalysis.properties;
- this.accessors = new PropertyAccessor<ContainerType>[this.properties.Length];
- for (int i = 0; i < this.accessors.Length; i++)
- {
- this.accessors[i] = PropertyAccessor<ContainerType>.Create(this.properties[i]);
- }
- }
}
public override void WriteMetadata(
@@ -70,15 +63,13 @@ namespace System.Diagnostics.Tracing
}
}
- public override void WriteData(
- TraceLoggingDataCollector collector,
- ref ContainerType value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
- if (this.accessors != null)
+ if (this.properties != null)
{
- foreach (var accessor in this.accessors)
+ foreach (var property in this.properties)
{
- accessor.Write(collector, ref value);
+ property.typeInfo.WriteData(collector, property.getter(value));
}
}
}
@@ -91,7 +82,7 @@ namespace System.Diagnostics.Tracing
var memebersValues = new List<object>();
for (int i = 0; i < this.properties.Length; i++)
{
- var propertyValue = accessors[i].GetData((ContainerType)value);
+ var propertyValue = properties[i].propertyInfo.GetValue(value);
membersNames.Add(properties[i].name);
memebersValues.Add(properties[i].typeInfo.GetData(propertyValue));
}
@@ -100,18 +91,5 @@ namespace System.Diagnostics.Tracing
return null;
}
-
- public override void WriteObjectData(
- TraceLoggingDataCollector collector,
- object valueObj)
- {
- if (this.accessors != null)
- {
- var value = valueObj == null
- ? default(ContainerType)
- : (ContainerType)valueObj;
- this.WriteData(collector, ref value);
- }
- }
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/NameInfo.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/NameInfo.cs
index acc76078ff..1a428e5d03 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/NameInfo.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/NameInfo.cs
@@ -26,14 +26,14 @@ namespace System.Diagnostics.Tracing
{
for(;;)
{
- int snapshot =lastIdentity;
+ int snapshot = lastIdentity;
int newIdentity = (lastIdentity & ~0xFFFFFF) + eventId;
newIdentity = Math.Max(newIdentity, snapshot); // Should be redundant. as we only create descriptors once.
if (Interlocked.CompareExchange(ref lastIdentity, newIdentity, snapshot) == snapshot)
break;
}
}
-
+
private static int lastIdentity = Statics.TraceLoggingChannel << 24;
internal readonly string name;
internal readonly EventTags tags;
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAccessor.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAccessor.cs
deleted file mode 100644
index 388e0b61c0..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAccessor.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Reflection;
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- /// <summary>
- /// TraceLogging: Each PropertyAccessor instance encapsulates the information
- /// needed to read a particular property from an instance of ContainerType
- /// and write the value to a DataCollector. Used by InvokeTypeInfo.
- /// </summary>
- /// <typeparam name="ContainerType">
- /// The type of the object from which properties are read.
- /// </typeparam>
- internal abstract class PropertyAccessor<ContainerType>
- {
- public abstract void Write(TraceLoggingDataCollector collector, ref ContainerType value);
- public abstract object GetData(ContainerType value);
-
- public static PropertyAccessor<ContainerType> Create(PropertyAnalysis property)
- {
- // Due to current Project N limitations on handling generic instantiations with
- // 2 generic parameters we have to explicitly create the instantiations that we consider
- // important to EventSource performance (we have considered int, long, string for the moment).
- // Everything else is handled by NonGenericPropertyWriter that ends up boxing the container object.
- var retType = property.getterInfo.ReturnType;
- if (!Statics.IsValueType(typeof(ContainerType)))
- {
- if (retType == typeof(int))
- return new ClassPropertyWriter<ContainerType, int>(property);
- else if (retType == typeof(long))
- return new ClassPropertyWriter<ContainerType, long>(property);
- else if (retType == typeof(string))
- return new ClassPropertyWriter<ContainerType, string>(property);
- }
- else
- {
- // Handle the case if it is a struct (DD 1027919)
- }
-
- // Otherwise use the boxing one.
- return new NonGenericProperytWriter<ContainerType>(property);
- }
- }
-
- /// <summary>
- /// The type specific version of the property writers uses generics in a way
- /// that Project N can't handle at the moment. To avoid this we simply
- /// use reflection completely.
- /// </summary>
- internal class NonGenericProperytWriter<ContainerType> : PropertyAccessor<ContainerType>
- {
- public NonGenericProperytWriter(PropertyAnalysis property)
- {
- getterInfo = property.getterInfo;
- typeInfo = property.typeInfo;
- }
-
- public override void Write(TraceLoggingDataCollector collector, ref ContainerType container)
- {
- object value = container == null
- ? null
- : getterInfo.Invoke((object)container, null);
- this.typeInfo.WriteObjectData(collector, value);
- }
-
- public override object GetData(ContainerType container)
- {
- return container == null
- ? default(ValueType)
- : getterInfo.Invoke((object)container, null);
- }
-
- private readonly TraceLoggingTypeInfo typeInfo;
- private readonly MethodInfo getterInfo;
- }
-
- /// <summary>
- /// Implementation of PropertyAccessor for use when ContainerType is a
- /// value type.
- /// </summary>
- /// <typeparam name="ContainerType">The type of the object from which properties are read.</typeparam>
- /// <typeparam name="ValueType">Type of the property being read.</typeparam>
- internal class StructPropertyWriter<ContainerType, ValueType>
- : PropertyAccessor<ContainerType>
- {
- private delegate ValueType Getter(ref ContainerType container);
- private readonly TraceLoggingTypeInfo<ValueType> valueTypeInfo;
- private readonly Getter getter;
-
- public StructPropertyWriter(PropertyAnalysis property)
- {
- this.valueTypeInfo = (TraceLoggingTypeInfo<ValueType>)property.typeInfo;
- this.getter = (Getter)Statics.CreateDelegate(
- typeof(Getter),
- property.getterInfo);
- }
-
- public override void Write(TraceLoggingDataCollector collector, ref ContainerType container)
- {
- var value = container == null
- ? default(ValueType)
- : getter(ref container);
- this.valueTypeInfo.WriteData(collector, ref value);
- }
-
- public override object GetData(ContainerType container)
- {
- return container == null
- ? default(ValueType)
- : getter(ref container);
- }
- }
-
- /// <summary>
- /// Implementation of PropertyAccessor for use when ContainerType is a
- /// reference type.
- /// </summary>
- /// <typeparam name="ContainerType">The type of the object from which properties are read.</typeparam>
- /// <typeparam name="ValueType">Type of the property being read.</typeparam>
- internal class ClassPropertyWriter<ContainerType, ValueType>
- : PropertyAccessor<ContainerType>
- {
- private delegate ValueType Getter(ContainerType container);
- private readonly TraceLoggingTypeInfo<ValueType> valueTypeInfo;
- private readonly Getter getter;
-
- public ClassPropertyWriter(PropertyAnalysis property)
- {
- this.valueTypeInfo = (TraceLoggingTypeInfo<ValueType>)property.typeInfo;
- this.getter = (Getter)Statics.CreateDelegate(
- typeof(Getter),
- property.getterInfo);
- }
-
- public override void Write(TraceLoggingDataCollector collector, ref ContainerType container)
- {
- var value = container == null
- ? default(ValueType)
- : getter(container);
- this.valueTypeInfo.WriteData(collector, ref value);
- }
-
- public override object GetData(ContainerType container)
- {
- return container == null
- ? default(ValueType)
- : getter(container);
- }
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAnalysis.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAnalysis.cs
index 64972d1bfb..4688a9241e 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAnalysis.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAnalysis.cs
@@ -17,18 +17,20 @@ namespace System.Diagnostics.Tracing
internal sealed class PropertyAnalysis
{
internal readonly string name;
- internal readonly MethodInfo getterInfo;
+ internal readonly PropertyInfo propertyInfo;
+ internal readonly Func<PropertyValue, PropertyValue> getter;
internal readonly TraceLoggingTypeInfo typeInfo;
internal readonly EventFieldAttribute fieldAttribute;
public PropertyAnalysis(
string name,
- MethodInfo getterInfo,
+ PropertyInfo propertyInfo,
TraceLoggingTypeInfo typeInfo,
EventFieldAttribute fieldAttribute)
{
this.name = name;
- this.getterInfo = getterInfo;
+ this.propertyInfo = propertyInfo;
+ this.getter = PropertyValue.GetPropertyGetter(propertyInfo);
this.typeInfo = typeInfo;
this.fieldAttribute = fieldAttribute;
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs
new file mode 100644
index 0000000000..0f34d95648
--- /dev/null
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs
@@ -0,0 +1,251 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+#if !ES_BUILD_AGAINST_DOTNET_V35
+using Contract = System.Diagnostics.Contracts.Contract;
+#else
+using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
+#endif
+
+namespace System.Diagnostics.Tracing
+{
+ /// <summary>
+ /// Holds property values of any type. For common value types, we have inline storage so that we don't need
+ /// to box the values. For all other types, we store the value in a single object reference field.
+ ///
+ /// To get the value of a property quickly, use a delegate produced by <see cref="PropertyValue.GetPropertyGetter(PropertyInfo)"/>.
+ /// </summary>
+ internal unsafe struct PropertyValue
+ {
+ /// <summary>
+ /// Union of well-known value types, to avoid boxing those types.
+ /// </summary>
+ [StructLayout(LayoutKind.Explicit)]
+ public struct Scalar
+ {
+ [FieldOffset(0)]
+ public Boolean AsBoolean;
+ [FieldOffset(0)]
+ public Byte AsByte;
+ [FieldOffset(0)]
+ public SByte AsSByte;
+ [FieldOffset(0)]
+ public Char AsChar;
+ [FieldOffset(0)]
+ public Int16 AsInt16;
+ [FieldOffset(0)]
+ public UInt16 AsUInt16;
+ [FieldOffset(0)]
+ public Int32 AsInt32;
+ [FieldOffset(0)]
+ public UInt32 AsUInt32;
+ [FieldOffset(0)]
+ public Int64 AsInt64;
+ [FieldOffset(0)]
+ public UInt64 AsUInt64;
+ [FieldOffset(0)]
+ public IntPtr AsIntPtr;
+ [FieldOffset(0)]
+ public UIntPtr AsUIntPtr;
+ [FieldOffset(0)]
+ public Single AsSingle;
+ [FieldOffset(0)]
+ public Double AsDouble;
+ [FieldOffset(0)]
+ public Guid AsGuid;
+ [FieldOffset(0)]
+ public DateTime AsDateTime;
+ [FieldOffset(0)]
+ public DateTimeOffset AsDateTimeOffset;
+ [FieldOffset(0)]
+ public TimeSpan AsTimeSpan;
+ [FieldOffset(0)]
+ public Decimal AsDecimal;
+ }
+
+ // Anything not covered by the Scalar union gets stored in this reference.
+ readonly object _reference;
+ readonly Scalar _scalar;
+ readonly int _scalarLength;
+
+ private PropertyValue(object value)
+ {
+ _reference = value;
+ _scalar = default(Scalar);
+ _scalarLength = 0;
+ }
+
+ private PropertyValue(Scalar scalar, int scalarLength)
+ {
+ _reference = null;
+ _scalar = scalar;
+ _scalarLength = scalarLength;
+ }
+
+ private PropertyValue(Boolean value) : this(new Scalar() { AsBoolean = value }, sizeof(Boolean)) { }
+ private PropertyValue(Byte value) : this(new Scalar() { AsByte = value }, sizeof(Byte)) { }
+ private PropertyValue(SByte value) : this(new Scalar() { AsSByte = value }, sizeof(SByte)) { }
+ private PropertyValue(Char value) : this(new Scalar() { AsChar = value }, sizeof(Char)) { }
+ private PropertyValue(Int16 value) : this(new Scalar() { AsInt16 = value }, sizeof(Int16)) { }
+ private PropertyValue(UInt16 value) : this(new Scalar() { AsUInt16 = value }, sizeof(UInt16)) { }
+ private PropertyValue(Int32 value) : this(new Scalar() { AsInt32 = value }, sizeof(Int32)) { }
+ private PropertyValue(UInt32 value) : this(new Scalar() { AsUInt32 = value }, sizeof(UInt32)) { }
+ private PropertyValue(Int64 value) : this(new Scalar() { AsInt64 = value }, sizeof(Int64)) { }
+ private PropertyValue(UInt64 value) : this(new Scalar() { AsUInt64 = value }, sizeof(UInt64)) { }
+ private PropertyValue(IntPtr value) : this(new Scalar() { AsIntPtr = value }, sizeof(IntPtr)) { }
+ private PropertyValue(UIntPtr value) : this(new Scalar() { AsUIntPtr = value }, sizeof(UIntPtr)) { }
+ private PropertyValue(Single value) : this(new Scalar() { AsSingle = value }, sizeof(Single)) { }
+ private PropertyValue(Double value) : this(new Scalar() { AsDouble = value }, sizeof(Double)) { }
+ private PropertyValue(Guid value) : this(new Scalar() { AsGuid = value }, sizeof(Guid)) { }
+ private PropertyValue(DateTime value) : this(new Scalar() { AsDateTime = value }, sizeof(DateTime)) { }
+ private PropertyValue(DateTimeOffset value) : this(new Scalar() { AsDateTimeOffset = value }, sizeof(DateTimeOffset)) { }
+ private PropertyValue(TimeSpan value) : this(new Scalar() { AsTimeSpan = value }, sizeof(TimeSpan)) { }
+ private PropertyValue(Decimal value) : this(new Scalar() { AsDecimal = value }, sizeof(Decimal)) { }
+
+ public static Func<object, PropertyValue> GetFactory(Type type)
+ {
+ if (type == typeof(Boolean)) return value => new PropertyValue((Boolean)value);
+ if (type == typeof(Byte)) return value => new PropertyValue((Byte)value);
+ if (type == typeof(SByte)) return value => new PropertyValue((SByte)value);
+ if (type == typeof(Char)) return value => new PropertyValue((Char)value);
+ if (type == typeof(Int16)) return value => new PropertyValue((Int16)value);
+ if (type == typeof(UInt16)) return value => new PropertyValue((UInt16)value);
+ if (type == typeof(Int32)) return value => new PropertyValue((Int32)value);
+ if (type == typeof(UInt32)) return value => new PropertyValue((UInt32)value);
+ if (type == typeof(Int64)) return value => new PropertyValue((Int64)value);
+ if (type == typeof(UInt64)) return value => new PropertyValue((UInt64)value);
+ if (type == typeof(IntPtr)) return value => new PropertyValue((IntPtr)value);
+ if (type == typeof(UIntPtr)) return value => new PropertyValue((UIntPtr)value);
+ if (type == typeof(Single)) return value => new PropertyValue((Single)value);
+ if (type == typeof(Double)) return value => new PropertyValue((Double)value);
+ if (type == typeof(Guid)) return value => new PropertyValue((Guid)value);
+ if (type == typeof(DateTime)) return value => new PropertyValue((DateTime)value);
+ if (type == typeof(DateTimeOffset)) return value => new PropertyValue((DateTimeOffset)value);
+ if (type == typeof(TimeSpan)) return value => new PropertyValue((TimeSpan)value);
+ if (type == typeof(Decimal)) return value => new PropertyValue((Decimal)value);
+
+ return value => new PropertyValue(value);
+ }
+
+
+ public object ReferenceValue
+ {
+ get
+ {
+ Contract.Assert(_scalarLength == 0, "This ReflectedValue refers to an unboxed value type, not a reference type or boxed value type.");
+ return _reference;
+ }
+ }
+
+ public Scalar ScalarValue
+ {
+ get
+ {
+ Contract.Assert(_scalarLength > 0, "This ReflectedValue refers to a reference type or boxed value type, not an unboxed value type");
+ return _scalar;
+ }
+ }
+
+ public int ScalarLength
+ {
+ get
+ {
+ Contract.Assert(_scalarLength > 0, "This ReflectedValue refers to a reference type or boxed value type, not an unboxed value type");
+ return _scalarLength;
+ }
+ }
+
+ /// <summary>
+ /// Gets a delegate that gets the value of a given property.
+ /// </summary>
+ public static Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property)
+ {
+ if (property.DeclaringType.GetTypeInfo().IsValueType)
+ return GetBoxedValueTypePropertyGetter(property);
+ else
+ return GetReferenceTypePropertyGetter(property);
+ }
+
+ /// <summary>
+ /// Gets a delegate that gets the value of a property of a value type. We unfortunately cannot avoid boxing the value type,
+ /// without making this generic over the value type. That would result in a large number of generic instantiations, and furthermore
+ /// does not work correctly on .Net Native (we cannot express the needed instantiations in an rd.xml file). We expect that user-defined
+ /// value types will be rare, and in any case the boxing only happens for events that are actually enabled.
+ /// </summary>
+ private static Func<PropertyValue, PropertyValue> GetBoxedValueTypePropertyGetter(PropertyInfo property)
+ {
+ var type = property.PropertyType;
+
+ if (type.GetTypeInfo().IsEnum)
+ type = Enum.GetUnderlyingType(type);
+
+ var factory = GetFactory(type);
+
+ return container => factory(property.GetValue(container.ReferenceValue));
+ }
+
+ /// <summary>
+ /// For properties of reference types, we use a generic helper class to get the value. This enables us to use MethodInfo.CreateDelegate
+ /// to build a fast getter. We can get away with this on .Net Native, because we really only need one runtime instantiation of the
+ /// generic type, since it's only instantiated over reference types (and thus all instances are shared).
+ /// </summary>
+ /// <param name="property"></param>
+ /// <returns></returns>
+ private static Func<PropertyValue, PropertyValue> GetReferenceTypePropertyGetter(PropertyInfo property)
+ {
+ var helper = (TypeHelper)Activator.CreateInstance(typeof(ReferenceTypeHelper<>).MakeGenericType(property.DeclaringType));
+ return helper.GetPropertyGetter(property);
+ }
+
+ private abstract class TypeHelper
+ {
+ public abstract Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property);
+
+ protected Delegate GetGetMethod(PropertyInfo property, Type propertyType)
+ {
+ return property.GetMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(property.DeclaringType, propertyType));
+ }
+ }
+
+ private sealed class ReferenceTypeHelper<TContainer> : TypeHelper where TContainer : class
+ {
+ public override Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property)
+ {
+ var type = property.PropertyType;
+
+ if (!Statics.IsValueType(type))
+ {
+ var getter = (Func<TContainer, object>)GetGetMethod(property, type);
+ return container => new PropertyValue(getter((TContainer)container.ReferenceValue));
+ }
+ else
+ {
+ if (type.GetTypeInfo().IsEnum)
+ type = Enum.GetUnderlyingType(type);
+
+ if (type == typeof(Boolean)) { var f = (Func<TContainer, Boolean>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(Byte)) { var f = (Func<TContainer, Byte>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(SByte)) { var f = (Func<TContainer, SByte>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(Char)) { var f = (Func<TContainer, Char>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(Int16)) { var f = (Func<TContainer, Int16>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(UInt16)) { var f = (Func<TContainer, UInt16>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(Int32)) { var f = (Func<TContainer, Int32>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(UInt32)) { var f = (Func<TContainer, UInt32>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(Int64)) { var f = (Func<TContainer, Int64>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(UInt64)) { var f = (Func<TContainer, UInt64>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(IntPtr)) { var f = (Func<TContainer, IntPtr>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(UIntPtr)) { var f = (Func<TContainer, UIntPtr>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(Single)) { var f = (Func<TContainer, Single>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(Double)) { var f = (Func<TContainer, Double>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(Guid)) { var f = (Func<TContainer, Guid>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(DateTime)) { var f = (Func<TContainer, DateTime>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(DateTimeOffset)) { var f = (Func<TContainer, DateTimeOffset>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(TimeSpan)) { var f = (Func<TContainer, TimeSpan>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+ if (type == typeof(Decimal)) { var f = (Func<TContainer, Decimal>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
+
+ return container => new PropertyValue(property.GetValue(container.ReferenceValue));
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleEventTypes.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleEventTypes.cs
index 7a613f4293..19e922205e 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleEventTypes.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleEventTypes.cs
@@ -18,30 +18,19 @@ namespace System.Diagnostics.Tracing
/// Type of the top-level payload object. Should be EmptyStruct if the
/// event has no payload.
/// </typeparam>
- internal class SimpleEventTypes<T>
- : TraceLoggingEventTypes
+ internal static class SimpleEventTypes<T>
{
- private static SimpleEventTypes<T> instance;
+ private static TraceLoggingEventTypes instance;
- internal readonly TraceLoggingTypeInfo<T> typeInfo;
-
- private SimpleEventTypes(TraceLoggingTypeInfo<T> typeInfo)
- : base(
- typeInfo.Name,
- typeInfo.Tags,
- new TraceLoggingTypeInfo[] { typeInfo })
- {
- this.typeInfo = typeInfo;
- }
-
- public static SimpleEventTypes<T> Instance
+ public static TraceLoggingEventTypes Instance
{
get { return instance ?? InitInstance(); }
}
- private static SimpleEventTypes<T> InitInstance()
+ private static TraceLoggingEventTypes InitInstance()
{
- var newInstance = new SimpleEventTypes<T>(TraceLoggingTypeInfo<T>.Instance);
+ var info = TraceLoggingTypeInfo.GetInstance(typeof(T), null);
+ var newInstance = new TraceLoggingEventTypes(info.Name, info.Tags, new TraceLoggingTypeInfo[] { info });
Interlocked.CompareExchange(ref instance, newInstance, null);
return instance;
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs
index d262bdba2e..f6b621e960 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs
@@ -3,6 +3,13 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
+
+#if !ES_BUILD_AGAINST_DOTNET_V35
+using Contract = System.Diagnostics.Contracts.Contract;
+#else
+using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
+#endif
#if ES_BUILD_STANDALONE
namespace Microsoft.Diagnostics.Tracing
@@ -10,15 +17,13 @@ namespace Microsoft.Diagnostics.Tracing
namespace System.Diagnostics.Tracing
#endif
{
- #region NullTypeInfo
-
/// <summary>
/// TraceLogging: Type handler for empty or unsupported types.
/// </summary>
- /// <typeparam name="DataType">The type to handle.</typeparam>
- internal sealed class NullTypeInfo<DataType>
- : TraceLoggingTypeInfo<DataType>
+ internal sealed class NullTypeInfo : TraceLoggingTypeInfo
{
+ public NullTypeInfo() : base(typeof(EmptyStruct)) { }
+
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
string name,
@@ -27,7 +32,7 @@ namespace System.Diagnostics.Tracing
collector.AddGroup(name);
}
- public override void WriteData(TraceLoggingDataCollector collector, ref DataType value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
return;
}
@@ -38,792 +43,107 @@ namespace System.Diagnostics.Tracing
}
}
- #endregion
-
- #region Primitive scalars
-
- /// <summary>
- /// TraceLogging: Type handler for Boolean.
- /// </summary>
- internal sealed class BooleanTypeInfo
- : TraceLoggingTypeInfo<Boolean>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format8(format, TraceLoggingDataType.Boolean8));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Boolean value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Byte.
- /// </summary>
- internal sealed class ByteTypeInfo
- : TraceLoggingTypeInfo<Byte>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format8(format, TraceLoggingDataType.UInt8));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Byte value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for SByte.
- /// </summary>
- internal sealed class SByteTypeInfo
- : TraceLoggingTypeInfo<SByte>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format8(format, TraceLoggingDataType.Int8));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref SByte value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Int16.
- /// </summary>
- internal sealed class Int16TypeInfo
- : TraceLoggingTypeInfo<Int16>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format16(format, TraceLoggingDataType.Int16));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Int16 value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for UInt16.
- /// </summary>
- internal sealed class UInt16TypeInfo
- : TraceLoggingTypeInfo<UInt16>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format16(format, TraceLoggingDataType.UInt16));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref UInt16 value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Int32.
- /// </summary>
- internal sealed class Int32TypeInfo
- : TraceLoggingTypeInfo<Int32>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format32(format, TraceLoggingDataType.Int32));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Int32 value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for UInt32.
- /// </summary>
- internal sealed class UInt32TypeInfo
- : TraceLoggingTypeInfo<UInt32>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format32(format, TraceLoggingDataType.UInt32));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref UInt32 value)
- {
- collector.AddScalar(value);
- }
- }
-
/// <summary>
- /// TraceLogging: Type handler for Int64.
+ /// Type handler for simple scalar types.
/// </summary>
- internal sealed class Int64TypeInfo
- : TraceLoggingTypeInfo<Int64>
+ sealed class ScalarTypeInfo : TraceLoggingTypeInfo
{
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format64(format, TraceLoggingDataType.Int64));
- }
+ Func<EventFieldFormat, TraceLoggingDataType, TraceLoggingDataType> formatFunc;
+ TraceLoggingDataType nativeFormat;
- public override void WriteData(TraceLoggingDataCollector collector, ref Int64 value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for UInt64.
- /// </summary>
- internal sealed class UInt64TypeInfo
- : TraceLoggingTypeInfo<UInt64>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
+ private ScalarTypeInfo(
+ Type type,
+ Func<EventFieldFormat, TraceLoggingDataType, TraceLoggingDataType> formatFunc,
+ TraceLoggingDataType nativeFormat)
+ : base(type)
{
- collector.AddScalar(name, Statics.Format64(format, TraceLoggingDataType.UInt64));
+ this.formatFunc = formatFunc;
+ this.nativeFormat = nativeFormat;
}
- public override void WriteData(TraceLoggingDataCollector collector, ref UInt64 value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for IntPtr.
- /// </summary>
- internal sealed class IntPtrTypeInfo
- : TraceLoggingTypeInfo<IntPtr>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.FormatPtr(format, Statics.IntPtrType));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref IntPtr value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for UIntPtr.
- /// </summary>
- internal sealed class UIntPtrTypeInfo
- : TraceLoggingTypeInfo<UIntPtr>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.FormatPtr(format, Statics.UIntPtrType));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref UIntPtr value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Double.
- /// </summary>
- internal sealed class DoubleTypeInfo
- : TraceLoggingTypeInfo<Double>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format64(format, TraceLoggingDataType.Double));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Double value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Single.
- /// </summary>
- internal sealed class SingleTypeInfo
- : TraceLoggingTypeInfo<Single>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format32(format, TraceLoggingDataType.Float));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Single value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Char.
- /// </summary>
- internal sealed class CharTypeInfo
- : TraceLoggingTypeInfo<Char>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
+ public override void WriteMetadata(TraceLoggingMetadataCollector collector, string name, EventFieldFormat format)
{
- collector.AddScalar(name, Statics.Format16(format, TraceLoggingDataType.Char16));
+ collector.AddScalar(name, formatFunc(format, nativeFormat));
}
- public override void WriteData(TraceLoggingDataCollector collector, ref Char value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
collector.AddScalar(value);
}
- }
-
- #endregion
-
- #region Primitive arrays
-
- /// <summary>
- /// TraceLogging: Type handler for Boolean[].
- /// </summary>
- internal sealed class BooleanArrayTypeInfo
- : TraceLoggingTypeInfo<Boolean[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format8(format, TraceLoggingDataType.Boolean8));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Boolean[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Byte[].
- /// </summary>
- internal sealed class ByteArrayTypeInfo
- : TraceLoggingTypeInfo<Byte[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- switch (format)
- {
- default:
- collector.AddBinary(name, Statics.MakeDataType(TraceLoggingDataType.Binary, format));
- break;
- case EventFieldFormat.String:
- collector.AddBinary(name, TraceLoggingDataType.CountedMbcsString);
- break;
- case EventFieldFormat.Xml:
- collector.AddBinary(name, TraceLoggingDataType.CountedMbcsXml);
- break;
- case EventFieldFormat.Json:
- collector.AddBinary(name, TraceLoggingDataType.CountedMbcsJson);
- break;
- case EventFieldFormat.Boolean:
- collector.AddArray(name, TraceLoggingDataType.Boolean8);
- break;
- case EventFieldFormat.Hexadecimal:
- collector.AddArray(name, TraceLoggingDataType.HexInt8);
- break;
-#if false
- case EventSourceFieldFormat.Signed:
- collector.AddArray(name, TraceLoggingDataType.Int8);
- break;
- case EventSourceFieldFormat.Unsigned:
- collector.AddArray(name, TraceLoggingDataType.UInt8);
- break;
-#endif
- }
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Byte[] value)
- {
- collector.AddBinary(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for SByte[].
- /// </summary>
- internal sealed class SByteArrayTypeInfo
- : TraceLoggingTypeInfo<SByte[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format8(format, TraceLoggingDataType.Int8));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref SByte[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Int16[].
- /// </summary>
- internal sealed class Int16ArrayTypeInfo
- : TraceLoggingTypeInfo<Int16[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format16(format, TraceLoggingDataType.Int16));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Int16[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for UInt16[].
- /// </summary>
- internal sealed class UInt16ArrayTypeInfo
- : TraceLoggingTypeInfo<UInt16[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format16(format, TraceLoggingDataType.UInt16));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref UInt16[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Int32[].
- /// </summary>
- internal sealed class Int32ArrayTypeInfo
- : TraceLoggingTypeInfo<Int32[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format32(format, TraceLoggingDataType.Int32));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Int32[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for UInt32[].
- /// </summary>
- internal sealed class UInt32ArrayTypeInfo
- : TraceLoggingTypeInfo<UInt32[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format32(format, TraceLoggingDataType.UInt32));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref UInt32[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Int64[].
- /// </summary>
- internal sealed class Int64ArrayTypeInfo
- : TraceLoggingTypeInfo<Int64[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format64(format, TraceLoggingDataType.Int64));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Int64[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for UInt64[].
- /// </summary>
- internal sealed class UInt64ArrayTypeInfo
- : TraceLoggingTypeInfo<UInt64[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format64(format, TraceLoggingDataType.UInt64));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref UInt64[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for IntPtr[].
- /// </summary>
- internal sealed class IntPtrArrayTypeInfo
- : TraceLoggingTypeInfo<IntPtr[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.FormatPtr(format, Statics.IntPtrType));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref IntPtr[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for UIntPtr[].
- /// </summary>
- internal sealed class UIntPtrArrayTypeInfo
- : TraceLoggingTypeInfo<UIntPtr[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.FormatPtr(format, Statics.UIntPtrType));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref UIntPtr[] value)
- {
- collector.AddArray(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Char[].
- /// </summary>
- internal sealed class CharArrayTypeInfo
- : TraceLoggingTypeInfo<Char[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format16(format, TraceLoggingDataType.Char16));
- }
- public override void WriteData(TraceLoggingDataCollector collector, ref Char[] value)
- {
- collector.AddArray(value);
- }
+ public static TraceLoggingTypeInfo Boolean() { return new ScalarTypeInfo(typeof(Boolean), Statics.Format8, TraceLoggingDataType.Boolean8); }
+ public static TraceLoggingTypeInfo Byte() { return new ScalarTypeInfo(typeof(Byte), Statics.Format8, TraceLoggingDataType.UInt8); }
+ public static TraceLoggingTypeInfo SByte() { return new ScalarTypeInfo(typeof(SByte), Statics.Format8, TraceLoggingDataType.Int8); }
+ public static TraceLoggingTypeInfo Char() { return new ScalarTypeInfo(typeof(Char), Statics.Format16, TraceLoggingDataType.Char16); }
+ public static TraceLoggingTypeInfo Int16() { return new ScalarTypeInfo(typeof(Int16), Statics.Format16, TraceLoggingDataType.Int16); }
+ public static TraceLoggingTypeInfo UInt16() { return new ScalarTypeInfo(typeof(UInt16), Statics.Format16, TraceLoggingDataType.UInt16); }
+ public static TraceLoggingTypeInfo Int32() { return new ScalarTypeInfo(typeof(Int32), Statics.Format32, TraceLoggingDataType.Int32); }
+ public static TraceLoggingTypeInfo UInt32() { return new ScalarTypeInfo(typeof(UInt32), Statics.Format32, TraceLoggingDataType.UInt32); }
+ public static TraceLoggingTypeInfo Int64() { return new ScalarTypeInfo(typeof(Int64), Statics.Format64, TraceLoggingDataType.Int64); }
+ public static TraceLoggingTypeInfo UInt64() { return new ScalarTypeInfo(typeof(UInt64), Statics.Format64, TraceLoggingDataType.UInt64); }
+ public static TraceLoggingTypeInfo IntPtr() { return new ScalarTypeInfo(typeof(IntPtr), Statics.FormatPtr, Statics.IntPtrType); }
+ public static TraceLoggingTypeInfo UIntPtr() { return new ScalarTypeInfo(typeof(UIntPtr), Statics.FormatPtr, Statics.UIntPtrType); }
+ public static TraceLoggingTypeInfo Single() { return new ScalarTypeInfo(typeof(Single), Statics.Format32, TraceLoggingDataType.Float); }
+ public static TraceLoggingTypeInfo Double() { return new ScalarTypeInfo(typeof(Double), Statics.Format64, TraceLoggingDataType.Double); }
+ public static TraceLoggingTypeInfo Guid() { return new ScalarTypeInfo(typeof(Guid), (f, t) => Statics.MakeDataType(TraceLoggingDataType.Guid, f), TraceLoggingDataType.Guid); }
}
- /// <summary>
- /// TraceLogging: Type handler for Double[].
- /// </summary>
- internal sealed class DoubleArrayTypeInfo
- : TraceLoggingTypeInfo<Double[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format64(format, TraceLoggingDataType.Double));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Double[] value)
- {
- collector.AddArray(value);
- }
- }
/// <summary>
- /// TraceLogging: Type handler for Single[].
+ /// Type handler for arrays of scalars
/// </summary>
- internal sealed class SingleArrayTypeInfo
- : TraceLoggingTypeInfo<Single[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.Format32(format, TraceLoggingDataType.Float));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Single[] value)
- {
- collector.AddArray(value);
- }
- }
-
- #endregion
-
- #region Enum scalars
-
- internal sealed class EnumByteTypeInfo<EnumType>
- : TraceLoggingTypeInfo<EnumType>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format8(format, TraceLoggingDataType.UInt8));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref EnumType value)
- {
- collector.AddScalar(EnumHelper<Byte>.Cast(value));
- }
-
- public override object GetData(object value)
- {
- return value;
- }
- }
-
- internal sealed class EnumSByteTypeInfo<EnumType>
- : TraceLoggingTypeInfo<EnumType>
+ internal sealed class ScalarArrayTypeInfo : TraceLoggingTypeInfo
{
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format8(format, TraceLoggingDataType.Int8));
- }
+ Func<EventFieldFormat, TraceLoggingDataType, TraceLoggingDataType> formatFunc;
+ TraceLoggingDataType nativeFormat;
+ int elementSize;
- public override void WriteData(TraceLoggingDataCollector collector, ref EnumType value)
+ private ScalarArrayTypeInfo(
+ Type type,
+ Func<EventFieldFormat, TraceLoggingDataType, TraceLoggingDataType> formatFunc,
+ TraceLoggingDataType nativeFormat,
+ int elementSize)
+ : base(type)
{
- collector.AddScalar(EnumHelper<SByte>.Cast(value));
+ this.formatFunc = formatFunc;
+ this.nativeFormat = nativeFormat;
+ this.elementSize = elementSize;
}
- public override object GetData(object value)
- {
- return value;
- }
- }
-
- internal sealed class EnumInt16TypeInfo<EnumType>
- : TraceLoggingTypeInfo<EnumType>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format16(format, TraceLoggingDataType.Int16));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref EnumType value)
- {
- collector.AddScalar(EnumHelper<Int16>.Cast(value));
- }
-
- public override object GetData(object value)
- {
- return value;
- }
- }
-
- internal sealed class EnumUInt16TypeInfo<EnumType>
- : TraceLoggingTypeInfo<EnumType>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format16(format, TraceLoggingDataType.UInt16));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref EnumType value)
- {
- collector.AddScalar(EnumHelper<UInt16>.Cast(value));
- }
-
- public override object GetData(object value)
- {
- return value;
- }
- }
-
- internal sealed class EnumInt32TypeInfo<EnumType>
- : TraceLoggingTypeInfo<EnumType>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format32(format, TraceLoggingDataType.Int32));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref EnumType value)
- {
- collector.AddScalar(EnumHelper<Int32>.Cast(value));
- }
-
- public override object GetData(object value)
- {
- return value;
- }
- }
-
- internal sealed class EnumUInt32TypeInfo<EnumType>
- : TraceLoggingTypeInfo<EnumType>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format32(format, TraceLoggingDataType.UInt32));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref EnumType value)
- {
- collector.AddScalar(EnumHelper<UInt32>.Cast(value));
- }
-
- public override object GetData(object value)
- {
- return value;
- }
- }
-
- internal sealed class EnumInt64TypeInfo<EnumType>
- : TraceLoggingTypeInfo<EnumType>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.Format64(format, TraceLoggingDataType.Int64));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref EnumType value)
- {
- collector.AddScalar(EnumHelper<Int64>.Cast(value));
- }
-
- public override object GetData(object value)
- {
- return value;
- }
- }
-
- internal sealed class EnumUInt64TypeInfo<EnumType>
- : TraceLoggingTypeInfo<EnumType>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
+ public override void WriteMetadata(TraceLoggingMetadataCollector collector, string name, EventFieldFormat format)
{
- collector.AddScalar(name, Statics.Format64(format, TraceLoggingDataType.UInt64));
+ collector.AddArray(name, formatFunc(format, nativeFormat));
}
- public override void WriteData(TraceLoggingDataCollector collector, ref EnumType value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
- collector.AddScalar(EnumHelper<UInt64>.Cast(value));
+ collector.AddArray(value, elementSize);
}
- public override object GetData(object value)
- {
- return value;
- }
+ public static TraceLoggingTypeInfo Boolean() { return new ScalarArrayTypeInfo(typeof(Boolean[]), Statics.Format8, TraceLoggingDataType.Boolean8, sizeof(Boolean)); }
+ public static TraceLoggingTypeInfo Byte() { return new ScalarArrayTypeInfo(typeof(Byte[]), Statics.Format8, TraceLoggingDataType.UInt8, sizeof(Byte)); }
+ public static TraceLoggingTypeInfo SByte() { return new ScalarArrayTypeInfo(typeof(SByte[]), Statics.Format8, TraceLoggingDataType.Int8, sizeof(SByte)); }
+ public static TraceLoggingTypeInfo Char() { return new ScalarArrayTypeInfo(typeof(Char[]), Statics.Format16, TraceLoggingDataType.Char16, sizeof(Char)); }
+ public static TraceLoggingTypeInfo Int16() { return new ScalarArrayTypeInfo(typeof(Int16[]), Statics.Format16, TraceLoggingDataType.Int16, sizeof(Int16)); }
+ public static TraceLoggingTypeInfo UInt16() { return new ScalarArrayTypeInfo(typeof(UInt16[]), Statics.Format16, TraceLoggingDataType.UInt16, sizeof(UInt16)); }
+ public static TraceLoggingTypeInfo Int32() { return new ScalarArrayTypeInfo(typeof(Int32[]), Statics.Format32, TraceLoggingDataType.Int32, sizeof(Int32)); }
+ public static TraceLoggingTypeInfo UInt32() { return new ScalarArrayTypeInfo(typeof(UInt32[]), Statics.Format32, TraceLoggingDataType.UInt32, sizeof(UInt32)); }
+ public static TraceLoggingTypeInfo Int64() { return new ScalarArrayTypeInfo(typeof(Int64[]), Statics.Format64, TraceLoggingDataType.Int64, sizeof(Int64)); }
+ public static TraceLoggingTypeInfo UInt64() { return new ScalarArrayTypeInfo(typeof(UInt64[]), Statics.Format64, TraceLoggingDataType.UInt64, sizeof(UInt64)); }
+ public static TraceLoggingTypeInfo IntPtr() { return new ScalarArrayTypeInfo(typeof(IntPtr[]), Statics.FormatPtr, Statics.IntPtrType, System.IntPtr.Size); }
+ public static TraceLoggingTypeInfo UIntPtr() { return new ScalarArrayTypeInfo(typeof(UIntPtr[]), Statics.FormatPtr, Statics.UIntPtrType, System.IntPtr.Size); }
+ public static TraceLoggingTypeInfo Single() { return new ScalarArrayTypeInfo(typeof(Single[]), Statics.Format32, TraceLoggingDataType.Float, sizeof(Single)); }
+ public static TraceLoggingTypeInfo Double() { return new ScalarArrayTypeInfo(typeof(Double[]), Statics.Format64, TraceLoggingDataType.Double, sizeof(Double)); }
+ public unsafe static TraceLoggingTypeInfo Guid() { return new ScalarArrayTypeInfo(typeof(Guid), (f, t) => Statics.MakeDataType(TraceLoggingDataType.Guid, f), TraceLoggingDataType.Guid, sizeof(Guid)); }
}
- #endregion
-
- #region Other built-in types
-
/// <summary>
/// TraceLogging: Type handler for String.
/// </summary>
- internal sealed class StringTypeInfo
- : TraceLoggingTypeInfo<String>
+ internal sealed class StringTypeInfo : TraceLoggingTypeInfo
{
+ public StringTypeInfo() : base(typeof(string)) { }
+
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
string name,
@@ -832,67 +152,29 @@ namespace System.Diagnostics.Tracing
collector.AddBinary(name, Statics.MakeDataType(TraceLoggingDataType.CountedUtf16String, format));
}
- public override void WriteData(TraceLoggingDataCollector collector, ref String value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
- collector.AddBinary(value);
+ collector.AddBinary((string)value.ReferenceValue);
}
public override object GetData(object value)
{
- object val = base.GetData(value);
- if (null == val)
- val = "";
-
- return val;
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Guid.
- /// </summary>
- internal sealed class GuidTypeInfo
- : TraceLoggingTypeInfo<Guid>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.Guid, format));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Guid value)
- {
- collector.AddScalar(value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for Guid[].
- /// </summary>
- internal sealed class GuidArrayTypeInfo
- : TraceLoggingTypeInfo<Guid[]>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddArray(name, Statics.MakeDataType(TraceLoggingDataType.Guid, format));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref Guid[] value)
- {
- collector.AddArray(value);
+ if(value == null)
+ {
+ return "";
+ }
+
+ return value;
}
}
/// <summary>
/// TraceLogging: Type handler for DateTime.
/// </summary>
- internal sealed class DateTimeTypeInfo
- : TraceLoggingTypeInfo<DateTime>
+ internal sealed class DateTimeTypeInfo : TraceLoggingTypeInfo
{
+ public DateTimeTypeInfo() : base(typeof(DateTime)) { }
+
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
string name,
@@ -901,9 +183,9 @@ namespace System.Diagnostics.Tracing
collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.FileTime, format));
}
- public override void WriteData(TraceLoggingDataCollector collector, ref DateTime value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
- var ticks = value.Ticks;
+ var ticks = value.ScalarValue.AsDateTime.Ticks;
collector.AddScalar(ticks < 504911232000000000 ? 0 : ticks - 504911232000000000);
}
}
@@ -911,9 +193,10 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// TraceLogging: Type handler for DateTimeOffset.
/// </summary>
- internal sealed class DateTimeOffsetTypeInfo
- : TraceLoggingTypeInfo<DateTimeOffset>
+ internal sealed class DateTimeOffsetTypeInfo : TraceLoggingTypeInfo
{
+ public DateTimeOffsetTypeInfo() : base(typeof(DateTimeOffset)) { }
+
public override void WriteMetadata(TraceLoggingMetadataCollector collector, string name, EventFieldFormat format)
{
var group = collector.AddGroup(name);
@@ -921,20 +204,22 @@ namespace System.Diagnostics.Tracing
group.AddScalar("Offset", TraceLoggingDataType.Int64);
}
- public override void WriteData(TraceLoggingDataCollector collector, ref DateTimeOffset value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
- var ticks = value.Ticks;
+ var dateTimeOffset = value.ScalarValue.AsDateTimeOffset;
+ var ticks = dateTimeOffset.Ticks;
collector.AddScalar(ticks < 504911232000000000 ? 0 : ticks - 504911232000000000);
- collector.AddScalar(value.Offset.Ticks);
+ collector.AddScalar(dateTimeOffset.Offset.Ticks);
}
}
/// <summary>
/// TraceLogging: Type handler for TimeSpan.
/// </summary>
- internal sealed class TimeSpanTypeInfo
- : TraceLoggingTypeInfo<TimeSpan>
+ internal sealed class TimeSpanTypeInfo : TraceLoggingTypeInfo
{
+ public TimeSpanTypeInfo() : base(typeof(TimeSpan)) { }
+
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
string name,
@@ -943,92 +228,50 @@ namespace System.Diagnostics.Tracing
collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.Int64, format));
}
- public override void WriteData(TraceLoggingDataCollector collector, ref TimeSpan value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
- collector.AddScalar(value.Ticks);
+ collector.AddScalar(value.ScalarValue.AsTimeSpan.Ticks);
}
}
/// <summary>
/// TraceLogging: Type handler for Decimal. (Note: not full-fidelity, exposed as Double.)
/// </summary>
- internal sealed class DecimalTypeInfo
- : TraceLoggingTypeInfo<Decimal>
- {
- public override void WriteMetadata(
- TraceLoggingMetadataCollector collector,
- string name,
- EventFieldFormat format)
- {
- collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.Double, format));
- }
-
- public override void WriteData(TraceLoggingDataCollector collector, ref decimal value)
- {
- collector.AddScalar((double)value);
- }
- }
-
- /// <summary>
- /// TraceLogging: Type handler for KeyValuePair.
- /// </summary>
- /// <typeparam name="K">Type of the KeyValuePair's Key property.</typeparam>
- /// <typeparam name="V">Type of the KeyValuePair's Value property.</typeparam>
- internal sealed class KeyValuePairTypeInfo<K, V>
- : TraceLoggingTypeInfo<KeyValuePair<K, V>>
+ internal sealed class DecimalTypeInfo : TraceLoggingTypeInfo
{
- private readonly TraceLoggingTypeInfo<K> keyInfo;
- private readonly TraceLoggingTypeInfo<V> valueInfo;
-
- public KeyValuePairTypeInfo(List<Type> recursionCheck)
- {
- this.keyInfo = TraceLoggingTypeInfo<K>.GetInstance(recursionCheck);
- this.valueInfo = TraceLoggingTypeInfo<V>.GetInstance(recursionCheck);
- }
+ public DecimalTypeInfo() : base(typeof(Decimal)) { }
public override void WriteMetadata(
TraceLoggingMetadataCollector collector,
string name,
EventFieldFormat format)
{
- var group = collector.AddGroup(name);
- this.keyInfo.WriteMetadata(group, "Key", EventFieldFormat.Default);
- this.valueInfo.WriteMetadata(group, "Value", format);
- }
-
- public override void WriteData(
- TraceLoggingDataCollector collector,
- ref KeyValuePair<K, V> value)
- {
- var key = value.Key;
- var val = value.Value;
- this.keyInfo.WriteData(collector, ref key);
- this.valueInfo.WriteData(collector, ref val);
+ collector.AddScalar(name, Statics.MakeDataType(TraceLoggingDataType.Double, format));
}
- public override object GetData(object value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
- var serializedType = new Dictionary<string, object>();
- var keyValuePair = (KeyValuePair<K, V>) value;
- serializedType.Add("Key", this.keyInfo.GetData(keyValuePair.Key));
- serializedType.Add("Value", this.valueInfo.GetData(keyValuePair.Value));
- return serializedType;
+ collector.AddScalar((double)value.ScalarValue.AsDecimal);
}
}
/// <summary>
/// TraceLogging: Type handler for Nullable.
/// </summary>
- /// <typeparam name="T">Type of the Nullable's Value property.</typeparam>
- internal sealed class NullableTypeInfo<T>
- : TraceLoggingTypeInfo<Nullable<T>>
- where T : struct
+ internal sealed class NullableTypeInfo : TraceLoggingTypeInfo
{
- private readonly TraceLoggingTypeInfo<T> valueInfo;
+ private readonly TraceLoggingTypeInfo valueInfo;
+ private readonly Func<PropertyValue, PropertyValue> hasValueGetter;
+ private readonly Func<PropertyValue, PropertyValue> valueGetter;
- public NullableTypeInfo(List<Type> recursionCheck)
+ public NullableTypeInfo(Type type, List<Type> recursionCheck)
+ : base(type)
{
- this.valueInfo = TraceLoggingTypeInfo<T>.GetInstance(recursionCheck);
+ var typeArgs = type.GenericTypeArguments;
+ Contract.Assert(typeArgs.Length == 1);
+ this.valueInfo = TraceLoggingTypeInfo.GetInstance(typeArgs[0], recursionCheck);
+ this.hasValueGetter = PropertyValue.GetPropertyGetter(type.GetTypeInfo().GetDeclaredProperty("HasValue"));
+ this.valueGetter = PropertyValue.GetPropertyGetter(type.GetTypeInfo().GetDeclaredProperty("Value"));
}
public override void WriteMetadata(
@@ -1041,16 +284,12 @@ namespace System.Diagnostics.Tracing
this.valueInfo.WriteMetadata(group, "Value", format);
}
- public override void WriteData(
- TraceLoggingDataCollector collector,
- ref Nullable<T> value)
+ public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
{
- var hasValue = value.HasValue;
+ var hasValue = hasValueGetter(value);
collector.AddScalar(hasValue);
- var val = hasValue ? value.Value : default(T);
- this.valueInfo.WriteData(collector, ref val);
+ var val = hasValue.ScalarValue.AsBoolean ? valueGetter(value) : valueInfo.PropertyValueFactory(Activator.CreateInstance(valueInfo.DataType));
+ this.valueInfo.WriteData(collector, val);
}
}
-
- #endregion
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs
index 8897ae2219..af6a43f811 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs
@@ -7,6 +7,8 @@ using System.Reflection;
using System.Runtime.CompilerServices;
using Encoding = System.Text.Encoding;
+using Microsoft.Reflection;
+
#if ES_BUILD_STANDALONE
using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
namespace Microsoft.Diagnostics.Tracing
@@ -213,7 +215,7 @@ namespace System.Diagnostics.Tracing
return TraceLoggingDataType.Int8;
case EventSourceFieldFormat.Unsigned:
return TraceLoggingDataType.UInt8;
-#endif
+#endif
default:
return MakeDataType(native, format);
}
@@ -343,7 +345,7 @@ namespace System.Diagnostics.Tracing
return IntPtrType;
case EventSourceFieldFormat.Unsigned:
return UIntPtrType;
-#endif
+#endif
default:
return MakeDataType(native, format);
}
@@ -366,52 +368,32 @@ namespace System.Diagnostics.Tracing
public static bool IsValueType(Type type)
{
- bool result;
-#if ES_BUILD_PCL
- result = type.GetTypeInfo().IsValueType;
-#else
- result = type.IsValueType;
-#endif
+ bool result = type.IsValueType();
return result;
}
public static bool IsEnum(Type type)
{
- bool result;
-#if ES_BUILD_PCL
- result = type.GetTypeInfo().IsEnum;
-#else
- result = type.IsEnum;
-#endif
+ bool result = type.IsEnum();
return result;
}
public static IEnumerable<PropertyInfo> GetProperties(Type type)
{
- IEnumerable<PropertyInfo> result;
-#if ES_BUILD_PCL
- result = type.GetRuntimeProperties();
-#else
- result = type.GetProperties();
-#endif
+ IEnumerable<PropertyInfo> result = type.GetProperties();
return result;
}
public static MethodInfo GetGetMethod(PropertyInfo propInfo)
{
- MethodInfo result;
-#if ES_BUILD_PCL
- result = propInfo.GetMethod;
-#else
- result = propInfo.GetGetMethod();
-#endif
+ MethodInfo result = propInfo.GetGetMethod();
return result;
}
public static MethodInfo GetDeclaredStaticMethod(Type declaringType, string name)
{
MethodInfo result;
-#if ES_BUILD_PCL
+#if (ES_BUILD_PCL || PROJECTN)
result = declaringType.GetTypeInfo().GetDeclaredMethod(name);
#else
result = declaringType.GetMethod(
@@ -426,7 +408,7 @@ namespace System.Diagnostics.Tracing
Type attributeType)
{
bool result;
-#if ES_BUILD_PCL
+#if (ES_BUILD_PCL || PROJECTN)
result = propInfo.IsDefined(attributeType);
#else
var attributes = propInfo.GetCustomAttributes(
@@ -441,7 +423,7 @@ namespace System.Diagnostics.Tracing
where AttributeType : Attribute
{
AttributeType result = null;
-#if ES_BUILD_PCL
+#if (ES_BUILD_PCL || PROJECTN)
foreach (var attrib in propInfo.GetCustomAttributes<AttributeType>(false))
{
result = attrib;
@@ -461,7 +443,7 @@ namespace System.Diagnostics.Tracing
where AttributeType : Attribute
{
AttributeType result = null;
-#if ES_BUILD_PCL
+#if (ES_BUILD_PCL || PROJECTN)
foreach (var attrib in type.GetTypeInfo().GetCustomAttributes<AttributeType>(false))
{
result = attrib;
@@ -479,11 +461,7 @@ namespace System.Diagnostics.Tracing
public static Type[] GetGenericArguments(Type type)
{
-#if ES_BUILD_PCL
- return type.GenericTypeArguments;
-#else
return type.GetGenericArguments();
-#endif
}
public static Type FindEnumerableElementType(Type type)
@@ -496,19 +474,19 @@ namespace System.Diagnostics.Tracing
}
else
{
-#if ES_BUILD_PCL
- var ifaceTypes = type.GetTypeInfo().ImplementedInterfaces;
+#if (ES_BUILD_PCL || PROJECTN)
+ var ifaceTypes = type.GetTypeInfo().ImplementedInterfaces;
#else
var ifaceTypes = type.FindInterfaces(IsGenericMatch, typeof(IEnumerable<>));
#endif
foreach (var ifaceType in ifaceTypes)
{
-#if ES_BUILD_PCL
- if (!IsGenericMatch(ifaceType, typeof(IEnumerable<>)))
- {
- continue;
- }
+#if (ES_BUILD_PCL || PROJECTN)
+ if (!IsGenericMatch(ifaceType, typeof(IEnumerable<>)))
+ {
+ continue;
+ }
#endif
if (elementType != null)
@@ -527,19 +505,13 @@ namespace System.Diagnostics.Tracing
public static bool IsGenericMatch(Type type, object openType)
{
- bool isGeneric;
-#if ES_BUILD_PCL
- isGeneric = type.IsConstructedGenericType;
-#else
- isGeneric = type.IsGenericType;
-#endif
- return isGeneric && type.GetGenericTypeDefinition() == (Type)openType;
+ return type.IsGenericType() && type.GetGenericTypeDefinition() == (Type)openType;
}
public static Delegate CreateDelegate(Type delegateType, MethodInfo methodInfo)
{
Delegate result;
-#if ES_BUILD_PCL
+#if (ES_BUILD_PCL || PROJECTN)
result = methodInfo.CreateDelegate(
delegateType);
#else
@@ -550,279 +522,203 @@ namespace System.Diagnostics.Tracing
return result;
}
- public static TraceLoggingTypeInfo GetTypeInfoInstance(Type dataType, List<Type> recursionCheck)
- {
- TraceLoggingTypeInfo result;
-
- if (dataType == typeof(Int32))
- {
- result = TraceLoggingTypeInfo<Int32>.Instance;
- }
- else if (dataType == typeof(Int64))
- {
- result = TraceLoggingTypeInfo<Int64>.Instance;
- }
- else if (dataType == typeof(String))
- {
- result = TraceLoggingTypeInfo<String>.Instance;
- }
- else
- {
- var getInstanceInfo = Statics.GetDeclaredStaticMethod(
- typeof(TraceLoggingTypeInfo<>).MakeGenericType(dataType),
- "GetInstance");
- var typeInfoObj = getInstanceInfo.Invoke(null, new object[] { recursionCheck });
- result = (TraceLoggingTypeInfo)typeInfoObj;
- }
-
- return result;
- }
-
- public static TraceLoggingTypeInfo<DataType> CreateDefaultTypeInfo<DataType>(
+ public static TraceLoggingTypeInfo CreateDefaultTypeInfo(
+ Type dataType,
List<Type> recursionCheck)
{
TraceLoggingTypeInfo result;
- var dataType = typeof(DataType);
if (recursionCheck.Contains(dataType))
{
- throw new NotSupportedException(Environment.GetResourceString("EventSource_RecursiveTypeDefinition"));
+ throw new NotSupportedException(Resources.GetResourceString("EventSource_RecursiveTypeDefinition"));
}
recursionCheck.Add(dataType);
var eventAttrib = Statics.GetCustomAttribute<EventDataAttribute>(dataType);
if (eventAttrib != null ||
- Statics.GetCustomAttribute<CompilerGeneratedAttribute>(dataType) != null)
+ Statics.GetCustomAttribute<CompilerGeneratedAttribute>(dataType) != null ||
+ IsGenericMatch(dataType, typeof(KeyValuePair<,>)))
{
var analysis = new TypeAnalysis(dataType, eventAttrib, recursionCheck);
- result = new InvokeTypeInfo<DataType>(analysis);
+ result = new InvokeTypeInfo(dataType, analysis);
}
else if (dataType.IsArray)
{
var elementType = dataType.GetElementType();
if (elementType == typeof(Boolean))
{
- result = new BooleanArrayTypeInfo();
+ result = ScalarArrayTypeInfo.Boolean();
}
else if (elementType == typeof(Byte))
{
- result = new ByteArrayTypeInfo();
+ result = ScalarArrayTypeInfo.Byte();
}
else if (elementType == typeof(SByte))
{
- result = new SByteArrayTypeInfo();
+ result = ScalarArrayTypeInfo.SByte();
}
else if (elementType == typeof(Int16))
{
- result = new Int16ArrayTypeInfo();
+ result = ScalarArrayTypeInfo.Int16();
}
else if (elementType == typeof(UInt16))
{
- result = new UInt16ArrayTypeInfo();
+ result = ScalarArrayTypeInfo.UInt16();
}
else if (elementType == typeof(Int32))
{
- result = new Int32ArrayTypeInfo();
+ result = ScalarArrayTypeInfo.Int32();
}
else if (elementType == typeof(UInt32))
{
- result = new UInt32ArrayTypeInfo();
+ result = ScalarArrayTypeInfo.UInt32();
}
else if (elementType == typeof(Int64))
{
- result = new Int64ArrayTypeInfo();
+ result = ScalarArrayTypeInfo.Int64();
}
else if (elementType == typeof(UInt64))
{
- result = new UInt64ArrayTypeInfo();
+ result = ScalarArrayTypeInfo.UInt64();
}
else if (elementType == typeof(Char))
{
- result = new CharArrayTypeInfo();
+ result = ScalarArrayTypeInfo.Char();
}
else if (elementType == typeof(Double))
{
- result = new DoubleArrayTypeInfo();
+ result = ScalarArrayTypeInfo.Double();
}
else if (elementType == typeof(Single))
{
- result = new SingleArrayTypeInfo();
+ result = ScalarArrayTypeInfo.Single();
}
else if (elementType == typeof(IntPtr))
{
- result = new IntPtrArrayTypeInfo();
+ result = ScalarArrayTypeInfo.IntPtr();
}
else if (elementType == typeof(UIntPtr))
{
- result = new UIntPtrArrayTypeInfo();
+ result = ScalarArrayTypeInfo.UIntPtr();
}
else if (elementType == typeof(Guid))
{
- result = new GuidArrayTypeInfo();
+ result = ScalarArrayTypeInfo.Guid();
}
else
{
- result = (TraceLoggingTypeInfo<DataType>)CreateInstance(
- typeof(ArrayTypeInfo<>).MakeGenericType(elementType),
- GetTypeInfoInstance(elementType, recursionCheck));
+ result = new ArrayTypeInfo(dataType, TraceLoggingTypeInfo.GetInstance(elementType, recursionCheck));
}
}
- else if (Statics.IsEnum(dataType))
+ else
{
- var underlyingType = Enum.GetUnderlyingType(dataType);
- if (underlyingType == typeof(Int32))
+ if (Statics.IsEnum(dataType))
+ dataType = Enum.GetUnderlyingType(dataType);
+
+ if (dataType == typeof(String))
{
- result = new EnumInt32TypeInfo<DataType>();
+ result = new StringTypeInfo();
}
- else if (underlyingType == typeof(UInt32))
+ else if (dataType == typeof(Boolean))
{
- result = new EnumUInt32TypeInfo<DataType>();
+ result = ScalarTypeInfo.Boolean();
}
- else if (underlyingType == typeof(Byte))
+ else if (dataType == typeof(Byte))
{
- result = new EnumByteTypeInfo<DataType>();
+ result = ScalarTypeInfo.Byte();
}
- else if (underlyingType == typeof(SByte))
+ else if (dataType == typeof(SByte))
{
- result = new EnumSByteTypeInfo<DataType>();
+ result = ScalarTypeInfo.SByte();
}
- else if (underlyingType == typeof(Int16))
+ else if (dataType == typeof(Int16))
{
- result = new EnumInt16TypeInfo<DataType>();
+ result = ScalarTypeInfo.Int16();
}
- else if (underlyingType == typeof(UInt16))
+ else if (dataType == typeof(UInt16))
{
- result = new EnumUInt16TypeInfo<DataType>();
+ result = ScalarTypeInfo.UInt16();
}
- else if (underlyingType == typeof(Int64))
+ else if (dataType == typeof(Int32))
{
- result = new EnumInt64TypeInfo<DataType>();
+ result = ScalarTypeInfo.Int32();
}
- else if (underlyingType == typeof(UInt64))
+ else if (dataType == typeof(UInt32))
{
- result = new EnumUInt64TypeInfo<DataType>();
+ result = ScalarTypeInfo.UInt32();
}
- else
+ else if (dataType == typeof(Int64))
{
- // Unexpected
- throw new NotSupportedException(Environment.GetResourceString("EventSource_NotSupportedEnumType", dataType.Name, underlyingType.Name));
+ result = ScalarTypeInfo.Int64();
}
- }
- else if (dataType == typeof(String))
- {
- result = new StringTypeInfo();
- }
- else if (dataType == typeof(Boolean))
- {
- result = new BooleanTypeInfo();
- }
- else if (dataType == typeof(Byte))
- {
- result = new ByteTypeInfo();
- }
- else if (dataType == typeof(SByte))
- {
- result = new SByteTypeInfo();
- }
- else if (dataType == typeof(Int16))
- {
- result = new Int16TypeInfo();
- }
- else if (dataType == typeof(UInt16))
- {
- result = new UInt16TypeInfo();
- }
- else if (dataType == typeof(Int32))
- {
- result = new Int32TypeInfo();
- }
- else if (dataType == typeof(UInt32))
- {
- result = new UInt32TypeInfo();
- }
- else if (dataType == typeof(Int64))
- {
- result = new Int64TypeInfo();
- }
- else if (dataType == typeof(UInt64))
- {
- result = new UInt64TypeInfo();
- }
- else if (dataType == typeof(Char))
- {
- result = new CharTypeInfo();
- }
- else if (dataType == typeof(Double))
- {
- result = new DoubleTypeInfo();
- }
- else if (dataType == typeof(Single))
- {
- result = new SingleTypeInfo();
- }
- else if (dataType == typeof(DateTime))
- {
- result = new DateTimeTypeInfo();
- }
- else if (dataType == typeof(Decimal))
- {
- result = new DecimalTypeInfo();
- }
- else if (dataType == typeof(IntPtr))
- {
- result = new IntPtrTypeInfo();
- }
- else if (dataType == typeof(UIntPtr))
- {
- result = new UIntPtrTypeInfo();
- }
- else if (dataType == typeof(Guid))
- {
- result = new GuidTypeInfo();
- }
- else if (dataType == typeof(TimeSpan))
- {
- result = new TimeSpanTypeInfo();
- }
- else if (dataType == typeof(DateTimeOffset))
- {
- result = new DateTimeOffsetTypeInfo();
- }
- else if (dataType == typeof(EmptyStruct))
- {
- result = new NullTypeInfo<EmptyStruct>();
- }
- else if (IsGenericMatch(dataType, typeof(KeyValuePair<,>)))
- {
- var args = GetGenericArguments(dataType);
- result = (TraceLoggingTypeInfo<DataType>)CreateInstance(
- typeof(KeyValuePairTypeInfo<,>).MakeGenericType(args[0], args[1]),
- recursionCheck);
- }
- else if (IsGenericMatch(dataType, typeof(Nullable<>)))
- {
- var args = GetGenericArguments(dataType);
- result = (TraceLoggingTypeInfo<DataType>)CreateInstance(
- typeof(NullableTypeInfo<>).MakeGenericType(args[0]),
- recursionCheck);
- }
- else
- {
- var elementType = FindEnumerableElementType(dataType);
- if (elementType != null)
+ else if (dataType == typeof(UInt64))
{
- result = (TraceLoggingTypeInfo<DataType>)CreateInstance(
- typeof(EnumerableTypeInfo<,>).MakeGenericType(dataType, elementType),
- GetTypeInfoInstance(elementType, recursionCheck));
+ result = ScalarTypeInfo.UInt64();
+ }
+ else if (dataType == typeof(Char))
+ {
+ result = ScalarTypeInfo.Char();
+ }
+ else if (dataType == typeof(Double))
+ {
+ result = ScalarTypeInfo.Double();
+ }
+ else if (dataType == typeof(Single))
+ {
+ result = ScalarTypeInfo.Single();
+ }
+ else if (dataType == typeof(DateTime))
+ {
+ result = new DateTimeTypeInfo();
+ }
+ else if (dataType == typeof(Decimal))
+ {
+ result = new DecimalTypeInfo();
+ }
+ else if (dataType == typeof(IntPtr))
+ {
+ result = ScalarTypeInfo.IntPtr();
+ }
+ else if (dataType == typeof(UIntPtr))
+ {
+ result = ScalarTypeInfo.UIntPtr();
+ }
+ else if (dataType == typeof(Guid))
+ {
+ result = ScalarTypeInfo.Guid();
+ }
+ else if (dataType == typeof(TimeSpan))
+ {
+ result = new TimeSpanTypeInfo();
+ }
+ else if (dataType == typeof(DateTimeOffset))
+ {
+ result = new DateTimeOffsetTypeInfo();
+ }
+ else if (dataType == typeof(EmptyStruct))
+ {
+ result = new NullTypeInfo();
+ }
+ else if (IsGenericMatch(dataType, typeof(Nullable<>)))
+ {
+ result = new NullableTypeInfo(dataType, recursionCheck);
}
else
{
- throw new ArgumentException(Environment.GetResourceString("EventSource_NonCompliantTypeError", dataType.Name));
+ var elementType = FindEnumerableElementType(dataType);
+ if (elementType != null)
+ {
+ result = new EnumerableTypeInfo(dataType, TraceLoggingTypeInfo.GetInstance(elementType, recursionCheck));
+ }
+ else
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_NonCompliantTypeError", dataType.Name));
+ }
}
}
- return (TraceLoggingTypeInfo<DataType>)result;
+ return result;
}
#endregion
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs
index 2ac1df17fd..6a805d951d 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs
@@ -60,70 +60,10 @@ namespace System.Diagnostics.Tracing
return this;
}
- /// <summary>
- /// Adds a Boolean value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- public void AddScalar(bool value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(bool));
- }
-
- /// <summary>
- /// Adds an SByte value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- //[CLSCompliant(false)]
- public void AddScalar(sbyte value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(sbyte));
- }
-
- /// <summary>
- /// Adds a Byte value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- public void AddScalar(byte value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(byte));
- }
-
- /// <summary>
- /// Adds an Int16 value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- public void AddScalar(short value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(short));
- }
-
- /// <summary>
- /// Adds a UInt16 value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- //[CLSCompliant(false)]
- public void AddScalar(ushort value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(ushort));
- }
-
- /// <summary>
- /// Adds an Int32 value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- public void AddScalar(int value)
+ public void AddScalar(PropertyValue value)
{
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(int));
- }
-
- /// <summary>
- /// Adds a UInt32 value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- //[CLSCompliant(false)]
- public void AddScalar(uint value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(uint));
+ var scalar = value.ScalarValue;
+ DataCollector.ThreadInstance.AddScalar(&scalar, value.ScalarLength);
}
/// <summary>
@@ -136,44 +76,6 @@ namespace System.Diagnostics.Tracing
}
/// <summary>
- /// Adds a UInt64 value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- //[CLSCompliant(false)]
- public void AddScalar(ulong value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(ulong));
- }
-
- /// <summary>
- /// Adds an IntPtr value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- public void AddScalar(IntPtr value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, IntPtr.Size);
- }
-
- /// <summary>
- /// Adds a UIntPtr value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- //[CLSCompliant(false)]
- public void AddScalar(UIntPtr value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, UIntPtr.Size);
- }
-
- /// <summary>
- /// Adds a Single value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- public void AddScalar(float value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(float));
- }
-
- /// <summary>
/// Adds a Double value to the event payload.
/// </summary>
/// <param name="value">Value to be added.</param>
@@ -183,24 +85,6 @@ namespace System.Diagnostics.Tracing
}
/// <summary>
- /// Adds a Char value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- public void AddScalar(char value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, sizeof(char));
- }
-
- /// <summary>
- /// Adds a Guid value to the event payload.
- /// </summary>
- /// <param name="value">Value to be added.</param>
- public void AddScalar(Guid value)
- {
- DataCollector.ThreadInstance.AddScalar(&value, 16);
- }
-
- /// <summary>
/// Adds a counted String value to the event payload.
/// </summary>
/// <param name="value">
@@ -211,185 +95,10 @@ namespace System.Diagnostics.Tracing
DataCollector.ThreadInstance.AddBinary(value, value == null ? 0 : value.Length * 2);
}
- /// <summary>
- /// Adds an array of Byte values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddBinary(byte[] value)
- {
- DataCollector.ThreadInstance.AddBinary(value, value == null ? 0 : value.Length);
- }
-
- /// <summary>
- /// Adds an array of Boolean values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddArray(bool[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(bool));
- }
-
- /// <summary>
- /// Adds an array of SByte values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- //[CLSCompliant(false)]
- public void AddArray(sbyte[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(sbyte));
- }
-
- /// <summary>
- /// Adds an array of Int16 values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddArray(short[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(short));
- }
-
- /// <summary>
- /// Adds an array of UInt16 values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- //[CLSCompliant(false)]
- public void AddArray(ushort[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(ushort));
- }
-
- /// <summary>
- /// Adds an array of Int32 values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddArray(int[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(int));
- }
-
- /// <summary>
- /// Adds an array of UInt32 values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- //[CLSCompliant(false)]
- public void AddArray(uint[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(uint));
- }
-
- /// <summary>
- /// Adds an array of Int64 values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddArray(long[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(long));
- }
-
- /// <summary>
- /// Adds an array of UInt64 values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- //[CLSCompliant(false)]
- public void AddArray(ulong[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(ulong));
- }
-
- /// <summary>
- /// Adds an array of IntPtr values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddArray(IntPtr[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, IntPtr.Size);
- }
-
- /// <summary>
- /// Adds an array of UIntPtr values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- //[CLSCompliant(false)]
- public void AddArray(UIntPtr[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, UIntPtr.Size);
- }
-
- /// <summary>
- /// Adds an array of Single values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddArray(float[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(float));
- }
-
- /// <summary>
- /// Adds an array of Double values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddArray(double[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(double));
- }
-
- /// <summary>
- /// Adds an array of Char values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddArray(char[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(char));
- }
-
- /// <summary>
- /// Adds an array of Guid values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddArray(Guid[] value)
- {
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, 16);
- }
-
- /// <summary>
- /// Adds an array of Byte values to the event payload.
- /// </summary>
- /// <param name="value">
- /// Value to be added. A null value is treated as a zero-length array.
- /// </param>
- public void AddCustom(byte[] value)
+ public void AddArray(PropertyValue value, int elementSize)
{
- DataCollector.ThreadInstance.AddArray(value, value == null ? 0 : value.Length, sizeof(byte));
+ Array array = (Array)value.ReferenceValue;
+ DataCollector.ThreadInstance.AddArray(array, array == null ? 0 : array.Length, elementSize);
}
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs
index 9dd3d8c035..366d615a85 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs
@@ -17,6 +17,7 @@
#if ES_BUILD_STANDALONE
using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
+using EventDescriptor = Microsoft.Diagnostics.Tracing.EventDescriptor;
#endif
using System;
@@ -120,8 +121,7 @@ namespace System.Diagnostics.Tracing
}
var options = new EventSourceOptions();
- var data = new EmptyStruct();
- this.WriteImpl(eventName, ref options, ref data, null, null);
+ this.WriteImpl(eventName, ref options, null, null, null, SimpleEventTypes<EmptyStruct>.Instance);
}
/// <summary>
@@ -148,8 +148,7 @@ namespace System.Diagnostics.Tracing
return;
}
- var data = new EmptyStruct();
- this.WriteImpl(eventName, ref options, ref data, null, null);
+ this.WriteImpl(eventName, ref options, null, null, null, SimpleEventTypes<EmptyStruct>.Instance);
}
/// <summary>
@@ -182,7 +181,7 @@ namespace System.Diagnostics.Tracing
}
var options = new EventSourceOptions();
- this.WriteImpl(eventName, ref options, ref data, null, null);
+ this.WriteImpl(eventName, ref options, data, null, null, SimpleEventTypes<T>.Instance);
}
/// <summary>
@@ -219,7 +218,7 @@ namespace System.Diagnostics.Tracing
return;
}
- this.WriteImpl(eventName, ref options, ref data, null, null);
+ this.WriteImpl(eventName, ref options, data, null, null, SimpleEventTypes<T>.Instance);
}
/// <summary>
@@ -258,7 +257,7 @@ namespace System.Diagnostics.Tracing
return;
}
- this.WriteImpl(eventName, ref options, ref data, null, null);
+ this.WriteImpl(eventName, ref options, data, null, null, SimpleEventTypes<T>.Instance);
}
/// <summary>
@@ -311,9 +310,10 @@ namespace System.Diagnostics.Tracing
this.WriteImpl(
eventName,
ref options,
- ref data,
+ data,
pActivity,
- relatedActivityId == Guid.Empty ? null : pRelated);
+ relatedActivityId == Guid.Empty ? null : pRelated,
+ SimpleEventTypes<T>.Instance);
}
}
@@ -354,7 +354,7 @@ namespace System.Diagnostics.Tracing
string eventName,
ref EventSourceOptions options,
TraceLoggingEventTypes eventTypes,
- Guid* activityID,
+ Guid* activityID,
Guid* childActivityID,
params object[] values)
{
@@ -412,12 +412,12 @@ namespace System.Diagnostics.Tracing
/// </param>
[SecuritySafeCritical]
private unsafe void WriteMultiMergeInner(
- string eventName,
- ref EventSourceOptions options,
- TraceLoggingEventTypes eventTypes,
- Guid* activityID,
- Guid* childActivityID,
- params object[] values)
+ string eventName,
+ ref EventSourceOptions options,
+ TraceLoggingEventTypes eventTypes,
+ Guid* activityID,
+ Guid* childActivityID,
+ params object[] values)
{
int identity = 0;
byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0
@@ -455,7 +455,7 @@ namespace System.Diagnostics.Tracing
descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1);
descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1);
-#if !ES_BUILD_PCL
+#if (!ES_BUILD_PCL && !PROJECTN)
System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
#endif
try
@@ -470,10 +470,12 @@ namespace System.Diagnostics.Tracing
for (int i = 0; i < eventTypes.typeInfos.Length; i++)
{
- eventTypes.typeInfos[i].WriteObjectData(TraceLoggingDataCollector.Instance, values[i]);
+ var info = eventTypes.typeInfos[i];
+ info.WriteData(TraceLoggingDataCollector.Instance, info.PropertyValueFactory(values[i]));
}
this.WriteEventRaw(
+ eventName,
ref descriptor,
activityID,
childActivityID,
@@ -584,6 +586,7 @@ namespace System.Diagnostics.Tracing
}
this.WriteEventRaw(
+ eventName,
ref descriptor,
activityID,
childActivityID,
@@ -594,17 +597,16 @@ namespace System.Diagnostics.Tracing
}
[SecuritySafeCritical]
- private unsafe void WriteImpl<T>(
+ private unsafe void WriteImpl(
string eventName,
ref EventSourceOptions options,
- ref T data,
+ object data,
Guid* pActivityId,
- Guid* pRelatedActivityId)
+ Guid* pRelatedActivityId,
+ TraceLoggingEventTypes eventTypes)
{
try
{
- var eventTypes = SimpleEventTypes<T>.Instance;
-
fixed (EventSourceOptions* pOptions = &options)
{
EventDescriptor descriptor;
@@ -629,7 +631,7 @@ namespace System.Diagnostics.Tracing
descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1);
descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1);
-#if !ES_BUILD_PCL
+#if (!ES_BUILD_PCL && !PROJECTN)
System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
#endif
EventOpcode opcode = (EventOpcode)descriptor.Opcode;
@@ -663,9 +665,11 @@ namespace System.Diagnostics.Tracing
pins,
pinCount);
- eventTypes.typeInfo.WriteData(TraceLoggingDataCollector.Instance, ref data);
-
+ var info = eventTypes.typeInfos[0];
+ info.WriteData(TraceLoggingDataCollector.Instance, info.PropertyValueFactory(data));
+
this.WriteEventRaw(
+ eventName,
ref descriptor,
pActivityId,
pRelatedActivityId,
@@ -675,17 +679,17 @@ namespace System.Diagnostics.Tracing
// TODO enable filtering for listeners.
if (m_Dispatchers != null)
{
- var eventData = (EventPayload)(eventTypes.typeInfo.GetData(data));
+ var eventData = (EventPayload)(eventTypes.typeInfos[0].GetData(data));
WriteToAllListeners(eventName, ref descriptor, nameInfo.tags, pActivityId, eventData);
}
}
- catch(Exception ex)
+ catch (Exception ex)
{
if (ex is EventSourceException)
throw;
else
- ThrowEventSourceException(ex);
+ ThrowEventSourceException(eventName, ex);
}
finally
{
@@ -699,7 +703,7 @@ namespace System.Diagnostics.Tracing
if (ex is EventSourceException)
throw;
else
- ThrowEventSourceException(ex);
+ ThrowEventSourceException(eventName, ex);
}
}
@@ -727,7 +731,7 @@ namespace System.Diagnostics.Tracing
DispatchToAllListeners(-1, pActivityId, eventCallbackArgs);
}
-#if !ES_BUILD_PCL
+#if (!ES_BUILD_PCL && !PROJECTN)
[System.Runtime.ConstrainedExecution.ReliabilityContract(
System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState,
System.Runtime.ConstrainedExecution.Cer.Success)]
@@ -761,9 +765,13 @@ namespace System.Diagnostics.Tracing
if (!byte.TryParse(etwTrait, out traitNum))
{
if (etwTrait == "GROUP")
+ {
traitNum = 1;
+ }
else
- throw new ArgumentException(Environment.GetResourceString("UnknownEtwTrait", etwTrait), "traits");
+ {
+ throw new ArgumentException(Resources.GetResourceString("UnknownEtwTrait", etwTrait), "traits");
+ }
}
string value = m_traits[i + 1];
int lenPos = traitMetaData.Count;
@@ -776,7 +784,7 @@ namespace System.Diagnostics.Tracing
}
}
providerMetadata = Statics.MetadataForString(this.Name, 0, traitMetaData.Count, 0);
- int startPos = providerMetadata.Length-traitMetaData.Count;
+ int startPos = providerMetadata.Length - traitMetaData.Count;
foreach (var b in traitMetaData)
providerMetadata[startPos++] = b;
}
@@ -803,16 +811,22 @@ namespace System.Diagnostics.Tracing
if (value[i] != ' ') // Skip spaces between bytes.
{
if (!(i + 1 < value.Length))
- throw new ArgumentException(Environment.GetResourceString("EvenHexDigits"), "traits");
+ {
+ throw new ArgumentException(Resources.GetResourceString("EvenHexDigits"), "traits");
+ }
metaData.Add((byte)(HexDigit(value[i]) * 16 + HexDigit(value[i + 1])));
i++;
}
}
}
else if ('A' <= firstChar || ' ' == firstChar) // Is it alphabetic or space (excludes digits and most punctuation).
+ {
metaData.AddRange(Encoding.UTF8.GetBytes(value));
+ }
else
- throw new ArgumentException(Environment.GetResourceString("IllegalValue", value), "traits");
+ {
+ throw new ArgumentException(Resources.GetResourceString("IllegalValue", value), "traits");
+ }
return metaData.Count - startPos;
}
@@ -823,12 +837,19 @@ namespace System.Diagnostics.Tracing
private static int HexDigit(char c)
{
if ('0' <= c && c <= '9')
+ {
return (c - '0');
+ }
if ('a' <= c)
- c = unchecked((char) (c - ('a' - 'A'))); // Convert to lower case
+ {
+ c = unchecked((char)(c - ('a' - 'A'))); // Convert to lower case
+ }
if ('A' <= c && c <= 'F')
+ {
return (c - 'A' + 10);
- throw new ArgumentException(Environment.GetResourceString("BadHexDigit", c), "traits");
+ }
+
+ throw new ArgumentException(Resources.GetResourceString("BadHexDigit", c), "traits");
}
private NameInfo UpdateDescriptor(
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs
index 06b840f7b7..39327f6786 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs
@@ -21,7 +21,7 @@ namespace System.Diagnostics.Tracing
/// TraceLogging: Used when calling EventSource.WriteMultiMerge.
/// Stores the type information to use when writing the event fields.
/// </summary>
- internal class TraceLoggingEventTypes
+ public class TraceLoggingEventTypes
{
internal readonly TraceLoggingTypeInfo[] typeInfos;
internal readonly string name;
@@ -220,7 +220,7 @@ namespace System.Diagnostics.Tracing
var result = new TraceLoggingTypeInfo[paramInfos.Length];
for (int i = 0; i < paramInfos.Length; ++i)
{
- result[i] = Statics.GetTypeInfoInstance(paramInfos[i].ParameterType, recursionCheck);
+ result[i] = TraceLoggingTypeInfo.GetInstance(paramInfos[i].ParameterType, recursionCheck);
}
return result;
@@ -239,7 +239,7 @@ namespace System.Diagnostics.Tracing
var result = new TraceLoggingTypeInfo[types.Length];
for (int i = 0; i < types.Length; i++)
{
- result[i] = Statics.GetTypeInfoInstance(types[i], recursionCheck);
+ result[i] = TraceLoggingTypeInfo.GetInstance(types[i], recursionCheck);
}
return result;
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs
index ff97db5aa2..cee8985aba 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs
@@ -231,7 +231,7 @@ namespace System.Diagnostics.Tracing
if (this.BeginningBufferedArray)
{
- throw new NotSupportedException(Environment.GetResourceString("EventSource_NotSupportedNestedArraysEnums"));
+ throw new NotSupportedException(Resources.GetResourceString("EventSource_NotSupportedNestedArraysEnums"));
}
this.impl.AddScalar(2);
@@ -243,7 +243,7 @@ namespace System.Diagnostics.Tracing
{
if (this.bufferedArrayFieldCount >= 0)
{
- throw new NotSupportedException(Environment.GetResourceString("EventSource_NotSupportedNestedArraysEnums"));
+ throw new NotSupportedException(Resources.GetResourceString("EventSource_NotSupportedNestedArraysEnums"));
}
this.bufferedArrayFieldCount = 0;
@@ -254,7 +254,7 @@ namespace System.Diagnostics.Tracing
{
if (this.bufferedArrayFieldCount != 1)
{
- throw new InvalidOperationException(Environment.GetResourceString("EventSource_IncorrentlyAuthoredTypeInfo"));
+ throw new InvalidOperationException(Resources.GetResourceString("EventSource_IncorrentlyAuthoredTypeInfo"));
}
this.bufferedArrayFieldCount = int.MinValue;
@@ -273,7 +273,7 @@ namespace System.Diagnostics.Tracing
{
if (this.BeginningBufferedArray)
{
- throw new NotSupportedException(Environment.GetResourceString("EventSource_NotSupportedCustomSerializedData"));
+ throw new NotSupportedException(Resources.GetResourceString("EventSource_NotSupportedCustomSerializedData"));
}
this.impl.AddScalar(2);
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs
index 21a4390e42..7d4b53315e 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
+using System.Collections.Generic;
#if !ES_BUILD_AGAINST_DOTNET_V35
using Contract = System.Diagnostics.Contracts.Contract;
@@ -28,6 +29,7 @@ namespace System.Diagnostics.Tracing
private readonly EventOpcode opcode = (EventOpcode)(-1);
private readonly EventTags tags;
private readonly Type dataType;
+ private readonly Func<object, PropertyValue> propertyValueFactory;
internal TraceLoggingTypeInfo(Type dataType)
{
@@ -40,6 +42,7 @@ namespace System.Diagnostics.Tracing
this.name = dataType.Name;
this.dataType = dataType;
+ this.propertyValueFactory = PropertyValue.GetFactory(dataType);
}
internal TraceLoggingTypeInfo(
@@ -70,6 +73,7 @@ namespace System.Diagnostics.Tracing
this.opcode = opcode;
this.tags = tags;
this.dataType = dataType;
+ this.propertyValueFactory = PropertyValue.GetFactory(dataType);
}
/// <summary>
@@ -123,6 +127,11 @@ namespace System.Diagnostics.Tracing
get { return this.dataType; }
}
+ internal Func<object, PropertyValue> PropertyValueFactory
+ {
+ get { return this.propertyValueFactory; }
+ }
+
/// <summary>
/// When overridden by a derived class, writes the metadata (schema) for
/// this type. Note that the sequence of operations in WriteMetadata should be
@@ -162,9 +171,9 @@ namespace System.Diagnostics.Tracing
/// Refer to TraceLoggingTypeInfo.WriteObjectData for information about this
/// method.
/// </param>
- public abstract void WriteObjectData(
+ public abstract void WriteData(
TraceLoggingDataCollector collector,
- object value);
+ PropertyValue value);
/// <summary>
/// Fetches the event parameter data for internal serialization.
@@ -175,5 +184,25 @@ namespace System.Diagnostics.Tracing
{
return value;
}
+
+ [ThreadStatic] // per-thread cache to avoid synchronization
+ private static Dictionary<Type, TraceLoggingTypeInfo> threadCache;
+
+ public static TraceLoggingTypeInfo GetInstance(Type type, List<Type> recursionCheck)
+ {
+ var cache = threadCache ?? (threadCache = new Dictionary<Type, TraceLoggingTypeInfo>());
+
+ TraceLoggingTypeInfo instance;
+ if (!cache.TryGetValue(type, out instance))
+ {
+ if (recursionCheck == null)
+ recursionCheck = new List<Type>();
+ var recursionCheckCount = recursionCheck.Count;
+ instance = Statics.CreateDefaultTypeInfo(type, recursionCheck);
+ cache[type] = instance;
+ recursionCheck.RemoveRange(recursionCheckCount, recursionCheck.Count - recursionCheckCount);
+ }
+ return instance;
+ }
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo_T.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo_T.cs
deleted file mode 100644
index 58945987ee..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo_T.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Collections.Generic;
-using Interlocked = System.Threading.Interlocked;
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- /// <summary>
- /// TraceLogging: used when implementing a custom TraceLoggingTypeInfo.
- /// Implementations of this type provide the behaviors that TraceLogging
- /// uses to turn objects into event data. TraceLogging provides default
- /// implementations of this type, but custom implementations can be used
- /// when the default TraceLogging implementation is insufficient.
- /// </summary>
- /// <typeparam name="DataType">
- /// The type of object that is handled by this implementation.
- /// </typeparam>
- internal abstract class TraceLoggingTypeInfo<DataType>
- : TraceLoggingTypeInfo
- {
- private static TraceLoggingTypeInfo<DataType> instance;
-
- /// <summary>
- /// Initializes a new instance of the TraceLoggingTypeInfo class with
- /// default settings. Uses typeof(DataType).Name for EventName and FieldName.
- /// Marks Level and Opcode as unset. Sets Keywords and Traits to 0.
- /// </summary>
- protected TraceLoggingTypeInfo()
- : base(typeof(DataType))
- {
- return;
- }
-
- /// <summary>
- /// Initializes a new instance of the TraceLoggingTypeInfo class, using
- /// the specified values for the EventName, Level, Opcode, Keywords,
- /// FieldName, and Traits properties.
- /// </summary>
- /// <param name="name">
- /// The value for the Name property. Must not contain '\0' characters.
- /// Must not be null.
- /// </param>
- /// <param name="level">
- /// The value for the Level property, or -1 to mark Level as unset.
- /// </param>
- /// <param name="opcode">
- /// The value for the Opcode property, or -1 to mark Opcode as unset.
- /// </param>
- /// <param name="keywords">
- /// The value for the Keywords property.
- /// </param>
- /// <param name="tags">
- /// The value for the Tags property.
- /// </param>
- protected TraceLoggingTypeInfo(
- string name,
- EventLevel level,
- EventOpcode opcode,
- EventKeywords keywords,
- EventTags tags)
- : base(
- typeof(DataType),
- name,
- level,
- opcode,
- keywords,
- tags)
- {
- return;
- }
-
- /// <summary>
- /// Gets the type info that will be used for handling instances of
- /// DataType. If the instance has not already been set, this will
- /// call TrySetInstance(automaticSerializer) to set one, where
- /// automaticSerializer is the value returned from CreateDefault(),
- /// or a do-nothing serializer if CreateDefault() fails.
- /// </summary>
- public static TraceLoggingTypeInfo<DataType> Instance
- {
- get
- {
- return instance ?? InitInstance();
- }
- }
-
- /// <summary>
- /// When overridden by a derived class, writes the data (fields) for an instance
- /// of DataType. Note that the sequence of operations in WriteData should be
- /// essentially identical to the sequence of operations in WriteMetadata. Otherwise,
- /// the metadata and data will not match, which may cause trouble when decoding the
- /// event.
- /// </summary>
- /// <param name="collector">
- /// The object that collects the data for the instance. Data is written by calling
- /// methods on the collector object. Note that if the type contains sub-objects,
- /// the implementation of this method may need to call the WriteData method
- /// for the sub-object, e.g. by calling
- /// TraceLoggingTypeInfo&lt;SubType&gt;.Instance.WriteData(...).
- /// </param>
- /// <param name="value">
- /// The value for which data is to be written.
- /// </param>
- public abstract void WriteData(
- TraceLoggingDataCollector collector,
- ref DataType value);
-
- /// <summary>
- /// When overridden in a derived class, writes the data (fields) for an instance
- /// of DataType. The default implementation of WriteObjectData calls
- /// WriteData(collector, (DataType)value). Normally, you will override WriteData
- /// and not WriteObjectData. However, if your implementation of WriteData has to
- /// cast the value to object, it may be more efficient to reverse this calling
- /// pattern, i.e. to implement WriteObjectData, and then implement WriteData as a
- /// call to WriteObjectData.
- /// </summary>
- /// <param name="collector">
- /// The object that collects the data for the instance. Data is written by calling
- /// methods on the collector object. Note that if the type contains sub-objects,
- /// the implementation of this method may need to call the WriteData method
- /// for the sub-object, e.g. by calling
- /// TraceLoggingTypeInfo&lt;SubType&gt;.Instance.WriteData(...).
- /// </param>
- /// <param name="value">
- /// The value for which data is to be written. Note that this value may be null
- /// (even for value types) if the property from which the value was read is
- /// missing or null.
- /// </param>
- public override void WriteObjectData(
- TraceLoggingDataCollector collector,
- object value)
- {
- var val = value == null ? default(DataType) : (DataType)value;
- this.WriteData(collector, ref val);
- }
-
- internal static TraceLoggingTypeInfo<DataType> GetInstance(List<Type> recursionCheck)
- {
- if (instance == null)
- {
- var recursionCheckCount = recursionCheck.Count;
- var newInstance = Statics.CreateDefaultTypeInfo<DataType>(recursionCheck);
- Interlocked.CompareExchange(ref instance, newInstance, null);
- recursionCheck.RemoveRange(recursionCheckCount, recursionCheck.Count - recursionCheckCount);
- }
-
- return instance;
- }
-
- private static TraceLoggingTypeInfo<DataType> InitInstance()
- {
- return GetInstance(new List<Type>());
- }
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TypeAnalysis.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TypeAnalysis.cs
index 8b44ddec15..3221dbdc0d 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TypeAnalysis.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TypeAnalysis.cs
@@ -57,7 +57,7 @@ namespace System.Diagnostics.Tracing
}
var propertyType = propertyInfo.PropertyType;
- var propertyTypeInfo = Statics.GetTypeInfoInstance(propertyType, recursionCheck);
+ var propertyTypeInfo = TraceLoggingTypeInfo.GetInstance(propertyType, recursionCheck);
var fieldAttribute = Statics.GetCustomAttribute<EventFieldAttribute>(propertyInfo);
string propertyName =
@@ -68,7 +68,7 @@ namespace System.Diagnostics.Tracing
: propertyInfo.Name;
propertyList.Add(new PropertyAnalysis(
propertyName,
- getterInfo,
+ propertyInfo,
propertyTypeInfo,
fieldAttribute));
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/Winmeta.cs b/src/mscorlib/src/System/Diagnostics/Eventing/Winmeta.cs
index 9971a8ff8c..31e5a68d68 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/Winmeta.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/Winmeta.cs
@@ -24,7 +24,8 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// WindowsEventLevel. Custom values must be in the range from 16 through 255
/// </summary>
- public enum EventLevel {
+ public enum EventLevel
+ {
/// <summary>
/// Log always
/// </summary>
@@ -53,10 +54,11 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// WindowsEventTask. Custom values must be in the range from 1 through 65534
/// </summary>
-#if !ES_BUILD_STANDALONE
+#if (!ES_BUILD_STANDALONE && !PROJECTN)
[System.Runtime.CompilerServices.FriendAccessAllowed]
#endif
- public enum EventTask {
+ public enum EventTask
+ {
/// <summary>
/// Undefined task
/// </summary>
@@ -65,7 +67,7 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// EventOpcode. Custom values must be in the range from 11 through 239
/// </summary>
-#if !ES_BUILD_STANDALONE
+#if (!ES_BUILD_STANDALONE && !PROJECTN)
[System.Runtime.CompilerServices.FriendAccessAllowed]
#endif
public enum EventOpcode
@@ -120,12 +122,12 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// EventChannel. Custom values must be in the range from 16 through 255. Currently only predefined values allowed.
/// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification="Backwards compatibility")]
-#if !ES_BUILD_STANDALONE
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification = "Backwards compatibility")]
+#if (!ES_BUILD_STANDALONE && !PROJECTN)
[System.Runtime.CompilerServices.FriendAccessAllowed]
#endif
- public enum EventChannel : byte
- {
+ public enum EventChannel : byte
+ {
/// <summary>
/// No channel
/// </summary>
@@ -146,7 +148,8 @@ namespace System.Diagnostics.Tracing
/// EventOpcode
/// </summary>
[Flags]
- public enum EventKeywords : long {
+ public enum EventKeywords : long
+ {
/// <summary>
/// No events.
/// </summary>
diff --git a/src/nativeresources/processrc.awk b/src/nativeresources/processrc.awk
index 1632753956..fcfd6e4f91 100644
--- a/src/nativeresources/processrc.awk
+++ b/src/nativeresources/processrc.awk
@@ -40,9 +40,9 @@ BEGIN {
# some of the resource IDs have trailing L
gsub(/L/, "", $i);
expression = expression $i;
- $i="";
i++;
}
+
# evaluate the resource ID expression
cmd = "echo $(("expression"))";
cmd | getline var;
@@ -50,13 +50,17 @@ BEGIN {
# in case shell returned the result as a string, ensure the var has numeric type
var = var + 0;
+ # Extract string content starting with either " or L"
+ idx = match($0, /L?\"/);
+ content = substr($0, idx);
+
# remove the L prefix from strings
- gsub(/L"/, "\"", $0);
+ gsub(/L"/, "\"", content);
# join strings "..." "..." into one
- gsub(/" +"/, "", $0);
+ gsub(/" +"/, "", content);
# write the resource entry to the target file
- writestringentry(var, $0);
+ writestringentry(var, content);
}
}
END {
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index c139efcba8..7eaba46688 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -6112,6 +6112,7 @@ PALIMPORT int __cdecl vsprintf(char *, const char *, va_list);
PALIMPORT int __cdecl sscanf(const char *, const char *, ...);
PALIMPORT int __cdecl atoi(const char *);
PALIMPORT LONG __cdecl atol(const char *);
+PALIMPORT long long int __cdecl atoll(const char *);
PALIMPORT ULONG __cdecl strtoul(const char *, char **, int);
PALIMPORT double __cdecl atof(const char *);
PALIMPORT double __cdecl strtod(const char *, char **);
diff --git a/src/pal/inc/pal_mstypes.h b/src/pal/inc/pal_mstypes.h
index aca1c60814..e56cf1bd6d 100644
--- a/src/pal/inc/pal_mstypes.h
+++ b/src/pal/inc/pal_mstypes.h
@@ -319,8 +319,7 @@ typedef signed __int64 LONG64;
#ifdef BIT64
-// UNIXTODO: Implement proper _atoi64, the atol returns 32 bit result
-#define _atoi64 (__int64)atol
+#define _atoi64 (__int64)atoll
typedef __int64 INT_PTR, *PINT_PTR;
typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
diff --git a/src/scripts/Utilities.py b/src/scripts/Utilities.py
index 0de1cafdbd..9dfefb7329 100644
--- a/src/scripts/Utilities.py
+++ b/src/scripts/Utilities.py
@@ -7,7 +7,7 @@ def walk_recursively_and_update(dcmp):
for name in dcmp.diff_files:
srcpath = dcmp.right + "/" + name
destpath = dcmp.left + "/" + name
- print "Updating %s" % (destpath)
+ print("Updating %s" % (destpath))
if os.path.isfile(srcpath):
shutil.copyfile(srcpath, destpath)
else :
@@ -17,7 +17,7 @@ def walk_recursively_and_update(dcmp):
for name in dcmp.right_only:
srcpath = dcmp.right + "/" + name
destpath = dcmp.left + "/" + name
- print "Updating %s" % (destpath)
+ print("Updating %s" % (destpath))
if os.path.isfile(srcpath):
shutil.copyfile(srcpath, destpath)
elif os.path.isdir(srcpath):
@@ -28,7 +28,7 @@ def walk_recursively_and_update(dcmp):
#delete left only files
for name in dcmp.left_only:
path = dcmp.left + "/" + name
- print "Deleting " % (path)
+ print("Deleting " % (path))
if os.path.isfile(path):
os.remove(path)
elif os.path.isdir(path):
diff --git a/src/scripts/genWinEtw.py b/src/scripts/genWinEtw.py
index 52bcbd4763..19f9f30e68 100644
--- a/src/scripts/genWinEtw.py
+++ b/src/scripts/genWinEtw.py
@@ -37,12 +37,12 @@ def generateEtwMacroHeader(sClrEtwAllMan, sExcludeFile,macroHeader,inHeader):
os.makedirs(incDir)
outHeader = open(macroHeader,'w')
- print >>outHeader, stdprolog
-
- print >>outHeader, "#include \"" + os.path.basename(inHeader) + '"'
- print >>outHeader, "#define NO_OF_ETW_PROVIDERS " + str(numOfProviders)
- print >>outHeader, "#define MAX_BYTES_PER_ETW_PROVIDER " + str(nMaxEventBytesPerProvider)
- print >>outHeader, "EXTERN_C __declspec(selectany) const BYTE etwStackSupportedEvents[NO_OF_ETW_PROVIDERS][MAX_BYTES_PER_ETW_PROVIDER] = \n{"
+ outHeader.write(stdprolog + "\n")
+
+ outHeader.write("#include \"" + os.path.basename(inHeader) + '"\n')
+ outHeader.write("#define NO_OF_ETW_PROVIDERS " + str(numOfProviders) + "\n")
+ outHeader.write("#define MAX_BYTES_PER_ETW_PROVIDER " + str(nMaxEventBytesPerProvider) + "\n")
+ outHeader.write("EXTERN_C __declspec(selectany) const BYTE etwStackSupportedEvents[NO_OF_ETW_PROVIDERS][MAX_BYTES_PER_ETW_PROVIDER] = \n{\n")
for providerNode in tree.getElementsByTagName('provider'):
stackSupportedEvents = [0]*nMaxEventBytesPerProvider
@@ -55,8 +55,8 @@ def generateEtwMacroHeader(sClrEtwAllMan, sExcludeFile,macroHeader,inHeader):
eventTemplate = eventNode.getAttribute('template')
eventTemplate = eventNode.getAttribute('template')
eventValue = int(eventNode.getAttribute('value'))
- eventIndex = eventValue/8
- eventBitPositionInIndex = eventValue%8
+ eventIndex = eventValue // 8
+ eventBitPositionInIndex = eventValue % 8
eventStackBitFromNoStackList = int(getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.nostack))
eventStackBitFromExplicitStackList = int(getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.explicitstack))
@@ -80,8 +80,8 @@ def generateEtwMacroHeader(sClrEtwAllMan, sExcludeFile,macroHeader,inHeader):
del line[-1]
line.append("},")
- print >>outHeader,''.join(line)
- print >>outHeader, "};"
+ outHeader.write(''.join(line) + "\n")
+ outHeader.write("};\n")
outHeader.close()
diff --git a/src/scripts/genXplatEventing.py b/src/scripts/genXplatEventing.py
index 0f4033e18f..1d01b60a6c 100644
--- a/src/scripts/genXplatEventing.py
+++ b/src/scripts/genXplatEventing.py
@@ -10,7 +10,6 @@
import os
import xml.dom.minidom as DOM
-from sets import Set
stdprolog="""
//
@@ -179,8 +178,8 @@ def bucketizeAbstractTemplates(template,fnPrototypes,var_Dependecies):
return templateProp
-ignoredXmlTemplateAttribes = Set(["map","outType"])
-usedXmlTemplateAttribes = Set(["name","inType","count", "length"])
+ignoredXmlTemplateAttribes = frozenset(["map","outType"])
+usedXmlTemplateAttribes = frozenset(["name","inType","count", "length"])
def parseTemplateNodes(templateNodes):
@@ -608,14 +607,14 @@ def generateEtmDummyHeader(sClrEtwAllMan,clretwdummy):
if not os.path.exists(incDir):
os.makedirs(incDir)
Clretwdummy = open(clretwdummy,'w')
- print >>Clretwdummy, stdprolog
+ Clretwdummy.write(stdprolog + "\n")
for providerNode in tree.getElementsByTagName('provider'):
templateNodes = providerNode.getElementsByTagName('template')
allTemplates = parseTemplateNodes(templateNodes)
eventNodes = providerNode.getElementsByTagName('event')
#pal: create etmdummy.h
- print >>Clretwdummy,generateclrEtwDummy(eventNodes,allTemplates)
+ Clretwdummy.write(generateclrEtwDummy(eventNodes, allTemplates) + "\n")
Clretwdummy.close()
@@ -632,20 +631,20 @@ def generatePlformIndependentFiles(sClrEtwAllMan,incDir,etmDummyFile, testDir):
Clrallevents = open(clrallevents,'w')
Clrxplatevents = open(clrxplatevents,'w')
- print >>Clrallevents, stdprolog
- print >>Clrxplatevents, stdprolog
+ Clrallevents.write(stdprolog + "\n")
+ Clrxplatevents.write(stdprolog + "\n")
- print >>Clrallevents, "\n#include \"clrxplatevents.h\"\n"
+ Clrallevents.write("\n#include \"clrxplatevents.h\"\n\n")
for providerNode in tree.getElementsByTagName('provider'):
templateNodes = providerNode.getElementsByTagName('template')
allTemplates = parseTemplateNodes(templateNodes)
eventNodes = providerNode.getElementsByTagName('event')
#vm header:
- print >>Clrallevents,generateClrallEvents(eventNodes,allTemplates)
+ Clrallevents.write(generateClrallEvents(eventNodes, allTemplates) + "\n")
#pal: create clrallevents.h
- print >>Clrxplatevents, generateClrXplatEvents(eventNodes,allTemplates)
+ Clrxplatevents.write(generateClrXplatEvents(eventNodes, allTemplates) + "\n")
Clrxplatevents.close()
@@ -653,9 +652,9 @@ def generatePlformIndependentFiles(sClrEtwAllMan,incDir,etmDummyFile, testDir):
class EventExclusions:
def __init__(self):
- self.nostack = Set()
- self.explicitstack = Set()
- self.noclrinstance = Set()
+ self.nostack = set()
+ self.explicitstack = set()
+ self.noclrinstance = set()
def parseExclusionList(exclusionListFile):
ExclusionFile = open(exclusionListFile,'r')
diff --git a/src/scripts/genXplatLttng.py b/src/scripts/genXplatLttng.py
index 1a1652e22b..fbabfb85ae 100644
--- a/src/scripts/genXplatLttng.py
+++ b/src/scripts/genXplatLttng.py
@@ -428,8 +428,8 @@ def generateLttngFiles(etwmanifest,intermediate):
#Top level Cmake
topCmake = open(eventprovider_directory + "/CMakeLists.txt", 'w')
- print >>topCmake, stdprolog_cmake
- print >>topCmake, """cmake_minimum_required(VERSION 2.8.12.2)
+ topCmake.write(stdprolog_cmake + "\n")
+ topCmake.write("""cmake_minimum_required(VERSION 2.8.12.2)
project(eventprovider)
@@ -441,7 +441,7 @@ def generateLttngFiles(etwmanifest,intermediate):
add_library(eventprovider
STATIC
-"""
+""")
for providerNode in tree.getElementsByTagName('provider'):
providerName = providerNode.getAttribute('name')
@@ -451,21 +451,22 @@ def generateLttngFiles(etwmanifest,intermediate):
providerName_File = providerName.replace('-','')
providerName_File = providerName_File.lower()
- print >>topCmake,' "'+ lttngevntprovPre + providerName_File + ".cpp" + '"'
+ topCmake.write(' "'+ lttngevntprovPre + providerName_File + ".cpp" + '"\n')
- print >>topCmake, """)
+ topCmake.write(""")
add_subdirectory(tracepointprovider)
# Install the static eventprovider library
- install (TARGETS eventprovider DESTINATION lib)"""
+ install (TARGETS eventprovider DESTINATION lib)
+ """)
topCmake.close()
#TracepointProvider Cmake
tracepointprovider_Cmake = open(tracepointprovider_directory + "/CMakeLists.txt", 'w')
- print >>tracepointprovider_Cmake, stdprolog_cmake
- print >>tracepointprovider_Cmake, """cmake_minimum_required(VERSION 2.8.12.2)
+ tracepointprovider_Cmake.write(stdprolog_cmake + "\n")
+ tracepointprovider_Cmake.write("""cmake_minimum_required(VERSION 2.8.12.2)
project(coreclrtraceptprovider)
@@ -477,7 +478,8 @@ def generateLttngFiles(etwmanifest,intermediate):
add_compile_options(-fPIC)
add_library(coreclrtraceptprovider
- SHARED"""
+ SHARED
+ """)
for providerNode in tree.getElementsByTagName('provider'):
providerName = providerNode.getAttribute('name')
@@ -487,16 +489,17 @@ def generateLttngFiles(etwmanifest,intermediate):
providerName_File = providerName.replace('-','')
providerName_File = providerName_File.lower()
- print >>tracepointprovider_Cmake,' "'+ lttngevntprovTpPre + providerName_File +".cpp" + '"'
+ tracepointprovider_Cmake.write(' "'+ lttngevntprovTpPre + providerName_File +".cpp" + '"\n')
- print >>tracepointprovider_Cmake, """ )
+ tracepointprovider_Cmake.write(""" )
target_link_libraries(coreclrtraceptprovider
-llttng-ust
)
#Install the static coreclrtraceptprovider library
- install (TARGETS coreclrtraceptprovider DESTINATION .)"""
+ install (TARGETS coreclrtraceptprovider DESTINATION .)
+ """)
tracepointprovider_Cmake.close()
# Generate Lttng specific instrumentation
@@ -520,40 +523,43 @@ def generateLttngFiles(etwmanifest,intermediate):
lTTngImpl = open(lttngevntprov, 'w')
lTTngTpImpl = open(lttngevntprovTp, 'w')
- print >>lTTngHdr, stdprolog
- print >>lTTngImpl, stdprolog
- print >>lTTngTpImpl, stdprolog
+ lTTngHdr.write(stdprolog + "\n")
+ lTTngImpl.write(stdprolog + "\n")
+ lTTngTpImpl.write(stdprolog + "\n")
- print >>lTTngTpImpl,"\n#define TRACEPOINT_CREATE_PROBES\n"
+ lTTngTpImpl.write("\n#define TRACEPOINT_CREATE_PROBES\n")
- print >>lTTngTpImpl,"#include \"./"+lttngevntheadershortname + "\""
+ lTTngTpImpl.write("#include \"./"+lttngevntheadershortname + "\"\n")
- print >>lTTngHdr, """
+ lTTngHdr.write("""
#include "palrt.h"
#include "pal.h"
#undef TRACEPOINT_PROVIDER
-"""
+""")
- print >>lTTngHdr, "#define TRACEPOINT_PROVIDER " + providerName
- print >>lTTngHdr,"""
-#undef TRACEPOINT_INCLUDE"""
+ lTTngHdr.write("#define TRACEPOINT_PROVIDER " + providerName + "\n")
+ lTTngHdr.write("""
- print >>lTTngHdr,"#define TRACEPOINT_INCLUDE \"./" + lttngevntheadershortname + "\"\n"
+#undef TRACEPOINT_INCLUDE
+""")
+
+ lTTngHdr.write("#define TRACEPOINT_INCLUDE \"./" + lttngevntheadershortname + "\"\n\n")
- print >>lTTngHdr, "#if !defined(LTTNG_CORECLR_H" + providerName + ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n"
- print >>lTTngHdr, "#define LTTNG_CORECLR_H" + providerName
+ lTTngHdr.write("#if !defined(LTTNG_CORECLR_H" + providerName + ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n\n")
+ lTTngHdr.write("#define LTTNG_CORECLR_H" + providerName + "\n")
- print >>lTTngHdr, "\n#include <lttng/tracepoint.h>\n"
+ lTTngHdr.write("\n#include <lttng/tracepoint.h>\n\n")
- print >>lTTngImpl, """
+ lTTngImpl.write("""
#define TRACEPOINT_DEFINE
-#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE"""
- print >>lTTngImpl,"#include \"" + lttngevntheadershortname + "\"\n"
+#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
+""")
+ lTTngImpl.write("#include \"" + lttngevntheadershortname + "\"\n\n")
@@ -562,10 +568,10 @@ def generateLttngFiles(etwmanifest,intermediate):
allTemplates = parseTemplateNodes(templateNodes)
#generate the header
- print >>lTTngHdr,generateLttngHeader(providerName,allTemplates,eventNodes)
+ lTTngHdr.write(generateLttngHeader(providerName,allTemplates,eventNodes) + "\n")
#create the implementation of eventing functions : lttngeventprov*.cp
- print >>lTTngImpl,generateLttngTpProvider(providerName,eventNodes,allTemplates)
+ lTTngImpl.write(generateLttngTpProvider(providerName,eventNodes,allTemplates) + "\n")
lTTngHdr.close()
lTTngImpl.close()
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index a4d90d7073..4441f3b039 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -4776,7 +4776,7 @@ DWORD64 GetModRMOperandValue(BYTE rex, BYTE* ip, PCONTEXT pContext, bool is8Bit,
BYTE rm = (modrm & 0x07);
reg |= (rex_r << 3);
- rm |= (rex_b << 3);
+ BYTE rmIndex = rm | (rex_b << 3);
// 8 bit idiv without the REX prefix uses registers AH, CH, DH, BH for rm 4..8
// which is an exception from the regular register indexes.
@@ -4859,7 +4859,7 @@ DWORD64 GetModRMOperandValue(BYTE rex, BYTE* ip, PCONTEXT pContext, bool is8Bit,
}
else
{
- result = GetRegisterValueByIndex(pContext, rm);
+ result = GetRegisterValueByIndex(pContext, rmIndex);
if (mod == 1)
{
@@ -4881,10 +4881,10 @@ DWORD64 GetModRMOperandValue(BYTE rex, BYTE* ip, PCONTEXT pContext, bool is8Bit,
{
// 8 bit idiv without the REX prefix uses registers AH, CH, DH or BH for rm 4..8.
// So we shift the register index to get the real register index.
- rm -= 4;
+ rmIndex -= 4;
}
- result = (DWORD64)GetRegisterAddressByIndex(pContext, rm);
+ result = (DWORD64)GetRegisterAddressByIndex(pContext, rmIndex);
if (isAhChDhBh)
{
diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp
index ab1d66f82b..64455a355c 100644
--- a/src/vm/gcenv.ee.cpp
+++ b/src/vm/gcenv.ee.cpp
@@ -492,6 +492,17 @@ static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
pThread->SetHasPromotedBytes();
+ Frame* pTopFrame = pThread->GetFrame();
+ Object ** topStack = (Object **)pTopFrame;
+ if ((pTopFrame != ((Frame*)-1))
+ && (pTopFrame->GetVTablePtr() == InlinedCallFrame::GetMethodFrameVPtr())) {
+ // It is an InlinedCallFrame. Get SP from it.
+ InlinedCallFrame* pInlinedFrame = (InlinedCallFrame*)pTopFrame;
+ topStack = (Object **)pInlinedFrame->GetCallSiteSP();
+ }
+
+ sc->stack_limit = (uintptr_t)topStack;
+
#ifdef FEATURE_CONSERVATIVE_GC
if (g_pConfig->GetGCConservative())
{
@@ -500,14 +511,6 @@ static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
// Since we report every thing as pinned, we don't need to run following code for relocation phase.
if (sc->promotion)
{
- Frame* pTopFrame = pThread->GetFrame();
- Object ** topStack = (Object **)pTopFrame;
- if ((pTopFrame != ((Frame*)-1))
- && (pTopFrame->GetVTablePtr() == InlinedCallFrame::GetMethodFrameVPtr())) {
- // It is an InlinedCallFrame. Get SP from it.
- InlinedCallFrame* pInlinedFrame = (InlinedCallFrame*)pTopFrame;
- topStack = (Object **)pInlinedFrame->GetCallSiteSP();
- }
Object ** bottomStack = (Object **) pThread->GetCachedStackBase();
Object ** walk;
for (walk = topStack; walk < bottomStack; walk ++)
diff --git a/src/vm/siginfo.cpp b/src/vm/siginfo.cpp
index 0567b539b3..24c89a35b8 100644
--- a/src/vm/siginfo.cpp
+++ b/src/vm/siginfo.cpp
@@ -4937,12 +4937,24 @@ void PromoteCarefully(promote_func fn,
assert(flags & GC_CALL_INTERIOR);
#if !defined(DACCESS_COMPILE)
+
+ //
+ // Sanity check the stack scan limit
+ //
+ assert(sc->stack_limit != 0);
+
// Note that the base is at a higher address than the limit, since the stack
// grows downwards.
- if (sc->thread_under_crawl->IsAddressInStack(*ppObj))
+ // To check whether the object is in the stack or not, we also need to check the sc->stack_limit.
+ // The reason is that on Unix, the stack size can be unlimited. In such case, the system can
+ // shrink the current reserved stack space. That causes the real limit of the stack to move up and
+ // the range can be reused for other purposes. But the sc->stack_limit is stable during the scan.
+ // Even on Windows, we care just about the stack above the stack_limit.
+ if ((sc->thread_under_crawl->IsAddressInStack(*ppObj)) && (PTR_TO_TADDR(*ppObj) >= sc->stack_limit))
{
return;
}
+
#endif // !defined(DACCESS_COMPILE)
(*fn) (ppObj, sc, flags);