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

Activator.CreateInstance fails to call constructor for value types #6536

Closed
gafter opened this issue Aug 22, 2016 · 6 comments
Closed

Activator.CreateInstance fails to call constructor for value types #6536

gafter opened this issue Aug 22, 2016 · 6 comments
Assignees
Milestone

Comments

@gafter
Copy link
Member

gafter commented Aug 22, 2016

See dotnet/roslyn#1029 and http://roslyn.codeplex.com/workitem/465 for some context.

The issue is basically an optimization introduced in Activator.CreateInstance around CLR 4.0 and present ever since. The optimization assumes that parameterless instantiation of generic T type does not cause sideeffects if T is found to be a struct and therefore instances can be cached. Parameterless struct constructors (which are permitted by spec) violate such assumptions and make optimization observable.

@jkotas
Copy link
Member

jkotas commented Aug 22, 2016

This code makes incorrect assumption that value types have no default constructor.

@jkotas
Copy link
Member

jkotas commented Aug 22, 2016

@gkhanna79 Could you please reassign it as appropriate?

@gkhanna79
Copy link
Member

@ramarag PTAL

@andrewjsaid
Copy link
Contributor

I read an article earlier today about Wire Serialiser where one of the optimisations was able to determine whether the constructor of a type had any side effects by counting the number of IL instructions. The author intelligently determined that any constructor with fewer than 8 IL bytes, accessed through GetILAsByteArray(), must have no side effects.

I am not familiar with the coreclr code based but I presume that the same optimisation can be used such that instead of

if (!ace.m_type.IsValueType)

we can have

// Pseudocode
if (defaultConstructor.GetILAsByteArray().Count > 8)

For reference:
See the section titled "Fast creation of empty objects" in the first link
https://rogeralsing.com/2016/08/16/wire-writing-one-of-the-fastest-net-serializers/
http://mattwarren.org/2016/08/23/Analysing-Optimisations-in-the-Wire-Serialiser/

This would then also provide a benefit to reference types which do not override the default constructor, although I am not sure whether you would also need to check all base types and whether that would be more expensive. Maybe it could be an optimisation only for those types inheriting from Object or ValueType?

@gkhanna79
Copy link
Member

@ramarag Did you take a look at this?

@gkhanna79
Copy link
Member

@kouvel Can you PTAL?

kouvel referenced this issue in kouvel/coreclr Apr 6, 2017
Fixes #6843
- Disabled caching struct types that have custom parameterless constructors in `ActivatorCache`
- Removed some things relevant to security, which don't apply to CoreCLR
jkotas referenced this issue in dotnet/coreclr Apr 7, 2017
…10778)

Fixes #6843
- Disabled caching struct types that have custom parameterless constructors in `ActivatorCache`
- Removed some things relevant to security, which don't apply to CoreCLR
hadibrais referenced this issue in hadibrais/coreclr Apr 7, 2017
…otnet#10778)

Fixes #6843
- Disabled caching struct types that have custom parameterless constructors in `ActivatorCache`
- Removed some things relevant to security, which don't apply to CoreCLR
@msftgits msftgits transferred this issue from dotnet/coreclr Jan 31, 2020
@msftgits msftgits added this to the 2.0.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 29, 2020
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

8 participants