Skip to content
This repository has been archived by the owner on Aug 24, 2022. It is now read-only.

Unconstrained generic parameters generate inefficient struct copies #107

Open
kg opened this issue Jun 26, 2012 · 1 comment
Open

Unconstrained generic parameters generate inefficient struct copies #107

kg opened this issue Jun 26, 2012 · 1 comment

Comments

@kg
Copy link
Member

kg commented Jun 26, 2012

As described in issue #105, if a function or class has a generic parameter that is constrained, you can pass a struct as the parameter. This will cause behavior to diverge from C# because the body of the generic method(s) is not generated with struct copies in the appropriate place(s) because the generic parameter is not a struct according to TypeUtil.

At present, if the parameter is constrained with ': struct', copies will be generated, but a complete solution needs to ensure that it works at runtime if you pass a struct as an unconstrained generic parameter.

This probably means that for generic methods, and all methods within a generic class, function bodies should be generated as if all the generic parameters are structs, and then instead of .MemberwiseClone(), a special .CloneForParameter(T) is inserted instead. Then as an optimization, some codegen can be done on the fly in $Of$NoInitialize to remove the clone calls if a parameter is known not to be a struct.

kg added a commit that referenced this issue Jul 3, 2012
…CloneParameter' where a struct copy would normally go, to ensure that a conditional struct copy is performed when the generic parameter type is a struct. If the parameter is constrained with 'struct', an unconditional copy is generated instead, and if it is constrained with 'class', no copy is generated. Partial fix for issue #107.

Move StructGenericParameter.cs to FailingTestCases because it relies on object.ReferenceEquals returning false due to structs always being  implicitly copied.
@kg
Copy link
Member Author

kg commented Jul 3, 2012

6cf8588 fixes this, with two caveats:

The optimizer is too clever so it will (safely) eliminate some copies, which has the side effect of causing object.ReferenceEquals to return true when it would return false in the .NET runtime (because casting a struct to an interface pointer doesn't box it or cause a copy, I think). This means that StructGenericParameter.cs does not pass.

The JSIL.CloneParameter calls probably have a tangible performance impact in loops and they could also introduce failures in unusual code paths. The right fix here is probably to dynamically convert the CloneParameter calls into MemberwiseClone calls (or remove them) based on the actual type of the parameter (in .Of() for generic types, and when binding generic parameters for generic methods).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant