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

PropertyDescriptor improvements #1648

Merged
merged 3 commits into from
Oct 16, 2023

Conversation

viruscamp
Copy link
Contributor

PropertyDescriptor improvements
add PropertyFlag.NonData
now PropertyDescriptors for CLR Field, Property and Indexer are accessor property descriptors.

By treating CLR Property as accessor property, it will reduce the time of call to Property Getter.

add PropertyFlag.NonData
now PropertyDescriptor's for Clr Field, Property and Indexer are accessor property descriptors
@viruscamp
Copy link
Contributor Author

Here is a test, which fail in the main branch current:

    class TestClass
    {
        public static readonly TestClass Instance = new TestClass();

        private int x = 1;
        public int PropertySideEffect => x++;
    }

    [Fact]
    public void ClrPropertySideEffect()
    {
        _engine.SetValue("testClass", TestClass.Instance);
        _engine.Execute("""
            const handler = {
              get(target, property, receiver) {
                return 2; // the same value to second call, make data property check happy
              }
            };
            const p = new Proxy(testClass, handler);
        """);

        Assert.Equal(1, TestClass.Instance.PropertySideEffect); // first call to PropertySideEffect
        Assert.Equal(2, _engine.Evaluate("p.PropertySideEffect").AsInteger()); // no call to PropertySideEffect
        Assert.Equal(2, TestClass.Instance.PropertySideEffect); // second call to PropertySideEffect
    }

@viruscamp
Copy link
Contributor Author

IMO, PropertyFlag.CustomJsValue and PropertyFlag.NonData should not be flags, they should be a readonly Property.

class PropertyDescriptor {
  public bool CustomJsValue => false;
  public bool NonData=> false;
}

class ReflectionDescriptor {
  public bool CustomJsValue => true;
  public bool NonData=> true;
}

@lahma
Copy link
Collaborator

lahma commented Oct 14, 2023

So if this is about performance (and to validate there's not regressions), could you show show some benchmark results before/after?

@viruscamp
Copy link
Contributor Author

So if this is about performance (and to validate there's not regressions), could you show show some benchmark results before/after?

It's not about performance mainly. It changed the behavior by making CLR Property and Indexer to be js accessor descriptor instead of data descriptor. So, the PropertyDescriptor.IsDataDescriptor method won't call the CLR Property/Indexer Getter to avoid the side effect in the CLR Property/Indexer Getter.

I think PropertyDescriptor.IsDataDescriptor is mainly used in JsProxy get/set, it may acclerate them for GetSetPropertyDescriptor and ReflectionDescriptor a little.
In a data descriptor(the original PropertyDescriptor), I added an additional check to NonData flag.

It's maybe a problem that CLR Field is also js accessor descriptor now.

@viruscamp
Copy link
Contributor Author

cd Jint.Tests.Test262
LC_ALL=C dotnet test

property-descriptor-nondata 64ee20f

Passed!  - Failed:     0, Passed: 56295, Skipped: 11583, Total: 67878, Duration: 1 m 31 s - Jint.Tests.Test262.dll (net6.0)
Passed!  - Failed:     0, Passed: 56295, Skipped: 11583, Total: 67878, Duration: 1 m 30 s - Jint.Tests.Test262.dll (net6.0)
Passed!  - Failed:     0, Passed: 56295, Skipped: 11583, Total: 67878, Duration: 1 m 31 s - Jint.Tests.Test262.dll (net6.0)

main 8ebdc34

Passed!  - Failed:     0, Passed: 56295, Skipped: 11583, Total: 67878, Duration: 1 m 31 s - Jint.Tests.Test262.dll (net6.0)
Passed!  - Failed:     0, Passed: 56295, Skipped: 11583, Total: 67878, Duration: 1 m 30 s - Jint.Tests.Test262.dll (net6.0)
Passed!  - Failed:     0, Passed: 56295, Skipped: 11583, Total: 67878, Duration: 1 m 30 s - Jint.Tests.Test262.dll (net6.0)

@lahma
Copy link
Collaborator

lahma commented Oct 16, 2023

Generally we can't tell much about performance by reading test run timings, there's a lot more going on there. But this seems quite safe and covered with tests, thank you for your contribution.

@lahma lahma merged commit 89a1b61 into sebastienros:main Oct 16, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants