Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 1197047

Browse files
authored
Merge branch 'release/2.2' into release/2.2-UpdateDependencies
2 parents 590e0bd + 73484d4 commit 1197047

File tree

11 files changed

+250
-24
lines changed

11 files changed

+250
-24
lines changed

ILAsmVersion.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.2.2-servicing-27317-07
1+
2.2.2-servicing-27317-07

dependencies.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<PropertyGroup>
1414
<!-- Central place to set the versions of all nuget packages produced in the repo -->
15-
<PackageVersion Condition="'$(PackageVersion)' == ''">2.2.2</PackageVersion>
15+
<PackageVersion Condition="'$(PackageVersion)' == ''">2.2.3</PackageVersion>
1616

1717
<!-- Set the boolean below to true to generate packages with stabilized versions -->
1818
<StabilizePackageVersion Condition="'$(StabilizePackageVersion)' == ''">false</StabilizePackageVersion>

src/jit/compiler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2988,7 +2988,8 @@ class Compiler
29882988
CORINFO_METHOD_HANDLE* method,
29892989
unsigned* methodFlags,
29902990
CORINFO_CONTEXT_HANDLE* contextHandle,
2991-
CORINFO_CONTEXT_HANDLE* exactContextHandle);
2991+
CORINFO_CONTEXT_HANDLE* exactContextHandle,
2992+
bool isExplicitTailCall);
29922993

29932994
CORINFO_CLASS_HANDLE impGetSpecialIntrinsicExactReturnType(CORINFO_METHOD_HANDLE specialIntrinsicHandle);
29942995

src/jit/flowgraph.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22400,7 +22400,8 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(GenTr
2240022400
CORINFO_METHOD_HANDLE method = call->gtCallMethHnd;
2240122401
unsigned methodFlags = 0;
2240222402
CORINFO_CONTEXT_HANDLE context = nullptr;
22403-
comp->impDevirtualizeCall(call, &method, &methodFlags, &context, nullptr);
22403+
bool explicitTailCall = (call->gtCall.gtCallMoreFlags & GTF_CALL_M_EXPLICIT_TAILCALL) != 0;
22404+
comp->impDevirtualizeCall(call, &method, &methodFlags, &context, nullptr, explicitTailCall);
2240422405
}
2240522406
}
2240622407
}

src/jit/importer.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7941,8 +7941,9 @@ var_types Compiler::impImportCall(OPCODE opcode,
79417941
assert(obj->gtType == TYP_REF);
79427942

79437943
// See if we can devirtualize.
7944+
bool explicitTailCall = (tailCall & PREFIX_TAILCALL_EXPLICIT) != 0;
79447945
impDevirtualizeCall(call->AsCall(), &callInfo->hMethod, &callInfo->methodFlags, &callInfo->contextHandle,
7945-
&exactContextHnd);
7946+
&exactContextHnd, explicitTailCall);
79467947
}
79477948

