Suprimir la emisión de la localsinit marca.Suppress emitting of localsinit flag.

  • [x] propuesto[x] Proposed
  • [] Prototipo: no iniciado[ ] Prototype: Not Started
  • [] Implementación: no iniciada[ ] Implementation: Not Started
  • [] Especificación: no iniciada[ ] Specification: Not Started

ResumenSummary

Permite suprimir la emisión de la localsinit marca a través del SkipLocalsInitAttribute atributo.Allow suppressing emit of localsinit flag via SkipLocalsInitAttribute attribute.

MotivaciónMotivation

FondoBackground

Por las variables locales de especificación de CLR que no contienen referencias no se inicializan en un valor determinado por la máquina virtual o JIT.Per CLR spec local variables that do not contain references are not initialized to a particular value by the VM/JIT. La lectura de estas variables sin inicialización tiene seguridad de tipos, pero, de lo contrario, el comportamiento es indefinido y específico de la implementación.Reading from such variables without initialization is type-safe, but otherwise the behavior is undefined and implementation specific. Normalmente, las variables locales sin inicializar contienen los valores que se dejaron en la memoria que ocupa ahora el marco de pila.Typically uninitialized locals contain whatever values were left in the memory that is now occupied by the stack frame. Esto podría provocar un comportamiento no determinista y difícil reproducir errores.That could lead to nondeterministic behavior and hard to reproduce bugs.

Hay dos maneras de "asignar" una variable local:There are two ways to "assign" a local variable:

  • almacenando un valor oby storing a value or
  • al especificar localsinit la marca que fuerza a todo lo que se asigna, el grupo de memoria local debe inicializarse con ceros Nota: Esto incluye las variables locales y los stackalloc datos.by specifying localsinit flag which forces everything that is allocated form the local memory pool to be zero-initialized NOTE: this includes both local variables and stackalloc data.

No se recomienda el uso de datos no inicializados y no se permite en código comprobable.Use of uninitialized data is discouraged and is not allowed in verifiable code. Aunque podría ser posible demostrar que, por medio del análisis de flujo, se permite que el algoritmo de comprobación sea conservador y simplemente se requiere que localsinit se establezca.While it might be possible to prove that by the means of flow analysis, it is permitted for the verification algorithm to be conservative and simply require that localsinit is set.

El compilador de C# históricamente emite una localsinit marca en todos los métodos que declaran variables locales.Historically C# compiler emits localsinit flag on all methods that declare locals.

Aunque C# emplea el análisis de asignación desfinito que es más estricto que el que necesitaría la especificación de CLR (C# también necesita considerar el ámbito de las variables locales), no se garantiza estrictamente que el código resultante se pueda comprobar formalmente:While C# employs definite-assignment analysis which is more strict than what CLR spec would require (C# also needs to consider scoping of locals), it is not strictly guaranteed that the resulting code would be formally verifiable:

  • Es posible que las reglas de CLR y C# no acuerden si el paso de un argumento local como out es use .CLR and C# rules may not agree on whether passing a local as out argument is a use.
  • Es posible que las reglas de CLR y C# no concuerden en el tratamiento de ramas condicionales cuando se conocen las condiciones (propagación constante).CLR and C# rules may not agree on treatment of conditional branches when conditions are known (constant propagation).
  • CLR también podría requerir localinits , ya que se permite.CLR could as well simply require localinits, since that is permitted.

ProblemaProblem

En las aplicaciones de alto rendimiento, el costo de la inicialización de cero forzada podría ser apreciable.In high-performance application the cost of forced zero-initialization could be noticeable. Es especialmente evidente cuando stackalloc se usa.It is particularly noticeable when stackalloc is used.

En algunos casos, JIT puede Elide la inicialización cero inicial de las variables locales individuales cuando dicha inicialización se "elimina" mediante asignaciones posteriores.In some cases JIT can elide initial zero-initialization of individual locals when such initialization is "killed" by subsequent assignments. No todas JITs lo hacen y esta optimización tiene límites.Not all JITs do this and such optimization has limits. No ayuda con stackalloc .It does not help with stackalloc.

Para ilustrar que el problema es real, hay un error conocido en el que un método que no contiene IL variables locales no tendría ninguna localsinit marca.To illustrate that the problem is real - there is a known bug where a method not containing any IL locals would not have localsinit flag. Los usuarios ya están aprovechando el error mediante la colocación stackalloc de estos métodos, intencionalmente para evitar los costos de inicialización.The bug is already being exploited by users by putting stackalloc into such methods - intentionally to avoid initialization costs. Es decir, a pesar de que la ausencia de IL variables locales es una métrica inestable y puede variar en función de los cambios en la estrategia CODEGEN.That is despite the fact that absence of IL locals is an unstable metric and may vary depending on changes in codegen strategy. El error debe corregirse y los usuarios deben obtener una forma más documentada y confiable de suprimir la marca.The bug should be fixed and users should get a more documented and reliable way of suppressing the flag.

