Repository navigation
Reduce redundant work in CoreCLR WebAssembly type-loader code generation #134631
Description
Description
Inspecting Release browser-wasm code for ClassLoader::CreateTypeHandleForTypeDefThrowing and its callees revealed redundant loads, unnecessary RVA-resolution paths, repeated signature parsing, and exception-handling code caused by contracts that are not visible to the C++ optimizer. This issue tracks targeted, behavior-preserving improvements to those paths.
The baseline was built from dc614919f33834bb38d5020651864321a1de121b with:
.\build.cmd -os browser -c Release -subset clr+libsInspect artifacts\bin\browser-wasm.Release\corehost\dotnet.native.wasm, using its matching dotnet.native.js.symbols to identify functions. Function indices are build-specific.
Configuration
Windows x64 build host, browser-wasm target, Release configuration, Emscripten 6.0.2. The relevant native translation unit is compiled with -O3, WebAssembly exceptions, and -fno-strict-aliasing.
Regression?
Not established as a regression. This is an investigation of existing code-generation opportunities, not a demonstrated application-throughput or startup regression.
Data
Isolated source-copy probes, compiled with the original TU options and relinked with private archive copies, produced these function-body sizes:
| Isolated change | Function | Before | After |
|---|---|---|---|
| Use raw field offsets during placement | HandleAutoLayout |
2,300 B | 2,119 B |
| Snapshot placement pointer/counts | HandleAutoLayout |
2,300 B | 2,253 B |
| Compare the retained MethodImpl token | PlaceMethodImpls |
1,618 B | 1,578 B |
| Cache the initial allocator pointer | CreateTypeHandleForTypeDefThrowing |
55,856 B | 55,819 B |
| Group initial builder-state allocations | CreateTypeHandleForTypeDefThrowing |
55,856 B | 55,732 B |
The raw-offset probe also eliminated two unreachable-for-valid-instance-fields RVA paths and a 16-byte linear-memory stack frame. The placement loop's four-bucket region changed from 17 loads to five. The token comparison changed from five loads plus reconstruction arithmetic to two loads.
Separately, 19 enumeration-cleanup sites in the baseline entry function have catch-all/terminate wrappers around HENUMInternal::ClearEnum, whose nonthrowing implementation is not expressed through a C++ exception specification.
These are static code-generation measurements, not execution frequencies or speedups. The probes were independent; their savings must not be assumed additive. Functional regression and performance validation are required for the final changes.
Analysis
Planned changes, kept independently reviewable:
- Use
FieldDesc::GetOffsetRaw()for loading-phase instance-field placement sentinels inHandleAutoLayout. - Expose stable placement state and the initial stacking allocator through locals, without enabling strict aliasing globally.
- Use the token retained by
bmtMDMethod::MethodSignatureinbmtMethodImplInfo::IsBody, rather than reconstructing it fromMethodDesc. - Express audited nonthrowing enumeration cleanup consistently through
HENUMInternal::ClearEnumandCStructArray::Clear; retain real cleanup and outer unwinding. - Parse the outer signature header once on a local cursor in
SigPointer::PeekValueTypeTokenClosed, preserving nonconsuming API behavior and malformed-signature handling. - Group the initial builder records into one arena allocation while preserving initialization, alignment and lifetime; evaluate the allocation-space tradeoff.
- Locally express the nonreturning native-reader fatal path under
HOST_WASM, inside the existing non-DAC branch. Preserve the host-native diagnostic rationale for not globally markingEEPolicy::HandleFatalErroras nonreturning.
Reducing the entry function merely by restricting late inlining is not the objective: an isolated Binaryen inlining-budget experiment reduced that function's size but increased total module size.
Note
This issue was generated by GitHub Copilot from a local code-generation investigation.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
dotnet-policy-service commentedon Sep 25, 2026
Tagging subscribers to this area: @dotnet/area-meta
See info in area-owners.md if you want to be subscribed.
dotnet-policy-service commentedon Sep 25, 2026
Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.