79487949
if (impIsThis(obj))
@@ -19275,6 +19276,7 @@ bool Compiler::IsMathIntrinsic(GenTree* tree)
1927519276
// methodFlags -- [IN/OUT] flags for the method to call. Updated iff call devirtualized.
1927619277
// contextHandle -- [IN/OUT] context handle for the call. Updated iff call devirtualized.
1927719278
// exactContextHnd -- [OUT] updated context handle iff call devirtualized
19279+
// isExplicitTailCalll -- [IN] true if we plan on using an explicit tail call
1927819280
//
1927919281
// Notes:
1928019282
// Virtual calls in IL will always "invoke" the base class method.
@@ -19303,7 +19305,8 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
1930319305
CORINFO_METHOD_HANDLE* method,
1930419306
unsigned* methodFlags,
1930519307
CORINFO_CONTEXT_HANDLE* contextHandle,
19306-
CORINFO_CONTEXT_HANDLE* exactContextHandle)
19308+
CORINFO_CONTEXT_HANDLE* exactContextHandle,
19309+
bool isExplicitTailCall)
1930719310
{
1930819311
assert(call != nullptr);
1930919312
assert(method != nullptr);
@@ -19598,6 +19601,12 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
1959819601
{
1959919602
JITDUMP("Now have direct call to boxed entry point, looking for unboxed entry point\n");
1960019603

19604+
if (isExplicitTailCall)
19605+
{
19606+
JITDUMP("Call is an explicit tail call, we cannot perform an unbox\n");
19607+
return;
19608+
}
19609+
1960119610
// Note for some shared methods the unboxed entry point requires an extra parameter.
1960219611
bool requiresInstMethodTableArg = false;
1960319612
CORINFO_METHOD_HANDLE unboxedEntryMethod =
@@ -19678,6 +19687,18 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
1967819687
call->gtCallObjp = localCopyThis;
1967919688
call->gtCallMethHnd = unboxedEntryMethod;
1968019689
derivedMethod = unboxedEntryMethod;
19690+
19691+
#if FEATURE_TAILCALL_OPT
19692+
if (call->IsImplicitTailCall())
19693+
{
19694+
JITDUMP("Clearing the implicit tail call flag\n");
19695+
19696+
// If set, we clear the implicit tail call flag
19697+
// as we just introduced a new address taken local variable
19698+
//
19699+
call->gtCallMoreFlags &= ~GTF_CALL_M_IMPLICIT_TAILCALL;
19700+
}
19701+
#endif // FEATURE_TAILCALL_OPT
1968119702
}
1968219703
else
1968319704
{

src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,6 @@ public override void WriteData(TraceLoggingDataCollector collector, PropertyValu
269269
internal sealed class NullableTypeInfo : TraceLoggingTypeInfo
270270
{
271271
private readonly TraceLoggingTypeInfo valueInfo;
272-
private readonly Func<PropertyValue, PropertyValue> hasValueGetter;
273272
private readonly Func<PropertyValue, PropertyValue> valueGetter;
274273

275274
public NullableTypeInfo(Type type, List<Type> recursionCheck)
@@ -278,7 +277,6 @@ public NullableTypeInfo(Type type, List<Type> recursionCheck)
278277
var typeArgs = type.GenericTypeArguments;
279278
Debug.Assert(typeArgs.Length == 1);
280279
this.valueInfo = TraceLoggingTypeInfo.GetInstance(typeArgs[0], recursionCheck);
281-
this.hasValueGetter = PropertyValue.GetPropertyGetter(type.GetTypeInfo().GetDeclaredProperty("HasValue"));
282280
this.valueGetter = PropertyValue.GetPropertyGetter(type.GetTypeInfo().GetDeclaredProperty("Value"));
283281
}
284282

@@ -294,9 +292,11 @@ public override void WriteMetadata(
294292

295293
public override void WriteData(TraceLoggingDataCollector collector, PropertyValue value)
296294
{
297-
var hasValue = hasValueGetter(value);
295+
// It's not currently possible to get the HasValue property of a nullable type through reflection when the
296+
// value is null. Instead, we simply check that the nullable is not null.
297+
var hasValue = value.ReferenceValue != null;
298298
collector.AddScalar(hasValue);
299-
var val = hasValue.ScalarValue.AsBoolean ? valueGetter(value) : valueInfo.PropertyValueFactory(Activator.CreateInstance(valueInfo.DataType));
299+
var val = hasValue ? valueGetter(value) : valueInfo.PropertyValueFactory(Activator.CreateInstance(valueInfo.DataType));
300300
this.valueInfo.WriteData(collector, val);
301301
}
302302
}

src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ public void AddScalar(double value)
8484
DataCollector.ThreadInstance.AddScalar(&value, sizeof(double));
8585
}
8686

87+
/// <summary>
88+
/// Adds a Boolean value to the event payload.
89+
/// </summary>
90+
/// <param name="value">Value to be added.</param>
91+
public void AddScalar(bool value)
92+
{
93+
DataCollector.ThreadInstance.AddScalar(&value, sizeof(bool));
94+
}
95+
8796
/// <summary>
8897
/// Adds a null-terminated String value to the event payload.
8998
/// </summary>

src/mscorlib/src/System/Diagnostics/Eventing/EventPipeMetadataGenerator.cs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ private unsafe byte[] GenerateMetadata(
7575
// level : 4 bytes
7676
// parameterCount : 4 bytes
7777
uint metadataLength = 24 + ((uint)eventName.Length + 1) * 2;
78+
uint defaultMetadataLength = metadataLength;
7879

7980
// Check for an empty payload.
8081
// Write<T> calls with no arguments by convention have a parameter of
@@ -87,7 +88,16 @@ private unsafe byte[] GenerateMetadata(
8788
// Increase the metadataLength for parameters.
8889
foreach (var parameter in parameters)
8990
{
90-
metadataLength = metadataLength + parameter.GetMetadataLength();
91+
int pMetadataLength = parameter.GetMetadataLength();
92+
// The call above may return -1 which means we failed to get the metadata length.
93+
// We then return a default metadata blob (with parameterCount of 0) to prevent it from generating malformed metadata.
94+
if(pMetadataLength < 0)
95+
{
96+
parameters = Array.Empty<EventParameterInfo>();
97+
metadataLength = defaultMetadataLength;
98+
break;
99+
}
100+
metadataLength += (uint)pMetadataLength;
91101
}
92102

93103
metadata = new byte[metadataLength];
@@ -107,7 +117,11 @@ private unsafe byte[] GenerateMetadata(
107117
WriteToBuffer(pMetadata, metadataLength, ref offset, (uint)parameters.Length);
108118
foreach (var parameter in parameters)
109119
{
110-
parameter.GenerateMetadata(pMetadata, ref offset, metadataLength);
120+
if(!parameter.GenerateMetadata(pMetadata, ref offset, metadataLength))
121+
{
122+
// If we fail to generate metadata for any parameter, we should return the "default" metadata without any parameters
123+
return GenerateMetadata(eventId, eventName, keywords, level, version, Array.Empty<EventParameterInfo>());
124+
}
111125
}
112126
Debug.Assert(metadataLength == offset);
113127
}
@@ -174,7 +188,7 @@ internal void SetInfo(string name, Type type, TraceLoggingTypeInfo typeInfo = nu
174188
TypeInfo = typeInfo;
175189
}
176190

177-
internal unsafe void GenerateMetadata(byte* pMetadataBlob, ref uint offset, uint blobSize)
191+
internal unsafe bool GenerateMetadata(byte* pMetadataBlob, ref uint offset, uint blobSize)
178192
{
179193
TypeCode typeCode = GetTypeCodeExtended(ParameterType);
180194
if(typeCode == TypeCode.Object)
@@ -189,7 +203,7 @@ internal unsafe void GenerateMetadata(byte* pMetadataBlob, ref uint offset, uint
189203
InvokeTypeInfo invokeTypeInfo = TypeInfo as InvokeTypeInfo;
190204
if(invokeTypeInfo == null)
191205
{
192-
throw new NotSupportedException();
206+
return false;
193207
}
194208

195209
// Get the set of properties to be serialized.
@@ -201,7 +215,10 @@ internal unsafe void GenerateMetadata(byte* pMetadataBlob, ref uint offset, uint
201215

202216
foreach(PropertyAnalysis prop in properties)
203217
{
204-
GenerateMetadataForProperty(prop, pMetadataBlob, ref offset, blobSize);
218+
if(!GenerateMetadataForProperty(prop, pMetadataBlob, ref offset, blobSize))
219+
{
220+
return false;
221+
}
205222
}
206223
}
207224
else
@@ -225,9 +242,10 @@ internal unsafe void GenerateMetadata(byte* pMetadataBlob, ref uint offset, uint
225242
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte *)pParameterName, ((uint)ParameterName.Length + 1) * 2);
226243
}
227244
}
245+
return true;
228246
}
229247

230-
private static unsafe void GenerateMetadataForProperty(PropertyAnalysis property, byte* pMetadataBlob, ref uint offset, uint blobSize)
248+
private static unsafe bool GenerateMetadataForProperty(PropertyAnalysis property, byte* pMetadataBlob, ref uint offset, uint blobSize)
231249
{
232250
Debug.Assert(property != null);
233251
Debug.Assert(pMetadataBlob != null);
@@ -252,7 +270,10 @@ private static unsafe void GenerateMetadataForProperty(PropertyAnalysis property
252270

253271
foreach(PropertyAnalysis prop in properties)
254272
{
255-
GenerateMetadataForProperty(prop, pMetadataBlob, ref offset, blobSize);
273+
if(!GenerateMetadataForProperty(prop, pMetadataBlob, ref offset, blobSize))
274+
{
275+
return false;
276+
}
256277
}
257278
}
258279
else
@@ -274,10 +295,10 @@ private static unsafe void GenerateMetadataForProperty(PropertyAnalysis property
274295
// PropertyName : NULL-terminated string
275296
TypeCode typeCode = GetTypeCodeExtended(property.typeInfo.DataType);
276297

277-
// EventPipe does not support this type. Throw, which will cause no metadata to be registered for this event.
298+
// EventPipe does not support this type. Return false, which will cause no metadata to be registered for this event.
278299
if(typeCode == TypeCode.Object)
279300
{
280-
throw new NotSupportedException();
301+
return false;
281302
}
282303

283304
// Write the type code.
@@ -289,20 +310,21 @@ private static unsafe void GenerateMetadataForProperty(PropertyAnalysis property
289310
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte *)pPropertyName, ((uint)property.name.Length + 1) * 2);
290311
}
291312
}
313+
return true;
292314
}
293315

