Bug 59401 - MethodInfo.Invoke fails for generic methods with large arguments on armv7
Summary: MethodInfo.Invoke fails for generic methods with large arguments on armv7
Status: CONFIRMED
Alias: None
Product: iOS
Classification: Xamarin
Component: Mono runtime / AOT compiler (show other bugs)
Version: XI 10.99 (xcode9)
Hardware: PC Windows
: --- normal
Target Milestone: Future Cycle (TBD)
Assignee: Zoltan Varga
URL:
Depends on:
Blocks:
 
Reported: 2017-09-11 21:28 UTC by henry.lisowski
Modified: 2018-02-15 16:25 UTC (History)
6 users (show)

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


Attachments
Test Case (10.72 KB, application/zip)
2017-09-12 02:48 UTC, Alex Soto [MSFT]
Details


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 for Bug 59401 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description henry.lisowski 2017-09-11 21:28:38 UTC
I have two structs, Vector4 and Matrix. Vector4 has 4 floats, Matrix has 16 floats.

I have another class called MagicProperty.
public class MagicProperty<T>{
    public T Value{get;set;}
    public MagicProperty(T val){
        Value = val;
    }
}
When creating instances of MagicProperty using Activator.CreateInstance, MagicProperty<Vector4> succeeds but MagicProperty<Matrix> fails.

For reference:

//Make sure constructors don't get removed
MagicProperty<Vector4> vecProp = new MagicProperty<Vector4>(new Vector4());
MagicProperty<Matrix> matrixProp = new MagicProperty<Matrix>(new Matrix());

Type vecType = typeof(MagicProperty<Vector4>);
Type matrType = typeof(MagicProperty<Matrix>);
//Works fine
object vecResult = Activator.CreateInstance(vecType, new Vector4());
//Fails
object result = Activator.CreateInstance(matrType, new Matrix());

I've used reflection to confirm that the constructor for MagicProperty does in fact exist. 

It looks like, because Matrix is "big" it's actually trying to split it up into multiple parameters maybe? Which means it no longer matches the method definition as expected.

The actual error is the following:

Attempting to JIT compile method '(wrapper runtime-invoke) :runtime_invoke_void__this___Matrix (object,intptr,intptr,intptr)' while running in aot-only mode. See https://developer.xamarin.com/guides/ios/advanced_topics/limitations/ for more information.
(System.ExecutionEngineException)
at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:661


Here's the logs from where it fails:

2017-09-10 20:40:37.106 BugTestBench[313:29267] Unhandled managed exception:
Exception has been thrown by the target of an invocation. (System.Reflection.TargetInvocationException)
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00012] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:667 
at System.Reflection.MonoCMethod.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0007a] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:652 
at System.Reflection.MonoCMethod.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, Sys
tem.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:680 
at System.RuntimeType.CreateInstanceImpl (System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes, System.Threading.StackCrawlMark& stackMark) [0x001a7] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/referencesource/mscorlib/system/rttype.cs:5419 
at System.Activator.CreateInstance (System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes) [0x00064] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/referencesource/mscorlib/system/activator.cs:107 
at System.Activator.CreateIns
tance (System.Type type, System.Object[] args) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.10.0.36/src/mono/mcs/class/referencesource/mscorlib/system/activator.cs:112
Comment 1 Alex Soto [MSFT] 2017-09-12 02:48:36 UTC
Created attachment 24692 [details]
Test Case
Comment 2 Alex Soto [MSFT] 2017-09-12 02:52:14 UTC
Hello Henry

I have tried to reproduce the issue based on your instructions without luck, it works fine for me on both simulator and device.

Please provide all your version information and if possible test the attached test case in comment #2 and modify it to your own crasher version or include your own test case.

The easiest way to get exact version information:

- On Visual Studio for Mac: "Visual Studio" menu, "About Visual Studio" item, "Show Details" button.

- On Visual Studio for Windows: "Help menu", "About Microsoft Visual Studio" item.
Then copy/paste the version information (you can use the "Copy Information" button).
Comment 3 henry.lisowski 2017-09-15 04:47:15 UTC
VS (Windows) Version: 15.2 (26430.14)

So I downloaded your attached test project, and initially I couldn't deploy it to my device.  I looked into it and I'm running an iPhone 5C, which requires ARMv7.  Once I added that to the project file (Changing <MtouchArch>ARM64</MtouchArch> to <MtouchArch>ARMv7, ARM64</MtouchArch>) It deployed to my device, and crashed the same way I described above.  It looks like this might be a bug that only happens on ARMv7, but since this is the only test device I have I can't confirm that it doesn't happen on ARM64.  Do you have an ARMv7 device you could try it on?
Comment 4 Alex Soto [MSFT] 2017-09-15 14:02:02 UTC
Indeed I can replicate the issue with an iPhone 5 and the instructions provided in comment #3

{System.ExecutionEngineException: Attempting to JIT compile method '(wrapper runtime-invoke) <Module>:runtime_invoke_void__this___Matrix (object,intptr,intptr,intptr)' while running in aot-only mode. See https://developer.xamarin.com/guides/ios/advanced_topics/limitations/ for more information.

  at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
  at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in /Users/Alex/monotouch/xcode9/xamarin-macios/external/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:661 }
Comment 5 Zoltan Varga 2017-09-15 15:36:34 UTC
This happens because the AOT compiler doesn't know about the MagicProperty<Matrix>.ctor () method, and the generic code to handle this can't handle certain types like Matrix.
Comment 6 henry.lisowski 2017-09-15 17:43:02 UTC
What's different about the Matrix that would cause the failure when Vector4 does not?  They're both a struct with only floats, the only difference being a Matrix has 4 times the amount of floats.
Comment 7 Zoltan Varga 2017-09-15 17:51:52 UTC
Thats the reason.
Comment 8 henry.lisowski 2017-09-15 18:10:37 UTC
So it's a size issue?  If a struct is over a certain size the generic code breaks? Or is it the number of properties on the struct?  (Just trying to understand the problem a little better)
Comment 9 Zoltan Varga 2017-09-15 18:42:25 UTC
Its the size of the struct. Referencing the actual method might work around the issue, i.e. writing 
var v = new MagicProperty<Matrix> ();
somewhere.
Comment 10 henry.lisowski 2017-09-15 20:23:22 UTC
Calling the actual constructor of MagicProperty<Matrix> works fine.  The test case I'm using does this:

//Make sure constructors don't get removed
MagicProperty<Vector4> vecProp = new MagicProperty<Vector4>(new Vector4());
MagicProperty<Matrix> matrixProp = new MagicProperty<Matrix>(new Matrix());

Type vecType = typeof(MagicProperty<Vector4>);
Type matrType = typeof(MagicProperty<Matrix>);
//Works fine
object vecResult = Activator.CreateInstance(vecType, new Vector4());
//Fails
object result = Activator.CreateInstance(matrType, new Matrix());

So the constructor for MagicProperty<Matrix> isn't getting removed by linking (I even verified that using reflection at runtime).

So I can technically get around this by directly calling the constructor, but my current scenario requires using Activator.CreateInstance.  My current workaround has been to use a class version of Matrix instead of a struct, which works but creates a ton of garbage every frame that I'd like to avoid if possible.
Comment 11 Zoltan Varga 2017-09-19 20:53:19 UTC

*** This bug has been marked as a duplicate of bug 59184 ***
Comment 12 Sebastien Pouliot 2018-02-15 16:25:03 UTC
@Zoltan what that a duplicate or not ? wrt comment #11