Add getWasmTypeSymbol API to JIT-EE interface#123958
Conversation
|
@SingleAccretion, I tried having copilot implement your proposed JIT-EE API. Looking at it now, I'm thinking we may want to explicitly pass a count arg after the types arg instead of making it implicit with a null terminator, what do you think? Should we have it accept a SIG_INFO instead of passing a count and type pointers? Were you thinking something else? |
Yes, that is a good pattern for such APIs (note |
| typedef struct CORINFO_JUST_MY_CODE_HANDLE_*CORINFO_JUST_MY_CODE_HANDLE; | ||
| typedef struct CORINFO_PROFILING_STRUCT_* CORINFO_PROFILING_HANDLE; // a handle guaranteed to be unique per process | ||
| typedef struct CORINFO_GENERIC_STRUCT_* CORINFO_GENERIC_HANDLE; // a generic handle (could be any of the above) | ||
| typedef struct CORINFO_WASM_TYPE_SYMBOL_STRUCT_* CORINFO_WASM_TYPE_SYMBOL_HANDLE; // a handle for WASM type symbols |
There was a problem hiding this comment.
What do we plan to use CORINFO_WASM_TYPE_SYMBOL_HANDLE for?
There was a problem hiding this comment.
I'm partially speculating here but I think the idea is that these handles represent entries in the Wasm module's types table. In Wasm one of the first tables is the types table that maps signatures (i.e. (int, int) -> int) to indices, and then all function definitions and indirect calls refer to those signatures by index.
I'm guessing R2R needs to build up a table of these, and this API will be passing it the raw signature and getting back a handle that will eventually go in that table.
There was a problem hiding this comment.
It is the handle type for an ISymbolNode which would represent the signature array (it is a new kind of symbol, and we'll have a few others as well, e. g. for globals). It's not strictly necessary, we could get away with CORINFO_GENERIC_HANDLE. But it seems like a good thing to make the API a bit more typed for clarity.
There was a problem hiding this comment.
we could get away with CORINFO_GENERIC_HANDLE
CORINFO_GENERIC_HANDLE is used for type system things like MethodDescs or TypeDescs that are not ISymbolNode.
globals
We have these today. We use void* for most of them since they are raw addresses that just get embedded into the code . For example, CORINFO_CONST_LOOKUP.addr is ISymbolNode used for globals.
Is the idea that we would use CORINFO_WASM_TYPE_SYMBOL_HANDLE for e.g. addresses of globals as well? If yes, how are we going to reconcile that with void* used for these today?
There was a problem hiding this comment.
CORINFO_GENERIC_HANDLE is used for type system things like MethodDescs or TypeDescs that are not ISymbolNode
It is not consistent. CORINFO_GENERIC_HANDLE handle field in CORINFO_CONST_LOOKUP is a runtime (symbol) handle. I agree it would not be ideal to perpetuate this overloading.
Is the idea that we would use CORINFO_WASM_TYPE_SYMBOL_HANDLE for e.g. addresses of globals as well? If yes, how are we going to reconcile that with void* used for these today?
Do note that I meant "WASM globals". So for example, we will have an API like: <some handle type> getStackPointerGlobal that would return some WasmGlobalNode("__stack_pointer") : ISymbolNode. It wouldn't make sense for this API to return CORINFO_CONST_LOOKUP like for data/code symbols, since globals can't be accessed indirectly / don't have an address. <some handle type> here could indeed be just void*; consistency with the current proposal for signature/type symbols would have it as CORINFO_WASM_GLOBAL_SYMBOL_HANDLE. So these types would be fully orthogonal to what's used currently for code/data symbols.
|
Is it fine to land this without an implementation? Or do I need to implement the API before it's ready for review? cc @AndyAyersMS |
How sure are you about the API shape? Usually when I do something like this, I like to plumb through some of the implementation to build confidence that I have the right shape. |
One thing we may think about is future-proofing the API for vectors. We don't have a |
Yeah, I was thinking about vectors and wondering what the best solution is for those. Could we pass an array of CLASS_HANDLEs instead and then crossgen/the EE is responsible for figuring out the calling convention for things like singleton structs? |
|
Class handles have the same problem as things like |
|
I'm working on adding a new derived type of ObjectNode for a wasm type signature and making R2R create one and return a handle for it. |
Should this just take the encoded wasm signature of the type (using wasm encoding)? It would save us from problems with encoding the type one way and then re-encoding it in a different way on the other side. |
It could be a blob of bytes. I am not sure it would be a big saving in terms of coupling since we need to produce signatures in the managed compiler as well, straight from a |
Where do we need to do that? |
There are two main places:
There are also probably going to be cases with hand-emitted WASM where we will need to produce hand-crafted signatures that correspond in some fashion to their managed callees, which at that point may be yet to be compiled. This can be solved by delaying the signature realization and assuming the callee is going to be a part of the current compilation, and we will be able to retrieve the Jit-produced signature at object writing time. That's more complexity, however. |
|
OK, I plumbed things through at a basic level and verified that the Wasm emitter can get a handle back from the JIT-EE API for a zero-length list of types. Is there more I should do here? |
src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt
Outdated
Show resolved
Hide resolved
...aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_Wasm/WasmTypeNode.cs
Outdated
Show resolved
Hide resolved
...aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_Wasm/WasmTypeNode.cs
Outdated
Show resolved
Hide resolved
...aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_Wasm/WasmTypeNode.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
Outdated
Show resolved
Hide resolved
src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs
Show resolved
Hide resolved
...aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_Wasm/WasmTypeNode.cs
Outdated
Show resolved
Hide resolved
.../tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: kg <198130+kg@users.noreply.github.com>
Co-authored-by: kg <198130+kg@users.noreply.github.com>
Update generated files Fix typo Checkpoint Checkpoint Introduce CorInfoWasmType Exercise new JIT-EE API in emitter Address PR feedback Checkpoint Fix build Move type section Address PR feedback Move WasmTypeNode.cs next to WasmEmitter.cs
0654329 to
fbc5ad3
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds a new JIT-EE interface API getWasmTypeSymbol to enable the WebAssembly JIT compiler to obtain type symbol handles for native WASM types. The implementation provides complete cross-layer plumbing from the JIT through the execution engine and AOT compiler, with SuperPMI instrumentation for testing and replay. The actual functional implementation is deferred with placeholder stubs (UNREACHABLE(), NotImplementedException, etc.), making this a pure infrastructure change.
Changes:
- Introduces
CORINFO_WASM_TYPE_SYMBOL_HANDLEhandle type andCorInfoWasmTypeenum to the JIT-EE interface - Implements full plumbing through CEEInfo, managed AOT compiler (RyuJit/ReadyToRun), and SuperPMI infrastructure
- Adds
WasmTypeNodeto represent WASM type symbols in the AOT dependency graph and updatesObjectNodeSectionto includeWasmTypeSection
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/inc/corinfo.h | Defines CORINFO_WASM_TYPE_SYMBOL_HANDLE and CorInfoWasmType enum; adds virtual method to ICorDynamicInfo |
| src/coreclr/inc/jiteeversionguid.h | Updates JIT-EE version GUID to reflect interface change |
| src/coreclr/inc/icorjitinfoimpl_generated.h | Auto-generated: adds method declaration |
| src/coreclr/jit/ICorJitInfo_names_generated.h | Auto-generated: adds API name to enum |
| src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp | Auto-generated: adds wrapper implementation |
| src/coreclr/jit/emitwasm.cpp | Exercises new API during indirect call emission (temporary usage) |
| src/coreclr/vm/jitinterface.cpp | Implements CEEInfo::getWasmTypeSymbol with UNREACHABLE() stub |
| src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt | Adds type mappings and function signature for thunk generation |
| src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs | Defines managed equivalents of handle struct and enum |
| src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs | Auto-generated: adds callback and managed-to-native wrapper |
| src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs | New file: ObjectNode representing WASM type symbols |
| src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectNodeSection.cs | Adds WasmTypeSection constant for object file output |
| src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs | Updates to use centralized WasmTypeSection constant; whitespace cleanup |
| src/coreclr/tools/aot/jitinterface/jitinterface_generated.h | Auto-generated: adds callback function pointer |
| src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs | Implements stub throwing NotImplementedException |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs | Implements functional version creating WasmTypeNode |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs | Adds WasmTypeNodeKey and factory method for WasmTypeNode creation |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj | Adds WasmTypeNode.cs to project |
| src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h | Declares rec/dmp/rep methods and adds Packet_GetWasmTypeSymbol (235) |
| src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp | Implements recording, dump, and replay logic |
| src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h | Adds GetWasmTypeSymbol LightWeightMap entry |
| src/coreclr/tools/superpmi/superpmi-shared/agnostic.h | Defines Agnostic_GetWasmTypeSymbol struct |
| src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp | Implements MyICJI replay hook |
| src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp | Implements recording interceptor |
| src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp | Auto-generated: adds passthrough |
| src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp | Auto-generated: adds counting passthrough |
.../tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…sm/WasmTypeNode.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@dotnet/jit-contrib I think this is ready for review now. The plan is to immediately work on further changes to the object writer and R2R after this (together with Adam) to start wiring up relocations that use these new type symbol nodes to emit type indices into our output. |
SingleAccretion
left a comment
There was a problem hiding this comment.
LGTM with minor comments.
src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs
Outdated
Show resolved
Hide resolved
.../tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_Wasm/WasmTypeNode.cs
Show resolved
Hide resolved
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
|
|
||
| private CORINFO_WASM_TYPE_SYMBOL_STRUCT_* getWasmTypeSymbol(CorInfoWasmType* types, nuint typesSize) | ||
| { | ||
| throw new NotImplementedException(); |
There was a problem hiding this comment.
What is the implementation eventually going to do here? Will it look similar to the R2R implementation?
There was a problem hiding this comment.
It will be identical (and moved back to CorInfoImpl.cs). The reason it is somewhat difficult to start this way is due to the NodeFactory implementation not being shared (which is not ideal).
There was a problem hiding this comment.
similar to the R2R implementation
Exactly same as R2R implementation?
src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
Outdated
Show resolved
Hide resolved
adamperlin
left a comment
There was a problem hiding this comment.
I think this looks good to me, though I can't comment on all of the pieces here. I can follow up here with some work to re-use the WasmValueType definitions in CG2 for the new WasmTypeNode as well as updating the ObjectWriter to use the new node.
…foImpl.ReadyToRun.cs Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Description
Adds
CORINFO_WASM_TYPE_SYMBOL_HANDLE getWasmTypeSymbol(CorInfoType* types)to the JIT-EE interface with full cross-layer plumbing.Changes
New API surface:
CORINFO_WASM_TYPE_SYMBOL_HANDLEhandle typeCorInfoType*array pointerCore interface (5 files):
corinfo.hICorStaticInfoCorInfoImpl.cs→NotImplementedExceptionjitinterface.cpp→UNREACHABLE()SuperPMI instrumentation (5 files):
DWORDLONG, DWORDLONGmappingAuto-generated (7 files):
17 files total, 141 insertions. Functional implementation deferred via placeholder markers.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.