Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RuntimeModule::ResolveLiteralField has unnecessary call to Type.GetFields() #45986

Closed
eerhardt opened this issue Dec 11, 2020 · 4 comments
Closed
Assignees
Labels
area-System.Reflection runtime-coreclr specific to the CoreCLR runtime
Milestone

Comments

@eerhardt
Copy link
Member

We have the following code:

Type declaringType = ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
declaringType.GetFields();
try
{
return declaringType.GetField(fieldName,
BindingFlags.Static | BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.DeclaredOnly);

The call to declaringType.GetFields(); doesn't do anything with the resulting array of FieldInfos, and looks like it can be removed. If we can, we should remove it. If we can't remove it, we should add a comment why that line is necessary.

One thought I had was maybe the call to GetFields() "warmed up" the Type's cache of fields. But I would hope that the call to GetField(fieldName) would be valid even without the previous call to GetFields().

I searched the internal source code history back to December 2003, and it appears this line has always existed since this method was first written. So my initial suspicion is that it is a left-over line of code when the feature we first developed.


Another related issue is that I can't seem to find out how RuntimeModule::ResolveLiteralField would ever actually be called. The only call-site is in the public ResolveField method, but only when a MissingMethodException is thrown. The problem is - I didn't find a place inside the try-catch that throws a MissingMethodException. Maybe it is coming from the clr runtime?

If we are going to remove the above line, we should try to find a way to unit test this code to get it executed to ensure it still works as necessary. If we can't find a way to exercise this code, maybe the whole method should be removed?

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Dec 11, 2020
@joperezr
Copy link
Member

cc: @steveharter

@joperezr joperezr removed the untriaged New issue has not been triaged by the area owner label Feb 23, 2021
@steveharter
Copy link
Member

It is unfortunate the line is not commented. The only case I can think of is that it is an attempt on making field access predicable later when calling GetFields(). When calling the singular GetField() only that field is added to the cache, and when the plural GetFields() is called, it appends to that cache meaning the order of the various GetField() calls impact the ordering of GetFields().

However, if this is the reason for that line of code, it may not have the desired semantics of somewhere else called GetField() previously.

See also #46272 for the issue of having consistent ordering of properties.

A sample:

    class Program
    {
        static void Main(string[] args)
        {
            // Uncommenting these makes B and _b come first:
            //typeof(Foo).GetProperty("B");
            //typeof(Foo).GetField("_b");

            GetMembers();
        }

        static void GetMembers()
        {
            foreach (PropertyInfo p in typeof(Foo).GetProperties())
            {
                Console.WriteLine(p.Name);
            }

            foreach (FieldInfo f in typeof(Foo).GetFields())
            {
                Console.WriteLine(f.Name);
            }
        }
    }

    public class Foo
    {
        public int _a;
        public int _b;
        public int A { get; set; }
        public int B { get; set; }
    }

@ghost ghost added the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Feb 23, 2021
@buyaa-n
Copy link
Member

buyaa-n commented Mar 2, 2021

We can remove that row after #46272 implemented, keeping this issue as a reminder for that

@buyaa-n buyaa-n added this to the Future milestone Mar 2, 2021
@buyaa-n buyaa-n removed the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Mar 2, 2021
@ghost ghost added the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Mar 2, 2021
@buyaa-n buyaa-n removed the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Mar 2, 2021
@marek-safar marek-safar added the runtime-coreclr specific to the CoreCLR runtime label Mar 2, 2021
@buyaa-n
Copy link
Member

buyaa-n commented Oct 27, 2022

Fixed with #77497

@buyaa-n buyaa-n closed this as completed Oct 27, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Nov 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Reflection runtime-coreclr specific to the CoreCLR runtime
Projects
No open projects
Development

No branches or pull requests

6 participants