Skip to content

Commit 6c50d9f

Browse files
authored
Mark Go override as SkipLocalsInit if possible (#63277)
It can have so many locals that zero-initing is measurable.
1 parent 327bb30 commit 6c50d9f

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public partial class RegexGenerator
4141
};
4242

4343
/// <summary>Generates the code for one regular expression class.</summary>
44-
private static (string, ImmutableArray<Diagnostic>) EmitRegexType(RegexType regexClass)
44+
private static (string, ImmutableArray<Diagnostic>) EmitRegexType(RegexType regexClass, Compilation compilation)
4545
{
4646
var sb = new StringBuilder(1024);
4747
var writer = new IndentedTextWriter(new StringWriter(sb));
@@ -82,7 +82,7 @@ private static (string, ImmutableArray<Diagnostic>) EmitRegexType(RegexType rege
8282
generatedName += ComputeStringHash(generatedName).ToString("X");
8383

8484
// Generate the regex type
85-
ImmutableArray<Diagnostic> diagnostics = EmitRegexMethod(writer, regexClass.Method, generatedName);
85+
ImmutableArray<Diagnostic> diagnostics = EmitRegexMethod(writer, regexClass.Method, generatedName, compilation);
8686

8787
while (writer.Indent != 0)
8888
{
@@ -149,7 +149,7 @@ static bool ExceedsMaxDepthForSimpleCodeGeneration(RegexNode node, int allowedDe
149149
}
150150

151151
/// <summary>Generates the code for a regular expression method.</summary>
152-
private static ImmutableArray<Diagnostic> EmitRegexMethod(IndentedTextWriter writer, RegexMethod rm, string id)
152+
private static ImmutableArray<Diagnostic> EmitRegexMethod(IndentedTextWriter writer, RegexMethod rm, string id, Compilation compilation)
153153
{
154154
string patternExpression = Literal(rm.Pattern);
155155
string optionsExpression = Literal(rm.Options);
@@ -174,6 +174,8 @@ private static ImmutableArray<Diagnostic> EmitRegexMethod(IndentedTextWriter wri
174174
return ImmutableArray.Create(Diagnostic.Create(DiagnosticDescriptors.LimitedSourceGeneration, rm.MethodSyntax.GetLocation()));
175175
}
176176

177+
bool allowUnsafe = compilation.Options is CSharpCompilationOptions { AllowUnsafe: true };
178+
177179
writer.WriteLine($"new {id}();");
178180
writer.WriteLine();
179181
writer.WriteLine($" private {id}()");
@@ -231,6 +233,10 @@ private static ImmutableArray<Diagnostic> EmitRegexMethod(IndentedTextWriter wri
231233
writer.Indent -= 4;
232234
writer.WriteLine($" }}");
233235
writer.WriteLine();
236+
if (allowUnsafe)
237+
{
238+
writer.WriteLine($" [global::System.Runtime.CompilerServices.SkipLocalsInit]");
239+
}
234240
writer.WriteLine($" protected override void Go()");
235241
writer.WriteLine($" {{");
236242
writer.Indent += 4;

src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
4949
{
5050
Debug.Assert(state.Item1 is not null);
5151
object? result = GetRegexTypeToEmit(state.Item2, state.Item1, cancellationToken);
52-
return result is RegexType regexType ? EmitRegexType(regexType) : result;
52+
return result is RegexType regexType ? EmitRegexType(regexType, state.Item2) : result;
5353
})
5454
.Collect();
5555

src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Generators.Tests/RegexGeneratorParserTests.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,10 @@ partial class C
297297
", compile: true));
298298
}
299299

300-
[Fact]
301-
public async Task Valid_ClassWithNamespace()
300+
[Theory]
301+
[InlineData(false)]
302+
[InlineData(true)]
303+
public async Task Valid_ClassWithNamespace(bool allowUnsafe)
302304
{
303305
Assert.Empty(await RunGenerator(@"
304306
using System.Text.RegularExpressions;
@@ -310,7 +312,7 @@ partial class C
310312
private static partial Regex Valid();
311313
}
312314
}
313-
", compile: true));
315+
", compile: true, allowUnsafe: allowUnsafe));
314316
}
315317

316318
[Fact]
@@ -557,13 +559,13 @@ partial class C
557559
}
558560

559561
private async Task<IReadOnlyList<Diagnostic>> RunGenerator(
560-
string code, bool compile = false, LanguageVersion langVersion = LanguageVersion.Preview, MetadataReference[]? additionalRefs = null, CancellationToken cancellationToken = default)
562+
string code, bool compile = false, LanguageVersion langVersion = LanguageVersion.Preview, MetadataReference[]? additionalRefs = null, bool allowUnsafe = false, CancellationToken cancellationToken = default)
561563
{
562564
var proj = new AdhocWorkspace()
563565
.AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Create()))
564566
.AddProject("RegexGeneratorTest", "RegexGeneratorTest.dll", "C#")
565567
.WithMetadataReferences(additionalRefs is not null ? s_refs.Concat(additionalRefs) : s_refs)
566-
.WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
568+
.WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: allowUnsafe)
567569
.WithNullableContextOptions(NullableContextOptions.Enable))
568570
.WithParseOptions(new CSharpParseOptions(langVersion))
569571
.AddDocument("RegexGenerator.g.cs", SourceText.From(code, Encoding.UTF8)).Project;

0 commit comments

Comments
 (0)