-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[mono] When creating an array type, don't do full initialization of the element type #85828
Conversation
64393af
to
5faed55
Compare
Tagging subscribers to this area: Issue DetailsConsider code like this: public class Node<T>
{
public Node<T>[][] Children;
}
Console.WriteLine (typeof(Node<int>)); In this case, when we're JITing To resolve the field types we have to parse the types of all the fields, and we eventually end up parsing the type runtime/src/mono/mono/metadata/metadata.c Lines 4023 to 4027 in 558345d
When we get to line 4027 the second time (recursively), runtime/src/mono/mono/metadata/class.c Lines 2214 to 2215 in 558345d
When we call runtime/src/mono/mono/metadata/class-init.c Lines 1186 to 1187 in 558345d
with Compare with this other class: public unsafe class Node2<T>
{
public Node2<T>[] Children;
} In this case we only end up calling It seems the reason we get into trouble is because But note that the code has this: runtime/src/mono/mono/metadata/class-init.c Lines 1186 to 1189 in 558345d
I feel fairly certain we don't need the full class initialization if we're going to immediately initialize the field size information. Fixes #85821
|
Mono was a bit too aggressive with its TypeLoadException processing, not allowing some valid code in this case. This change applies the fix from: dotnet/runtime#85828
Mono was a bit too aggressive with its TypeLoadException processing, not allowing some valid code in this case. This change applies the fix from: dotnet/runtime#85828
Mono was a bit too aggressive with its TypeLoadException processing, not allowing some valid code in this case. This change applies the fix from: dotnet/runtime#85828
Mono was a bit too aggressive with its TypeLoadException processing, not allowing some valid code in this case. This change applies the fix from: dotnet/runtime#85828
Consider code like this:
In this case, when we're JITing
ldtoken class Node`1<int32>
we first have to parse the typeNode`1<int32>
and initialize it.When we're initializing it, we need to resolve the types of all the fields in the class in order to to figure out if its instance size.
To resolve the field types we have to parse the types of all the fields, and we eventually end up parsing the type
Node`1<!0>[][]
which ends up here:runtime/src/mono/mono/metadata/metadata.c
Lines 4023 to 4027 in 558345d
When we get to line 4027 the second time (recursively),
etype
isNode`1<!0>
as aMonoType*
. And we want to settype->data.klass
to its correspondingMonoClass*
. That ends up callingmono_class_from_mono_type_internal
, which does this:runtime/src/mono/mono/metadata/class.c
Lines 2214 to 2215 in 558345d
When we call
mono_class_create_array
we end up here:runtime/src/mono/mono/metadata/class-init.c
Lines 1186 to 1187 in 558345d
with
eclass
equal toNode`1<!0>` which we try to initialize and we get a TLE because we're going to try to initialize the same generic type definition
Node`1`` twice.Compare with this other class:
In this case we only end up calling
mono_class_from_mono_type_internal
onNode2`1<int32>
(not an array). And that branch does not do any initialization - it just returnstype->data.klass
(forNode2`1<!0>
- which is seen as a gtd at this point) ormono_class_create_generic_inst (type->data.generic_class)
(forNode2`1<int32>
which is seen later whenldtoken
inflates the gtd)) - without any extra initialization.It seems the reason we get into trouble is because
mono_class_create_array
does more work than otherMonoClass
creation functions - it tries to initialize theMonoClass
a little bit (for example by settingMonoClass:has_references
) which needs at least a little bit of the element class to be initialized.But note that the code has this:
runtime/src/mono/mono/metadata/class-init.c
Lines 1186 to 1189 in 558345d
I feel fairly certain we don't need the full class initialization if we're going to immediately initialize the field size information.
Fixes #85821