Skip to content

Conversation

hvitved
Copy link
Contributor

@hvitved hvitved commented Jun 4, 2021

Fixes github/codeql-action#544.

https://jenkins.internal.semmle.com/job/Changes/job/CSharp-Differences/1128/

This improves TRAP import time significantly on some projects:
Screenshot 2021-06-15 at 09 13 02

@github-actions github-actions bot added the C# label Jun 4, 2021
@@ -52,6 +54,10 @@ protected void DefineLabel(IEntity entity)
finally
{
writingLabel = false;
if (labelQueue.Any())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be while loop rather than an if so that we write out all the labels from the queue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DefineLabel is recursive, so a while loop is not needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This recursion might result in strange behavior: the first item (entity A) in the queue is dequeued, and if in the meantime DefineLabel is being called on another entity, then entity A might be enqueued again, which means it goes to the end of the queue, so the queue doesn't give any guarantee on the ordering.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order is not super important, what matters is that we populate the labels as early as possible. For example, for a method like

IEnumerable<int> M(string s) { }

we will (simplified) generate the following TRAP:

#0 = {#1} M({#2} s)
#1 = {#3}<{#4}>
#2 = "string"
#3 = "IEnumerable<>"
#4 = "int"

so we are still using labels before their definition, but the definition will follow shortly after, as opposed to the old implementation.

@hvitved hvitved marked this pull request as ready for review June 15, 2021 07:15
@hvitved hvitved requested a review from a team as a code owner June 15, 2021 07:15
protected void DefineLabel(IEntity entity)
{
if (writingLabel)
{
// Don't define a label whilst writing a label.
PopulateLater(() => DefineLabel(entity));
labelQueue.Enqueue(entity);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a guarantee that labelQueue gets emptied? It seems possible that there are items left in the queue:
Thread 1 starts defining label on entity A (writingLabel == true), Thread 2 enters if (writingLabel), Thread 1 finishes all the work even the finally block, and then Thread 2 enqueues the entity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's all single threaded: Multi-threading is only for extracting different files in parallel.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I should have known this. 🤦

@hvitved hvitved merged commit 501ba4b into github:main Jun 15, 2021
@hvitved hvitved deleted the csharp/early-labels branch June 15, 2021 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Process failed with exit code 100
3 participants