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

[mono][fullaot] Calling static virtual method from a generic method leads to "Attempting to JIT" error #65002

Closed
lambdageek opened this issue Feb 8, 2022 · 3 comments · Fixed by #65126
Labels
area-Codegen-AOT-mono untriaged New issue has not been triaged by the area owner
Milestone

Comments

@lambdageek
Copy link
Member

Compile this sample for FullAOT, then make run. Expected result: "Taking transition" is printed out. Actual result:

Unhandled Exception:
System.ExecutionEngineException: Attempting to JIT compile method 'St`1<Brz> Q:Delta<Brz> (St`1<Brz>,M`1<Brz>)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.

   at HelloWorld.Program.Main(String[] args) in /Users/alklig/work/dotnet-runtime/runtime/src/mono/sample/HelloWorld/Program.cs:line 45
[ERROR] FATAL UNHANDLED EXCEPTION: System.ExecutionEngineException: Attempting to JIT compile method 'St`1<Brz> Q:Delta<Brz> (St`1<Brz>,M`1<Brz>)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.

   at HelloWorld.Program.Main(String[] args) in /Users/alklig/work/dotnet-runtime/runtime/src/mono/sample/HelloWorld/Program.cs:line 45
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

public class St<T> {
    public T t;
    public T GetIt() => t;
}

public class M<T> {
    public bool Matches(T state) => false;
}

public interface Itf<T>  {
    static abstract St<T> TakeTransition(M<T> matcher, T state);
}

public class Q {
    public St<T> Delta<T> (St<T> src, M<T> matcher) where T : Itf<T>{
	Console.WriteLine ("Taking transition");
	return T.TakeTransition(matcher, src.GetIt());
    }
}

public class Brz : Itf<Brz> {
    public static St<Brz> TakeTransition (M<Brz> matcher, Brz state) {
	return new St<Brz>() { t = state };
    }
}

namespace HelloWorld
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            bool isMono = typeof(object).Assembly.GetType("Mono.RuntimeStructs") != null;
            Console.WriteLine($"Hello World {(isMono ? "from Mono!" : "from CoreCLR!")}");
            Console.WriteLine(typeof(object).Assembly.FullName);
            Console.WriteLine(System.Reflection.Assembly.GetEntryAssembly ());
            Console.WriteLine(System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription);
	    Console.WriteLine (GetEE());

	    new Q().Delta<Brz> (new St<Brz>(), new M<Brz>());
        }

	public static string GetEE() {
	    if (!System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported)
		return "FullAOT";
	    if (!System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeCompiled)
		return "Interp";
	    return "JIT";
	}
    }
}

Makefile:

TOP=../../../../
DOTNET:=$(TOP)./dotnet.sh
DOTNET_Q_ARGS=--nologo -v:q -consoleloggerparameters:NoSummary

MONO_CONFIG ?=Release
MONO_ARCH=x64

OS := $(shell uname -s)
ifeq ($(OS),Darwin)
	TARGET_OS=osx
else
	TARGET_OS=linux
endif

MONO_ENV_OPTIONS ?=--full-aot

ARTIFACTS_BIN=$(abspath $(TOP)artifacts/bin/HelloWorld/$(MONO_ARCH)/$(MONO_CONFIG)/$(TARGET_OS)-$(MONO_ARCH))

MONO_AOT_COMPILER=$(abspath $(TOP)artifacts/obj/mono/OSX.x64.Release/out/bin/mono-sgen)

publish: $(ARTIFACTS_BIN)/.touch-publish

$(ARTIFACTS_BIN)/.touch-publish: HelloWorld.csproj Program.cs
	$(DOTNET) publish -c $(MONO_CONFIG) -r $(TARGET_OS)-$(MONO_ARCH) /p:RunAOTCompilation=true
	touch $(ARTIFACTS_BIN)/.touch-publish

$(ARTIFACTS_BIN)/.touch-fullaot: $(ARTIFACTS_BIN)/.touch-publish
	pushd $(ARTIFACTS_BIN)/publish ; \
	for i in *.dll ; do \
		MONO_PATH=$(ARTIFACTS_BIN)/publish \
		$(MONO_AOT_COMPILER) --aot=full $${i} ; \
	done ; \
	popd
	touch $(ARTIFACTS_BIN)/.touch-fullaot

aot: $(ARTIFACTS_BIN)/.touch-fullaot

.PHONY: run

run: $(ARTIFACTS_BIN)/.touch-fullaot
	COMPlus_DebugWriteToStdErr=1 \
	MONO_ENV_OPTIONS="$(MONO_ENV_OPTIONS)" \
	$(TOP)artifacts/bin/HelloWorld/$(MONO_ARCH)/$(MONO_CONFIG)/$(TARGET_OS)-$(MONO_ARCH)/publish/HelloWorld

clean:
	rm -rf $(TOP)artifacts/bin/HelloWorld/
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Feb 8, 2022
@lambdageek lambdageek added this to the 7.0.0 milestone Feb 8, 2022
@lambdageek
Copy link
Member Author

FYI @vargaz

@lambdageek
Copy link
Member Author

Running with mono-sgen --aot=full -v -v -v -v -v we can see this during AOT compilation of HelloWorld.dll:

cmethod = St`1<T_GSHAREDVT> Itf`1<T_GSHAREDVT>:TakeTransition (M`1<T_GSHAREDVT>,T_GSHAREDVT)
sharing failed for method .Q.Delta/2 opcode call line 7362

if (m_method_is_static (cil_method) && mini_class_check_context_used (cfg, constrained_class))
// FIXME:
GENERIC_SHARING_FAILURE (CEE_CALL);

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Feb 10, 2022
vargaz added a commit to vargaz/runtime that referenced this issue Feb 10, 2022
…ode.

Fixes dotnet#65002.

When called from gshared code, these methods cannot be resolved at compile time,
since they depend on the constrained class which is only known at runtime.

* For calls from normal gshared code, load the method address from the rgctx.
* For calls from gsharedvt code, extend the existing mono_gsharedvt_constrained_call ()
JIT icall to be able to handle static virtual methods.
vargaz added a commit that referenced this issue Feb 10, 2022
…ode. (#65126)

Fixes #65002.

When called from gshared code, these methods cannot be resolved at compile time,
since they depend on the constrained class which is only known at runtime.

* For calls from normal gshared code, load the method address from the rgctx.
* For calls from gsharedvt code, extend the existing mono_gsharedvt_constrained_call ()
JIT icall to be able to handle static virtual methods.
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Feb 10, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Mar 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Codegen-AOT-mono untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant