Wasm enable shared generics and generic virtual methods#7897
Wasm enable shared generics and generic virtual methods#7897MichalStrehovsky merged 104 commits intodotnet:masterfrom
Conversation
# Conflicts: # src/dirs.proj
…r at least might as well do that now rather than work around the lack of it.
# Conflicts: # tests/src/Simple/HelloWasm/Program.cs
add call for generic context need to add the hidden param where necessary.
…ions calls incorrect.
…s when compiling.
Still have to do generic lookup functions and delegate thunks are undefined
Correct call for checking cctor to match cpp. Return the value - but its not used yet passes compilation.
Calling stub instead of signal() exception thrown: RuntimeError: index out of bounds,__ZN6EEType18get_OptionalFieldsEv@http://localhost:6931/HelloWasm.wasm:wasm-function[19519]:0xc24eb3 __ZN6EEType13get_RareFlagsEv@http://localhost:6931/HelloWasm.wasm:wasm-function[19529]:0xc257d1 __ZN6EEType14RequiresAlign8Ev@http://localhost:6931/HelloWasm.wasm:wasm-function[19615]:0xc2a3d7 _RhpNewArray@http://localhost:6931/HelloWasm.wasm:wasm-function[19617]:0xc2a523 _S_P_TypeLoader_System_Collections_Generic_LowLevelDictionary_2_System___Canon__IntPtr___Clear@http://localhost:6931/HelloWasm.wasm:wasm-function[2237]:0x2f3c6f _S_P_TypeLoader_System_Collections_Generic_LowLevelDictionary_2_System___Canon__IntPtr____ctor_0@http://localhost:6931/HelloWasm.wasm:wasm-function[1733]:0x29d8b4 _S_P_TypeLoader_System_Collections_Generic_LowLevelDictionary_2_System___Canon__IntPtr____ctor@http://localhost:6931/HelloWasm.wasm:wasm-function[1164]:0x256ca5 _S_P_TypeLoader_Internal_Runtime_TypeLoader_TypeLoaderEnvironment___ctor@http://localhost:6931/HelloWasm.wasm:wasm-function[861]:0x22fcff _S_P_TypeLoader_Internal_Runtime_TypeLoader_TypeLoaderEnvironment__Initialize@http://localhost:6931/HelloWasm.wasm:wasm-function[470]:0x202c0b _S_P_TypeLoader_Internal_Runtime_CompilerHelpers_LibraryInitializer__InitializeLibrary@http://localhost:6931/HelloWasm.wasm:wasm-function[400]:0x1fc3c6 _StartupCodeMain@http://localhost:6931/HelloWasm.wasm:wasm-function[396]:0x1fc2fe ___managed__Main@http://localhost:6931/HelloWasm.wasm:wasm-function[17784]:0xb875ad _main@http://localhost:6931/HelloWasm.wasm:wasm-function[19766]:0xc31ced Module._main@http://localhost:6931/HelloWasm.js:6592:33 callMain@http://localhost:6931/HelloWasm.js:7044:22 doRun@http://localhost:6931/HelloWasm.js:7102:49
Problem now seems to be that class statics are not initialised
now fails with _S_P_CoreLib_System_Diagnostics_Debug__Fail_0@http://localhost:6931/HelloWasm.wasm:wasm-function[702]:0x21d82e _S_P_CoreLib_System_Diagnostics_Debug__Assert_1@http://localhost:6931/HelloWasm.wasm:wasm-function[597]:0x20ff8a _S_P_CoreLib_System_Diagnostics_Debug__Assert@http://localhost:6931/HelloWasm.wasm:wasm-function[337]:0x1f7a56 _S_P_CoreLib_System_Threading_ManagedThreadId__AllocateId@http://localhost:6931/HelloWasm.wasm:wasm-function[2330]:0x2fb83b _S_P_CoreLib_System_Threading_ManagedThreadId___ctor@http://localhost:6931/HelloWasm.wasm:wasm-function[1682]:0x298e63 _S_P_CoreLib_System_Threading_ManagedThreadId__MakeForCurrentThread@http://localhost:6931/HelloWasm.wasm:wasm-function[1217]:0x25ae5b _S_P_CoreLib_System_Threading_ManagedThreadId__get_Current@http://localhost:6931/HelloWasm.wasm:wasm-function[810]:0x22b6ce _S_P_CoreLib_System_Runtime_CompilerServices_ClassConstructorRunner__get_CurrentManagedThreadId@http://localhost:6931/HelloWasm.wasm:wasm-function[484]:0x2050c7 _S_P_CoreLib_System_Runtime_CompilerServices_ClassConstructorRunner__EnsureClassConstructorRun@http://localhost:6931/HelloWasm.wasm:wasm-function[391]:0x1fbf2d
for the generic dict, try to remove the +1 pointer as otherwise the index lookup is one off - this maybe the wrong way to fix this.
Fails as InternalGetResourceString throws.
…erOffset is not working so the calli fails.
MichalStrehovsky
left a comment
There was a problem hiding this comment.
I started looking but I haven't looked at the two files with the biggest changes yet. I hope I'll get to those soon. Sorry for the delays.
...mbly/src/Compiler/DependencyAnalysis/WebAssemblyReadyToRunGenericLookupFromDictionaryNode.cs
Show resolved
Hide resolved
src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyVTableSlotNode.cs
Outdated
Show resolved
Hide resolved
| @@ -1,7 +1,15 @@ | |||
| <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
| <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current"> | |||
There was a problem hiding this comment.
I think all changes to this file can be backed out.
|
|
||
| <ProjectReference Include="ILHelpers.ilproj" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| <IlcArg Include="-r:$(IntermediateOutputPath)\ILHelpers.dll" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| <IlcArg Include="--usesharedgenerics" /> |
There was a problem hiding this comment.
Should not be needed since shared genercis are now the default for wasm too.
There was a problem hiding this comment.
having a problem with this. If its not here, how does it get into the .rsp?
There was a problem hiding this comment.
I wasn't reading
corert/src/ILCompiler/src/Program.cs
Lines 314 to 315 in ac04886
SharedGenericsMode enum?
There was a problem hiding this comment.
Could you remove this?
_S_P_CoreLib_System_Diagnostics_Debug__Assert@http://localhost:6931/Generics.wasm:wasm-function[375]:0x21682b _S_P_TypeLoader_Internal_TypeSystem_TypeDesc__SetRuntimeTypeHandleUnsafe@http://localhost:6931/Generics.wasm:wasm-function[11211]:0x78026a _S_P_TypeLoader_Internal_TypeSystem_CanonType__Initialize@http://localhost:6931/Generics.wasm:wasm-function[13993]:0x8fedfe _S_P_TypeLoader_Internal_TypeSystem_CanonType___ctor@http://localhost:6931/Generics.wasm:wasm-function[13024]:0x88a3cf _S_P_TypeLoader_Internal_TypeSystem_TypeSystemContext__get_CanonType@http://localhost:6931/Generics.wasm:wasm-function[11209]:0x78010c _S_P_TypeLoader_Internal_TypeSystem_TypeSystemContext__ResolveRuntimeTypeHandle@http://localhost:6931/Generics.wasm:wasm-function[10335]:0x71
…red-fails # Conflicts: # src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs # tests/src/Simple/HelloWasm/Program.cs
|
Thanks, have made the adjustment for the fat function offset |
|
Oh dear, I seem to have broken something, let me look at that. |
…red-fails # Conflicts: # src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs # tests/src/Simple/HelloWasm/Program.cs
|
Remove WIP as dependencies now merged |
|
Noticed a problem: Which is from the method When getting the constrained type we use Which results in which expects a Where have I gone wrong here, should I even be creating code for TKey, if that's a value type, then shouldn't it be the actual type? |
I would just do what the IL scanner is doing: grab the canonical form of the constrained type: corert/src/ILCompiler.Compiler/src/IL/ILImporter.Scanner.cs Lines 420 to 422 in 6c06857 The scanner keeps both canonical and runtime determined form of the method, and uses the canonical for things like this (TryResolveConstraintMethodApprox is called with canonical method and canonical constraint). The runtime determined form is only needed if we will have to do a generic lookup, but constrained calls don't end up needing that because they acquire the generic context from Note that the scanner still uses the runtime determined form of the constraint in case we need to box. |
|
Moving back to WIP as is failing on the |
|
Thanks for the constrained info. For the However when the GetHashCode is called from within a generic method : Then I get this error, or rather as I'm not using Dict<,> anymore: I want to ask if I have the And that is false. Is this wrong? |
|
My mistake, was looking the the ILOpcode box, not the callvirt where I didn't have the lookup code. Its in now along with a test. Removing WIP. Sorry about the back and forth on this. I have the standard tests working, but then move on to trying the Uno Platform where more errors are uncovered. |
MichalStrehovsky
left a comment
There was a problem hiding this comment.
Thanks! Once this feedback is addressed, we can check this in.
| Append(gvmSlotVarName); | ||
| Append(" & "); | ||
| Append(FatFunctionPointerConstants.Offset.ToString()); | ||
| Append(method.Context.Target.FatFunctionPointerOffset.ToString()); |
There was a problem hiding this comment.
Just a nit (also elsewhere):
| Append(method.Context.Target.FatFunctionPointerOffset.ToString()); | |
| Append(_typeSystemContext.Target.FatFunctionPointerOffset.ToString()); |
| @@ -0,0 +1,34 @@ | |||
| using System; | |||
There was a problem hiding this comment.
Could you add copyright header?
| @@ -0,0 +1,34 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
|
|
||
| SharedGenericsMode genericsMode = _useSharedGenerics || !_isWasmCodegen ? | ||
| SharedGenericsMode.CanonicalReferenceTypes : SharedGenericsMode.Disabled; | ||
| SharedGenericsMode genericsMode = SharedGenericsMode.CanonicalReferenceTypes; |
There was a problem hiding this comment.
_useSharedGenerics is now unused. Let's delete the command line option and field.
| TestReflectionInvoke.Run(); | ||
| TestFieldAccess.Run(); | ||
| TestDevirtualization.Run(); | ||
| TestGenericInlining.Run(); |
There was a problem hiding this comment.
Was this lost in a rebase?
| /// Offset by which fat function pointers are shifted to distinguish them | ||
| /// from real function pointers. Keep in line with FatFunctionPointerConstants | ||
| /// </summary> | ||
| internal const uint FatFunctionPointerOffset = (uint)1 << 31; |
There was a problem hiding this comment.
Could you switch this to the one obtained from Context.Target?
There was a problem hiding this comment.
Done. Moved a helper function from static to instance to get access.
| //TODO refactor argument creation with else below | ||
| arguments = new StackEntry[] | ||
| { | ||
| new ExpressionEntry(StackValueKind.ValueType, "eeType", CallGenericHelper(ReadyToRunHelperId.TypeHandle, type), |
There was a problem hiding this comment.
This would probably fix the TestNullableCasting test in the Simple\Generics test:
| new ExpressionEntry(StackValueKind.ValueType, "eeType", CallGenericHelper(ReadyToRunHelperId.TypeHandle, type), | |
| new ExpressionEntry(StackValueKind.ValueType, "eeType", CallGenericHelper(ReadyToRunHelperId.TypeHandleForCasting, type), |
If it doesn't fix it, then leave this as-is for now. Let's not add more scope to this.
There was a problem hiding this comment.
Unfortunately hits
{[S.P.CoreLib]System.Collections.Generic.ICollection1<T_System.__Canon>}` Have opened #7934
| HandleCall(null, methodSignature, ILOpcode.calli, calliTarget: ((ExpressionEntry)_stack.Pop()).ValueAsType(LLVM.PointerType(GetLLVMSignatureForMethod(methodSignature), 0), _builder)); | ||
| MethodSignature methodSignature = (MethodSignature)_canonMethodIL.GetObject(token); | ||
|
|
||
| if (_method.ToString().Contains("InvokeRet")) |
| } | ||
| else | ||
| { | ||
| if (ConstructedEETypeNode.CreationAllowed(typeDesc)) |
There was a problem hiding this comment.
Do we need this if check? If we call GetEETypePointerForTypeDesc with true below, it should do the right thing wrt dependency tracking.
There was a problem hiding this comment.
No, works with it removed.
| if (node == null) | ||
| continue; | ||
|
|
||
There was a problem hiding this comment.
Nit: undo white space change (same below).
| /// </summary> | ||
| #if WASM | ||
| // WebAssembly uses index tables, not addresses for function pointers. This is going to be contentious it is baked into Ilc and hence an Ilc for x64 will not be able to compile Wasm and vice versa. Alternative ways round this?. | ||
| public const int Offset = 1 << 31; |
There was a problem hiding this comment.
It was mentioned #7248 (comment) that there might be other better solutions available for Wasm.
...mbly/src/Compiler/DependencyAnalysis/WebAssemblyReadyToRunGenericLookupFromDictionaryNode.cs
Show resolved
Hide resolved
|
|
||
| <ProjectReference Include="ILHelpers.ilproj" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| <IlcArg Include="-r:$(IntermediateOutputPath)\ILHelpers.dll" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| <IlcArg Include="--usesharedgenerics" /> |
There was a problem hiding this comment.
having a problem with this. If its not here, how does it get into the .rsp?
|
|
||
| <ProjectReference Include="ILHelpers.ilproj" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| <IlcArg Include="-r:$(IntermediateOutputPath)\ILHelpers.dll" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| <IlcArg Include="--usesharedgenerics" /> |
There was a problem hiding this comment.
I wasn't reading
corert/src/ILCompiler/src/Program.cs
Lines 314 to 315 in ac04886
SharedGenericsMode enum?
| //TODO refactor argument creation with else below | ||
| arguments = new StackEntry[] | ||
| { | ||
| new ExpressionEntry(StackValueKind.ValueType, "eeType", CallGenericHelper(ReadyToRunHelperId.TypeHandle, type), |
There was a problem hiding this comment.
Unfortunately hits
{[S.P.CoreLib]System.Collections.Generic.ICollection1<T_System.__Canon>}` Have opened #7934
| @@ -0,0 +1,34 @@ | |||
| using System; | |||
|
|
||
| SharedGenericsMode genericsMode = _useSharedGenerics || !_isWasmCodegen ? | ||
| SharedGenericsMode.CanonicalReferenceTypes : SharedGenericsMode.Disabled; | ||
| SharedGenericsMode genericsMode = SharedGenericsMode.CanonicalReferenceTypes; |
| TestReflectionInvoke.Run(); | ||
| TestFieldAccess.Run(); | ||
| TestDevirtualization.Run(); | ||
| TestGenericInlining.Run(); |
| <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
| <ItemGroup> | ||
| <Compile Include="*.cs" /> | ||
| <IlcArg Include="--usesharedgenerics" /> |
|
|
||
| <ProjectReference Include="ILHelpers.ilproj" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| <IlcArg Include="-r:$(IntermediateOutputPath)\ILHelpers.dll" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| <IlcArg Include="--usesharedgenerics" /> |
MichalStrehovsky
left a comment
There was a problem hiding this comment.
Thanks for your patience on this!
Mostly taken from the cpp backend, this enables shared generics and generic virtual methods for the Wasm backend. Have tried to keep the logic as clean as I could, but maybe there's some obvious enhancements/reductions in code that I missed.
Size of HelloWasm.bc (LLVM bitcode) before 43,950KB, and after 37,593KB (these aren't exact as the after includes more tests, so actual saving is probably fractionally better) . HelloWasm before this change didn't have much in the way of generics so this mostly reflects the framework and runtime generics.
Enables the Simple/Generics tests for wasm which have the almost same coverage as cpp (Wasm includes an additional test) in terms of what is #if'ed out.
WIP as depends on #7893 and #7891
Fixes #7248