Skip to content

Commit 7c62502

Browse files
authored
Add support for FieldRva to EnC delta (#78033)
1 parent df41241 commit 7c62502

File tree

105 files changed

+2497
-595
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+2497
-595
lines changed

src/Compilers/CSharp/Portable/CSharpResources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5314,6 +5314,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
53145314
<data name="ERR_TooManyUserStrings" xml:space="preserve">
53155315
<value>Combined length of user strings used by the program exceeds allowed limit. Try to decrease use of string literals or try the EXPERIMENTAL feature flag 'experimental-data-section-string-literals'.</value>
53165316
</data>
5317+
<data name="ERR_TooManyUserStrings_RestartRequired" xml:space="preserve">
5318+
<value>Combined length of user strings used by the program exceeds allowed limit. Adding a string literal requires restarting the application.</value>
5319+
</data>
53175320
<data name="ERR_PatternNullableType" xml:space="preserve">
53185321
<value>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</value>
53195322
</data>

src/Compilers/CSharp/Portable/CodeGen/CodeGenerator.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ private void HandleReturn()
338338

339339
private void EmitTypeReferenceToken(Cci.ITypeReference symbol, SyntaxNode syntaxNode)
340340
{
341-
_builder.EmitToken(symbol, syntaxNode, _diagnostics.DiagnosticBag);
341+
_builder.EmitToken(symbol, syntaxNode);
342342
}
343343

344344
private void EmitSymbolToken(TypeSymbol symbol, SyntaxNode syntaxNode)
@@ -349,18 +349,18 @@ private void EmitSymbolToken(TypeSymbol symbol, SyntaxNode syntaxNode)
349349
private void EmitSymbolToken(MethodSymbol method, SyntaxNode syntaxNode, BoundArgListOperator optArgList, bool encodeAsRawDefinitionToken = false)
350350
{
351351
var methodRef = _module.Translate(method, syntaxNode, _diagnostics.DiagnosticBag, optArgList, needDeclaration: encodeAsRawDefinitionToken);
352-
_builder.EmitToken(methodRef, syntaxNode, _diagnostics.DiagnosticBag, encodeAsRawDefinitionToken ? Cci.MetadataWriter.RawTokenEncoding.RowId : 0);
352+
_builder.EmitToken(methodRef, syntaxNode, encodeAsRawDefinitionToken ? Cci.MetadataWriter.RawTokenEncoding.RowId : 0);
353353
}
354354

355355
private void EmitSymbolToken(FieldSymbol symbol, SyntaxNode syntaxNode)
356356
{
357357
var fieldRef = _module.Translate(symbol, syntaxNode, _diagnostics.DiagnosticBag);
358-
_builder.EmitToken(fieldRef, syntaxNode, _diagnostics.DiagnosticBag);
358+
_builder.EmitToken(fieldRef, syntaxNode);
359359
}
360360

361361
private void EmitSignatureToken(FunctionPointerTypeSymbol symbol, SyntaxNode syntaxNode)
362362
{
363-
_builder.EmitToken(_module.Translate(symbol).Signature, syntaxNode, _diagnostics.DiagnosticBag);
363+
_builder.EmitToken(_module.Translate(symbol).Signature, syntaxNode);
364364
}
365365

366366
private void EmitSequencePointStatement(BoundSequencePoint node)
@@ -444,25 +444,25 @@ private void EmitRestorePreviousSequencePoint(BoundRestorePreviousSequencePoint
444444
if (_savedSequencePoints is null || !_savedSequencePoints.TryGetValue(node.Identifier, out var span))
445445
return;
446446

447-
EmitStepThroughSequencePoint(node.Syntax.SyntaxTree, span);
447+
EmitStepThroughSequencePoint(node.Syntax, span);
448448
}
449449

450450
private void EmitStepThroughSequencePoint(BoundStepThroughSequencePoint node)
451451
{
452-
EmitStepThroughSequencePoint(node.Syntax.SyntaxTree, node.Span);
452+
EmitStepThroughSequencePoint(node.Syntax, node.Span);
453453
}
454454

455-
private void EmitStepThroughSequencePoint(SyntaxTree syntaxTree, TextSpan span)
455+
private void EmitStepThroughSequencePoint(SyntaxNode syntaxNode, TextSpan span)
456456
{
457457
if (!_emitPdbSequencePoints)
458458
return;
459459

460460
var label = new object();
461461
// The IL builder is eager to discard unreachable code, so
462462
// we fool it by branching on a condition that is always true at runtime.
463-
_builder.EmitConstantValue(ConstantValue.Create(true));
463+
_builder.EmitConstantValue(ConstantValue.Create(true), syntaxNode);
464464
_builder.EmitBranch(ILOpCode.Brtrue, label);
465-
EmitSequencePoint(syntaxTree, span);
465+
EmitSequencePoint(syntaxNode.SyntaxTree, span);
466466
_builder.EmitOpCode(ILOpCode.Nop);
467467
_builder.MarkLabel(label);
468468
EmitHiddenSequencePoint();

src/Compilers/CSharp/Portable/CodeGen/EmitAddress.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ private void EmitArrayElementAddress(BoundArrayAccess arrayAccess, AddressKind a
409409
else
410410
{
411411
_builder.EmitArrayElementAddress(_module.Translate((ArrayTypeSymbol)arrayAccess.Expression.Type),
412-
arrayAccess.Syntax, _diagnostics.DiagnosticBag);
412+
arrayAccess.Syntax);
413413
}
414414
}
415415

src/Compilers/CSharp/Portable/CodeGen/EmitArrayInitializer.cs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private void EmitArrayInitializers(ArrayTypeSymbol arrayType, BoundArrayInitiali
5555
{
5656
ImmutableArray<byte> data = this.GetRawData(initExprs);
5757

58-
_builder.EmitArrayBlockInitializer(data, inits.Syntax, _diagnostics.DiagnosticBag);
58+
_builder.EmitArrayBlockInitializer(data, inits.Syntax);
5959

6060
if (initializationStyle == ArrayInitializerStyle.Mixed)
6161
{
@@ -245,10 +245,9 @@ private bool EnableEnumArrayBlockInitialization
245245

246246
private ArrayInitializerStyle ShouldEmitBlockInitializer(TypeSymbol elementType, ImmutableArray<BoundExpression> inits)
247247
{
248-
if (_module.IsEncDelta)
248+
if (!_module.FieldRvaSupported)
249249
{
250-
// Avoid using FieldRva table. Can be allowed if tested on all supported runtimes.
251-
// Consider removing: https://github.com/dotnet/roslyn/issues/69480
250+
// Avoid using FieldRva table when not supported by the runtime.
252251
return ArrayInitializerStyle.Element;
253252
}
254253

@@ -449,10 +448,9 @@ private bool TryEmitOptimizedReadonlySpanCreation(NamedTypeSymbol spanType, Boun
449448
return true;
450449
}
451450

452-
if (_module.IsEncDelta)
451+
if (!_module.FieldRvaSupported)
453452
{
454-
// Avoid using FieldRva table. Can be allowed if tested on all supported runtimes.
455-
// Consider removing: https://github.com/dotnet/roslyn/issues/69480
453+
// Avoid using FieldRva table when not supported by the runtime.
456454
return false;
457455
}
458456

@@ -556,7 +554,7 @@ private bool TryEmitOptimizedReadonlySpanCreation(NamedTypeSymbol spanType, Boun
556554
// Map a field to the block (that makes it addressable).
557555
var field = _builder.module.GetFieldForData(data, alignment: 1, wrappedExpression.Syntax, _diagnostics.DiagnosticBag);
558556
_builder.EmitOpCode(ILOpCode.Ldsflda);
559-
_builder.EmitToken(field, wrappedExpression.Syntax, _diagnostics.DiagnosticBag);
557+
_builder.EmitToken(field, wrappedExpression.Syntax);
560558

561559
_builder.EmitIntConstant(lengthForConstructor);
562560

@@ -617,7 +615,7 @@ private bool TryEmitOptimizedReadonlySpanCreation(NamedTypeSymbol spanType, Boun
617615
// call ReadOnlySpan<elementType> RuntimeHelpers::CreateSpan<elementType>(fldHandle)
618616
var field = _builder.module.GetFieldForData(data, alignment: (ushort)specialElementType.SizeInBytes(), wrappedExpression.Syntax, _diagnostics.DiagnosticBag);
619617
_builder.EmitOpCode(ILOpCode.Ldtoken);
620-
_builder.EmitToken(field, wrappedExpression.Syntax, _diagnostics.DiagnosticBag);
618+
_builder.EmitToken(field, wrappedExpression.Syntax);
621619
_builder.EmitOpCode(ILOpCode.Call, stackAdjustment: 0);
622620
EmitSymbolToken(createSpan.Construct(elementType), wrappedExpression.Syntax, optArgList: null);
623621
return true;
@@ -654,7 +652,7 @@ bool tryEmitAsCachedArrayFromBlob(NamedTypeSymbol spanType, BoundExpression wrap
654652
// T[]? array = PrivateImplementationDetails.cachingField;
655653
// if (array is not null) goto arrayNotNull;
656654
_builder.EmitOpCode(ILOpCode.Ldsfld);
657-
_builder.EmitToken(cachingField, wrappedExpression.Syntax, _diagnostics.DiagnosticBag);
655+
_builder.EmitToken(cachingField, wrappedExpression.Syntax);
658656
_builder.EmitOpCode(ILOpCode.Dup);
659657
_builder.EmitBranch(ILOpCode.Brtrue, arrayNotNullLabel);
660658

@@ -665,10 +663,10 @@ bool tryEmitAsCachedArrayFromBlob(NamedTypeSymbol spanType, BoundExpression wrap
665663
_builder.EmitIntConstant(elementCount);
666664
_builder.EmitOpCode(ILOpCode.Newarr);
667665
EmitSymbolToken(arrayType.ElementType, wrappedExpression.Syntax);
668-
_builder.EmitArrayBlockInitializer(data, wrappedExpression.Syntax, _diagnostics.DiagnosticBag);
666+
_builder.EmitArrayBlockInitializer(data, wrappedExpression.Syntax);
669667
_builder.EmitOpCode(ILOpCode.Dup);
670668
_builder.EmitOpCode(ILOpCode.Stsfld);
671-
_builder.EmitToken(cachingField, wrappedExpression.Syntax, _diagnostics.DiagnosticBag);
669+
_builder.EmitToken(cachingField, wrappedExpression.Syntax);
672670

673671
// arrayNotNullLabel:
674672
// new ReadOnlySpan<T>(array)
@@ -714,7 +712,7 @@ bool tryEmitAsCachedArrayOfConstants(BoundArrayCreation arrayCreation, ArrayType
714712
// T[]? array = PrivateImplementationDetails.cachingField;
715713
// if (array is not null) goto arrayNotNull;
716714
_builder.EmitOpCode(ILOpCode.Ldsfld);
717-
_builder.EmitToken(cachingField, arrayCreation.Syntax, _diagnostics.DiagnosticBag);
715+
_builder.EmitToken(cachingField, arrayCreation.Syntax);
718716
_builder.EmitOpCode(ILOpCode.Dup);
719717
_builder.EmitBranch(ILOpCode.Brtrue, arrayNotNullLabel);
720718

@@ -724,7 +722,7 @@ bool tryEmitAsCachedArrayOfConstants(BoundArrayCreation arrayCreation, ArrayType
724722
EmitExpression(arrayCreation, used: true);
725723
_builder.EmitOpCode(ILOpCode.Dup);
726724
_builder.EmitOpCode(ILOpCode.Stsfld);
727-
_builder.EmitToken(cachingField, arrayCreation.Syntax, _diagnostics.DiagnosticBag);
725+
_builder.EmitToken(cachingField, arrayCreation.Syntax);
728726

729727
// arrayNotNullLabel:
730728
// new ReadOnlySpan<T>(array)

src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
using System.Runtime.CompilerServices;
1212
using Microsoft.CodeAnalysis.CodeGen;
1313
using Microsoft.CodeAnalysis.CSharp.Symbols;
14+
using Microsoft.CodeAnalysis.Emit;
1415
using Microsoft.CodeAnalysis.PooledObjects;
1516
using Roslyn.Utilities;
1617

1718
using static System.Linq.ImmutableArrayExtensions;
18-
using static Microsoft.CodeAnalysis.CSharp.Binder;
1919

2020
namespace Microsoft.CodeAnalysis.CSharp.CodeGen
2121
{
@@ -1098,7 +1098,7 @@ private void EmitArrayElementLoad(BoundArrayAccess arrayAccess, bool used)
10981098
}
10991099
else
11001100
{
1101-
_builder.EmitArrayElementLoad(_module.Translate((ArrayTypeSymbol)arrayAccess.Expression.Type), arrayAccess.Expression.Syntax, _diagnostics.DiagnosticBag);
1101+
_builder.EmitArrayElementLoad(_module.Translate((ArrayTypeSymbol)arrayAccess.Expression.Type), arrayAccess.Expression.Syntax);
11021102
}
11031103

11041104
EmitPopIfUnused(used);
@@ -2382,7 +2382,7 @@ private void EmitArrayCreationExpression(BoundArrayCreation expression, bool use
23822382
}
23832383
else
23842384
{
2385-
_builder.EmitArrayCreation(_module.Translate(arrayType), expression.Syntax, _diagnostics.DiagnosticBag);
2385+
_builder.EmitArrayCreation(_module.Translate(arrayType), expression.Syntax);
23862386
}
23872387

23882388
if (expression.InitializerOpt != null)
@@ -3200,7 +3200,7 @@ private void EmitArrayElementStore(ArrayTypeSymbol arrayType, SyntaxNode syntaxN
32003200
}
32013201
else
32023202
{
3203-
_builder.EmitArrayElementStore(_module.Translate(arrayType), syntaxNode, _diagnostics.DiagnosticBag);
3203+
_builder.EmitArrayElementStore(_module.Translate(arrayType), syntaxNode);
32043204
}
32053205
}
32063206

@@ -3438,7 +3438,7 @@ private void EmitDefaultValue(TypeSymbol type, bool used, SyntaxNode syntaxNode)
34383438
var constantValue = type.GetDefaultValue();
34393439
if (constantValue != null)
34403440
{
3441-
_builder.EmitConstantValue(constantValue);
3441+
_builder.EmitConstantValue(constantValue, syntaxNode);
34423442
return;
34433443
}
34443444
}
@@ -3474,44 +3474,28 @@ private void EmitDefaultExpression(BoundDefaultExpression expression, bool used)
34743474

34753475
private void EmitConstantExpression(TypeSymbol type, ConstantValue constantValue, bool used, SyntaxNode syntaxNode)
34763476
{
3477-
if (used) // unused constant has no side-effects
3477+
// unused constant has no side-effects
3478+
if (!used)
34783479
{
3479-
// Null type parameter values must be emitted as 'initobj' rather than 'ldnull'.
3480-
if (((object)type != null) && (type.TypeKind == TypeKind.TypeParameter) && constantValue.IsNull)
3481-
{
3482-
EmitInitObj(type, used, syntaxNode);
3483-
}
3484-
else if (!TryEmitStringLiteralAsUtf8Encoded(constantValue, syntaxNode))
3485-
{
3486-
_builder.EmitConstantValue(constantValue);
3487-
}
3480+
return;
34883481
}
3489-
}
34903482

3491-
private bool TryEmitStringLiteralAsUtf8Encoded(ConstantValue constantValue, SyntaxNode syntaxNode)
3492-
{
3493-
// Emit long strings into data section so they don't overflow the UserString heap.
3494-
if (constantValue.IsString &&
3495-
constantValue.StringValue.Length > _module.Compilation.DataSectionStringLiteralThreshold)
3483+
// Null type parameter values must be emitted as 'initobj' rather than 'ldnull'.
3484+
if (type is { TypeKind: TypeKind.TypeParameter } && constantValue.IsNull)
34963485
{
3497-
if (Binder.GetWellKnownTypeMember(_module.Compilation, WellKnownMember.System_Text_Encoding__get_UTF8, _diagnostics, syntax: syntaxNode) == null |
3498-
Binder.GetWellKnownTypeMember(_module.Compilation, WellKnownMember.System_Text_Encoding__GetString, _diagnostics, syntax: syntaxNode) == null)
3499-
{
3500-
return false;
3501-
}
3502-
3503-
Cci.IFieldReference field = _module.TryGetOrCreateFieldForStringValue(constantValue.StringValue, syntaxNode, _diagnostics.DiagnosticBag);
3504-
if (field == null)
3486+
EmitInitObj(type, used, syntaxNode);
3487+
}
3488+
else
3489+
{
3490+
// TODO: use-site dependencies are not reported to UsedAssemblyReferences https://github.com/dotnet/roslyn/issues/78172
3491+
if (constantValue.IsString && constantValue.StringValue.Length > _module.Compilation.DataSectionStringLiteralThreshold)
35053492
{
3506-
return false;
3493+
_ = Binder.GetWellKnownTypeMember(_module.Compilation, WellKnownMember.System_Text_Encoding__get_UTF8, _diagnostics, syntax: syntaxNode);
3494+
_ = Binder.GetWellKnownTypeMember(_module.Compilation, WellKnownMember.System_Text_Encoding__GetString, _diagnostics, syntax: syntaxNode);
35073495
}
35083496

3509-
_builder.EmitOpCode(ILOpCode.Ldsfld);
3510-
_builder.EmitToken(field, syntaxNode, _diagnostics.DiagnosticBag);
3511-
return true;
3497+
_builder.EmitConstantValue(constantValue, syntaxNode);
35123498
}
3513-
3514-
return false;
35153499
}
35163500

35173501
private void EmitInitObj(TypeSymbol type, bool used, SyntaxNode syntaxNode)
@@ -3602,7 +3586,7 @@ private void EmitHoistedVariableId(FieldSymbol field, SyntaxNode syntax)
36023586
var fieldRef = _module.Translate(field, syntax, _diagnostics.DiagnosticBag, needDeclaration: true);
36033587

36043588
_builder.EmitOpCode(ILOpCode.Ldtoken);
3605-
_builder.EmitToken(fieldRef, syntax, _diagnostics.DiagnosticBag, Cci.MetadataWriter.RawTokenEncoding.LiftedVariableId);
3589+
_builder.EmitToken(fieldRef, syntax, Cci.MetadataWriter.RawTokenEncoding.LiftedVariableId);
36063590
}
36073591

36083592
private void EmitMaximumMethodDefIndexExpression(BoundMaximumMethodDefIndex node)
@@ -3628,8 +3612,7 @@ private void EmitModuleVersionIdToken(BoundModuleVersionId node)
36283612
{
36293613
_builder.EmitToken(
36303614
_module.GetModuleVersionId(_module.Translate(node.Type, node.Syntax, _diagnostics.DiagnosticBag), node.Syntax, _diagnostics.DiagnosticBag),
3631-
node.Syntax,
3632-
_diagnostics.DiagnosticBag);
3615+
node.Syntax);
36333616
}
36343617

36353618
private void EmitThrowIfModuleCancellationRequested(SyntaxNode syntax)
@@ -3639,8 +3622,7 @@ private void EmitThrowIfModuleCancellationRequested(SyntaxNode syntax)
36393622
_builder.EmitOpCode(ILOpCode.Ldsflda);
36403623
_builder.EmitToken(
36413624
_module.GetModuleCancellationToken(_module.Translate(cancellationTokenType, syntax, _diagnostics.DiagnosticBag), syntax, _diagnostics.DiagnosticBag),
3642-
syntax,
3643-
_diagnostics.DiagnosticBag);
3625+
syntax);
36443626

36453627
var throwMethod = (MethodSymbol)_module.Compilation.GetWellKnownTypeMember(WellKnownMember.System_Threading_CancellationToken__ThrowIfCancellationRequested);
36463628

@@ -3650,8 +3632,7 @@ private void EmitThrowIfModuleCancellationRequested(SyntaxNode syntax)
36503632
_builder.EmitOpCode(ILOpCode.Call, -1);
36513633
_builder.EmitToken(
36523634
_module.Translate(throwMethod, syntax, _diagnostics.DiagnosticBag),
3653-
syntax,
3654-
_diagnostics.DiagnosticBag);
3635+
syntax);
36553636
}
36563637

36573638
private void EmitModuleCancellationTokenLoad(SyntaxNode syntax)
@@ -3661,8 +3642,7 @@ private void EmitModuleCancellationTokenLoad(SyntaxNode syntax)
36613642
_builder.EmitOpCode(ILOpCode.Ldsfld);
36623643
_builder.EmitToken(
36633644
_module.GetModuleCancellationToken(_module.Translate(cancellationTokenType, syntax, _diagnostics.DiagnosticBag), syntax, _diagnostics.DiagnosticBag),
3664-
syntax,
3665-
_diagnostics.DiagnosticBag);
3645+
syntax);
36663646
}
36673647

36683648
private void EmitModuleVersionIdStringLoad()
@@ -3685,7 +3665,7 @@ private void EmitInstrumentationPayloadRootStore(BoundInstrumentationPayloadRoot
36853665

36863666
private void EmitInstrumentationPayloadRootToken(BoundInstrumentationPayloadRoot node)
36873667
{
3688-
_builder.EmitToken(_module.GetInstrumentationPayloadRoot(node.AnalysisKind, _module.Translate(node.Type, node.Syntax, _diagnostics.DiagnosticBag), node.Syntax, _diagnostics.DiagnosticBag), node.Syntax, _diagnostics.DiagnosticBag);
3668+
_builder.EmitToken(_module.GetInstrumentationPayloadRoot(node.AnalysisKind, _module.Translate(node.Type, node.Syntax, _diagnostics.DiagnosticBag), node.Syntax, _diagnostics.DiagnosticBag), node.Syntax);
36893669
}
36903670

36913671
private void EmitSourceDocumentIndex(BoundSourceDocumentIndex node)

src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ private void EmitIsNotNullOrZero(BoundExpression comparand, ConstantValue nullOr
461461
EmitBox(comparandType, comparand.Syntax);
462462
}
463463

464-
_builder.EmitConstantValue(nullOrZero);
464+
_builder.EmitConstantValue(nullOrZero, comparand.Syntax);
465465
_builder.EmitOpCode(ILOpCode.Cgt_un);
466466
}
467467

@@ -475,7 +475,7 @@ private void EmitIsNullOrZero(BoundExpression comparand, ConstantValue nullOrZer
475475
EmitBox(comparandType, comparand.Syntax);
476476
}
477477

478-
_builder.EmitConstantValue(nullOrZero);
478+
_builder.EmitConstantValue(nullOrZero, comparand.Syntax);
479479
_builder.EmitOpCode(ILOpCode.Ceq);
480480
}
481481

0 commit comments

Comments
 (0)