Bug 3706 - generics aot jit problem
Summary: generics aot jit problem
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 5.2
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2012-03-01 13:55 UTC by Chris Toshok
Modified: 2016-02-11 15:03 UTC (History)
5 users (show)

Is this bug a regression?: ---
Last known good build:

AppDelegate.cs file (1.42 KB, text/plain)
2012-03-01 13:55 UTC, Chris Toshok
solution I've been using (7.21 KB, application/x-gzip)
2012-03-03 01:38 UTC, Chris Toshok

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Chris Toshok 2012-03-01 13:55:45 UTC
Created attachment 1447 [details]
AppDelegate.cs file

The attached AppDelegate.cs (just create a normal single view iphone app and replace that file with the attached) crashes with the usual "Could not JIT method ... full-aot..." with or without INTERNAL_SLOT_STRUCT defined.

Neither case seems like it should crash.  The type info should propagate in such a way that the aot compiler knows that (in the !INTERNAL_SLOT_STRUCT case) it needs an instantiation of Slot<ListObject>, shouldn't it?
Comment 1 Chris Toshok 2012-03-01 14:03:07 UTC
changing CrashMono to the following keeps things from crashing:

		public void CrashMono ()
			List<ListSlot<ListObject>> foo = new List<ListSlot<ListObject>>();
			MyList<ListObject> list = new MyList<ListObject>();

but I'm at a loss for how the mono compiler can't propagate T=ListObject into the instantiation of MyList, and know that List<ListSlot<ListObject>> is required itself.
Comment 2 Zoltan Varga 2012-03-01 19:12:29 UTC
I can't reproduce this with a console test program, neither with master or 2.10.
using System;
using System.Collections.Generic;
using System.Linq;

namespace genericsbug
	public class Tests {
		public static void Main (String[] args) {
			MyList<ListObject> list = new MyList<ListObject>();
	class ListObject
	class MyList<T> where T : ListObject
		protected struct Slot
			T item;
		List<Slot> slots = new List<Slot>();
Comment 3 Zoltan Varga 2012-03-02 17:36:20 UTC
I can't repro this with mt 5.2.5 either.
Comment 4 Chris Toshok 2012-03-02 18:24:00 UTC
On device?

it definitely happens here.. 100% of the time...

hrm..  mono version shouldn't matter as monotouch uses all its own stuff.

anything I can do on my end to gather more data?
Comment 5 Zoltan Varga 2012-03-02 19:02:25 UTC
Are you using some special linker flags etc ?
Comment 6 Chris Toshok 2012-03-03 01:35:13 UTC
nope, just a totally vanilla solution.

Let me attach it.
Comment 7 Chris Toshok 2012-03-03 01:38:14 UTC
Created attachment 1456 [details]
solution I've been using
Comment 8 Zoltan Varga 2012-03-03 06:32:54 UTC
I can somewhat reproduce this. I get a runtime assertion in Release|iPhone configuration instead of an exception printed to the application output window.
Comment 9 Zoltan Varga 2012-03-03 06:39:36 UTC
Correction: it only happens in Debug|iHpone configuration, and only if 'Enable debugging' is enabled. Probably the JIT optimizations disabled in debug mode cause this.
Comment 10 Zoltan Varga 2012-03-03 15:12:53 UTC
So the problem happens because of generic sharing. ListObject is a reference type,
so the 	MyList<ListObject> list = new MyList<ListObject>(); call doesn't cause any additional methods to be compiled because MyList<ListObject>.ctor () is generic shared, so it is implemented by MyList<T>.ctor ().
When MyList<T>.ctor () is compiled, it doesn't know about the non-gshared
List<MyList`1/Slot<ListObject>> type which is needed at runtime.
Comment 11 Chris Toshok 2012-03-04 00:31:14 UTC
gsharing isn't turned off in release mode, is it?  is there some other pass that's propagating type info?
Comment 12 Zoltan Varga 2012-03-04 08:51:47 UTC
I can only repro this in Debug mode.
Comment 13 Chris Toshok 2012-03-05 22:09:42 UTC
right.  Just wondering if there's an optimization pass that should be turned on for debug mode so that the code can execute?
Comment 14 Zoltan Varga 2012-03-06 14:15:53 UTC
You can turn on inlining by disabling the code which disables it in mini.c:

                cfg->opt &= ~MONO_OPT_DEADCE;
                //cfg->opt &= ~MONO_OPT_INLINE;
                cfg->opt &= ~MONO_OPT_COPYPROP;
                cfg->opt &= ~MONO_OPT_CONSPROP;
                /* This is no longer needed with sdb */
                //cfg->opt &= ~MONO_OPT_GSHARED;

This will make sdb less usable or not usable at all.
Comment 15 Rodrigo Kumpera 2012-03-06 14:35:25 UTC
Hey Zoltan,

The type List<MyList`1/Slot<T>> can be gshare'able. We should proably should look into how much work it would entail.
Comment 16 Rolf Bjarne Kvinge [MSFT] 2016-02-11 15:03:25 UTC
This works fine now.