Diseño detalladoDetailed design

Permite especificar System.Runtime.CompilerServices.SkipLocalsInitAttribute como una manera de indicar al compilador que no emita la localsinit marca.Allow specifying System.Runtime.CompilerServices.SkipLocalsInitAttribute as a way to tell the compiler to not emit localsinit flag.

El resultado final de este es que las variables locales no pueden inicializarse con ceros por el JIT, que en la mayoría de los casos es inobservable en C#.The end result of this will be that the locals may not be zero-initialized by the JIT, which is in most cases unobservable in C#.
Además de los stackalloc datos, no se inicializarán en cero.In addition to that stackalloc data will not be zero-initialized. Eso es claramente observable, pero también es el escenario más motivador.That is definitely observable, but also is the most motivating scenario.

Los destinos de atributo permitidos y reconocidos son: Method , Property , Module , Class , Struct , Interface , Constructor .Permitted and recognized attribute targets are: Method, Property, Module, Class, Struct, Interface, Constructor. Sin embargo, el compilador no requerirá que el atributo esté definido con los destinos enumerados, ni será de interés en qué ensamblado está definido el atributo.However compiler will not require that attribute is defined with the listed targets nor it will care in which assembly the attribute is defined.

Cuando se especifica el atributo en un contenedor ( class , module , que contiene el método para un método anidado,...), la marca afecta a todos los métodos contenidos en el contenedor.When attribute is specified on a container (class, module, containing method for a nested method, ...), the flag affects all methods contained within the container.

Los métodos sintetizados "heredan" la marca del contenedor lógico/propietario.Synthesized methods "inherit" the flag from the logical container/owner.

La marca solo afecta a la estrategia CODEGEN para los cuerpos de método reales.The flag affects only codegen strategy for actual method bodies. (Por ejemplo:I.E. la marca no tiene ningún efecto en los métodos abstractos y no se propaga a los métodos de reemplazo/implementación.the flag has no effect on abstract methods and is not propagated to overriding/implementing methods.

Esto es explícitamente una característica del compilador y no una característica del lenguaje.This is explicitly a compiler feature and not a language feature.
Del mismo modo que la línea de comandos del compilador cambia la característica controla los detalles de implementación de una estrategia de CODEGEN determinada y no necesita ser necesaria para la especificación de C#.Similarly to compiler command line switches the feature controls implementation details of a particular codegen strategy and does not need to be required by the C# spec.

InconvenientesDrawbacks

  • Es posible que los compiladores anteriores y otros no respeten el atributo.Old/other compilers may not honor the attribute. Omitir el atributo es un comportamiento compatible.Ignoring the attribute is compatible behavior. Solo puede dar lugar a una ligera disminución del rendimiento.Only may result in a slight perf hit.

  • El código sin localinits marca puede desencadenar errores de comprobación.The code without localinits flag may trigger verification failures. Los usuarios que solicitan esta característica generalmente no se ven preocupadas por la capacidad de comprobación.Users that ask for this feature are generally unconcerned with verifiability.

  • Aplicar el atributo en niveles superiores a un método individual tiene un efecto no local, que es observable cuando stackalloc se usa.Applying the attribute at higher levels than an individual method has nonlocal effect, which is observable when stackalloc is used. Aún así, este es el escenario más solicitado.Yet, this is the most requested scenario.

AlternativasAlternatives

  • omitir la localinits marca cuando el método se declara en unsafe contexto.omit localinits flag when method is declared in unsafe context. Esto podría provocar un cambio de comportamiento silencioso y peligroso de determinista a no determinista en el caso de stackalloc .That could cause silent and dangerous behavior change from deterministic to nondeterministic in a case of stackalloc.

  • omitir localinits siempre la marca.omit localinits flag always. Incluso peor que el anterior.Even worse than above.

  • omitir localinits marca a menos que stackalloc se use en el cuerpo del método.omit localinits flag unless stackalloc is used in the method body. No aborda el escenario más solicitado y puede desactivar el código sin ninguna opción para revertirlo de nuevo.Does not address the most requested scenario and may turn code unverifiable with no option to revert that back.

Preguntas no resueltasUnresolved questions

  • ¿Se debe emitir realmente el atributo a los metadatos?Should the attribute be actually emitted to metadata?

Design MeetingsDesign meetings

Ninguno todavía.None yet.