294316

295-
internal unsafe uint GetMetadataLength()
317+
internal unsafe int GetMetadataLength()
296318
{
297-
uint ret = 0;
319+
int ret = 0;
298320

299321
TypeCode typeCode = GetTypeCodeExtended(ParameterType);
300322
if(typeCode == TypeCode.Object)
301323
{
302324
InvokeTypeInfo typeInfo = TypeInfo as InvokeTypeInfo;
303325
if(typeInfo == null)
304326
{
305-
throw new NotSupportedException();
327+
return -1;
306328
}
307329

308330
// Each nested struct is serialized as:
@@ -319,7 +341,7 @@ internal unsafe uint GetMetadataLength()
319341
{
320342
foreach(PropertyAnalysis prop in properties)
321343
{
322-
ret += GetMetadataLengthForProperty(prop);
344+
ret += (int)GetMetadataLengthForProperty(prop);
323345
}
324346
}
325347

@@ -330,7 +352,7 @@ internal unsafe uint GetMetadataLength()
330352
}
331353
else
332354
{
333-
ret += (uint)(sizeof(uint) + ((ParameterName.Length + 1) * 2));
355+
ret += (int)(sizeof(uint) + ((ParameterName.Length + 1) * 2));
334356
}
335357

336358
return ret;
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
6+
// Metadata version: v4.0.30319
7+
.assembly extern mscorlib
8+
{
9+
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
10+
.ver 4:0:0:0
11+
}
12+
.assembly test
13+
{
14+
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
15+
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
16+
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
17+
.hash algorithm 0x00008004
18+
.ver 0:0:0:0
19+
}
20+
.module test.exe
21+
// MVID: {A80A87C4-1DDB-4F93-AB31-444266FDFA55}
22+
.imagebase 0x00400000
23+
.file alignment 0x00000200
24+
.stackreserve 0x00100000
25+
.subsystem 0x0003 // WINDOWS_CUI
26+
.corflags 0x00000001 // ILONLY
27+
// Image base: 0x0000024A58020000
28+
29+
30+
// =============== CLASS MEMBERS DECLARATION ===================
31+
32+
.class private auto ansi beforefieldinit Program
33+
extends [mscorlib]System.Object
34+
{
35+
.method public hidebysig instance string
36+
Test(int32 val) cil managed noinlining
37+
{
38+
// This testcase ensures that we don't perform devirtualization
39+
// via an unboxing optimization, for the callvirt below.
40+
41+
// Code size 12 (0xc)
42+
.maxstack 8
43+
IL_0000: ldarg.1
44+
IL_0001: box [mscorlib]System.Int32
45+
tail.
46+
IL_0006: callvirt instance string [mscorlib]System.Object::ToString()
47+
IL_000b: ret
48+
} // end of method Program::Test
49+
50+
.method private hidebysig static int32
51+
Main(string[] args) cil managed
52+
{
53+
.entrypoint
54+
// Code size 73 (0x49)
55+
.maxstack 2
56+
.locals init (int32 V_0,
57+
class Program V_1,
58+
string V_2)
59+
IL_0000: ldc.i4.m1
60+
IL_0001: stloc.0
61+
IL_0002: newobj instance void Program::.ctor()
62+
IL_0007: stloc.1
63+
IL_0008: ldloc.1
64+
IL_0009: ldc.i4.s 42
65+
IL_000b: callvirt instance string Program::Test(int32)
66+
IL_0010: stloc.2
67+
IL_0011: ldloc.2
68+
IL_0012: ldstr "42"
69+
IL_0017: call bool [mscorlib]System.String::op_Equality(string,
70+
string)
71+
IL_001c: brfalse.s IL_002d
72+
73+
IL_001e: ldstr "=== PASSED ==="
74+
IL_0023: call void [mscorlib]System.Console::WriteLine(string)
75+
IL_0028: ldc.i4.s 100
76+
IL_002a: stloc.0
77+
IL_002b: br.s IL_0047
78+
79+
IL_002d: ldstr "result shoudl be 42, is= "
80+
IL_0032: ldloc.2
81+
IL_0033: call string [mscorlib]System.String::Concat(string,
82+
string)
83+
IL_0038: call void [mscorlib]System.Console::WriteLine(string)
84+
IL_003d: ldstr "+++ FAILED +++"
85+
IL_0042: call void [mscorlib]System.Console::WriteLine(string)
86+
IL_0047: ldloc.0
87+
IL_0048: ret
88+
} // end of method Program::Main
89+
90+
.method public hidebysig specialname rtspecialname
91+
instance void .ctor() cil managed
92+
{
93+
// Code size 7 (0x7)
94+
.maxstack 8
95+
IL_0000: ldarg.0
96+
IL_0001: call instance void [mscorlib]System.Object::.ctor()
97+
IL_0006: ret
98+
} // end of method Program::.ctor
99+
100+
} // end of class Program
101+
102+
103+
// =============================================================
104+
105+
// *********** DISASSEMBLY COMPLETE ***********************
106+
// WARNING: Created Win32 resource file test2.res

0 commit comments

Comments
 (0)