[wasm] [JIT]: Enable more GC-ref local candidates by introducing spilling

Abierto
#136,663 2 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
42/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
csharp, wasm

Línea de trabajo

Read PR #135543 and trace how Wasm local candidates are selected and how GC safepoints treat references. The issue gives an example in System.SpanHelpers.IndexOfAny, where a GC reference could stay in a local if it is spilled to a pinned safe slot before a call. Done means enabling profitable GC reference locals with spills that preserve GC correctness; the issue names no implementation files or tests.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

arch-wasm area-CodeGen-coreclr tenet-performance

https://github.com/dotnet/runtime/pull/135543 introduced GC refs as Wasm local candidates, but only if they are never live across a GC safepoint. We could consider pushing further and allowing GC refs to be local candidates if it is profitable -- inserting spills as necessary to maintain GC correctness. Take the following instruction sequence from
int System.SpanHelpers.IndexOfAny<__Canon>(ref __Canon, __Canon, __Canon, int) as an example:
This is part of computing

lookUp.Equals(value0)

with T lookup; T value0 where T: IEquatable<T>?


 00BF:                       i32.load align=1
 00C2:                       i32.store align=1 offset=12 ;; spill value0
 00C5:                       local.get 0
 00C7:                       i32.load align=1 offset=12 ;; load value0 for nullcheck
 00CA:                       i32.eqz
 00CB:                       br_if 0
;; call setup for a future call to `Equals`
 00CD:                      local.get 0
 00CF:                       local.get 0
 00D1:                       i32.load align=1 offset=12  ;; load value0
 00D4:                       local.get 0
 00D6:                       i32.load align=1 offset=20 ;; load lookUp
;; setup + call for System.IEquatable lookup
 00D9:                       local.get 0
 00DB:                       local.get 1
 00DD:                       global.get 1 // imageBase
 00DF:                       i32.load align=1 offset=6860860 // METHOD_DICTIONARY_LOOKUP: System.IEquatable`1<mvar #0> (TYPE_HANDLE)
 00E5:                       local.tee 67
 00E7:                       local.get 67
 00E9:                       i32.load align=1
 00EC:                       call_indirect 0 (type 59) 
... 

In this case, the slot SP+12 is a gc ref. Notice that we update its value and store it at 00C2, before loading it multiple times at 00C7 and 00D1, with no GC safepoint in between. If we assigned this ref to a local instead, we could delete the loads but keep the initial spill for GC correctness, and we'd instead have:

i32.load align=1
local.tee <ref> ;; tee ref value0 into a local home
i32.store align=1 offset=12 ;; spill to pinned "safe slot"
local.get <ref> ;; load value0 from local home
i32.eqz
br_if 0
local.get 0
local.get <ref> ;; load value0 from local home
local.get 0
i32.load align=1 offset=20
local.get 0
local.get 1
global.get 1 // imageBase
i32.load align=1 offset=6860860 // METHOD_DICTIONARY_LOOKUP: System.IEquatable`1<mvar #0> (TYPE_HANDLE)
local.tee 67
local.get 67
i32.load align=1
call_indirect 0 (type 59)
;; local <ref> is safe to use since it was spilled to a pinned slot previously before the call

which has 1 net fewer instruction and less stack traffic.

Lenguaje dominante
C#
Estrellas
18.4k
Forks
5.8k
Merge medio
2 d 13 h
PR fusionados (30 d)
588

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de dotnet/runtime

Todos los issues de dotnet/runtime

Issues similares

Más issues de C#

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.