es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Significa FIXME: NYI en MutableCallSite.syncAll que aún no está implementado?

En java.lang.invoke existen dos constructos interesantes, MutableCallSite y SwitchPoint. Se describen como ofreciendo una forma de cambiar sus objetivos (a cualquier objetivo diferente para un MutableCallSite o a un objetivo predefinido cuando se invalide para un SwitchPoint), con la garantía de que otros hilos recogerán la actualización, pero con una sobrecarga reducida para los usos de la MCS o SP cuando no se ha cambiado (reducido, en comparación con una comprobación con efectos de sincronización en cada uso). La documentación de SwitchPoint dice que se puede construir sobre MutableCallSite, y en las fuentes de OpenJDK en GitHub, se hace. Así que el lugar para buscar la magia está en MutableCallSite.syncAll.

En la fuente de ese método, la magia parece tener tres pasos:

  • El paso 1 es un lazySet (efectos JMM de setRelease) en un AtomicInteger privado que ningún otro hilo nunca leerá;
  • El paso 2 mira todas las referencias MutableCallSite pasadas para confirmar que ninguna es nula;
  • El paso 3 es un comentario: // FIXME: NYI

A un ojo inexperto, parece que hay trabajo real que hacer para ese comentario. ;).

Parece que los desarrolladores de Android vieron ese comentario y eliminaron el método de Android porque no querían publicitar un método no implementado (aunque MutableCallSite sin syncAll no parece ser una construcción útil). ¿Tenían razón?

Por otro lado, parece muy poco probable que esté faltando tan claramente su funcionalidad. Ha estado en Java desde Java 7, y aparentemente proyectos importantes como Nashorn y JRuby han hecho un uso intensivo de MutableCallSite y SwitchPoint. No he tropezado con comentarios sobre que estén rotos debido a esto.

Además, entiendo que algunas implementaciones en la biblioteca de clases de Java pueden parecer incompletas porque partes de la magia son suministradas por la implementación de la JVM. Este parece ser un ejemplo principal donde eso podría estar sucediendo, pero no he podido encontrar los detalles.

¿Alguien conoce los detalles? Sería bueno saber qué comportamiento confiable realmente tiene. La documentación de syncAll suena muy prometedora al principio. Parafraseando:

  1. su efecto es forzar a todos los futuros lectores del objetivo de cada sitio de llamada a aceptar el valor más recientemente almacenado
  2. puede (¿puede??) bloquearse hasta que todos los lectores hayan (de alguna manera) eliminado todas las versiones anteriores
  3. los hilos de lectura pueden observar versiones anteriores del objetivo hasta que se devuelve la llamada a syncAll (¿Significa esto que pueden no hacerlo después de que se haya devuelto la llamada a syncAll? Y si es así, ¿no implicaría eso que #2 es realmente algo más fuerte que “puede”?)
  4. es “probablemente costoso” (como la compensación por tener getTarget sea barato; esa es la parte mágica).

Pero más tarde en la misma documentación, profundizando en los detalles de JMM, dice “Si (otro hilo) T ejecuta una acción de sincronización A después de la escritura volátil” … entonces debe ver el objetivo actualizado.

Eso suena un poco… menos sólido.

¿Se basa todo esto en algún conocimiento de implementación de JVM que coloca un límite superior en cuanto tiempo puede tardar después de que se devuelve la llamada a syncAll? Si es así, ¿se puede establecer ese límite superior?

Si realmente no falta nada y la cosa funciona como se anuncia, ¿valdría la pena eliminar el // FIXME: NYI del origen (y tal vez reemplazarlo por una explicación de lo que realmente sucede)?

Para más información: versión anterior de esta pregunta publicada en la lista mlvm-dev pero no atrajo ninguna respuesta.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Pregunta:

    ¿Cuál es la funcionalidad de MutableCallSite y SwitchPoint en java.lang.invoke? ¿Cómo funciona MutableCallSite.syncAll y por qué fue eliminado de Android? ¿Es posible que la funcionalidad faltante sea proporcionada por la implementación de la JVM? ¿Cuáles son los detalles de los efectos de JMM de syncAll y es confiable? ¿Debería eliminarse el FIXME: NYI en el código fuente y reemplazarse con una explicación de lo que realmente sucede?

    Respuesta:

    En java.lang.invoke, MutableCallSite y SwitchPoint proporcionan construcciones que permiten cambiar los objetivos con la garantía de que otros hilos recogerán la actualización, pero sin la sobrecarga de sincronización asociada con el bloqueo. MutableCallSite permite que sus objetivos se cambien por un objetivo arbitrario diferente, mientras que SwitchPoint permite que se cambien a un objetivo predefinido cuando se invalida. La documentación de SwitchPoint indica que puede construirse sobre MutableCallSite mediante el uso del método syncAll.

    En el código fuente de MutableCallSite.syncAll, hay tres pasos. El primer paso es una operación lazySet en un AtomicInteger privado que ningún otro hilo leerá. El segundo paso confirma que ninguna de las referencias MutableCallSite pasadas es nula. El tercer paso es un comentario FIXME: NYI, lo que indica que el método aún no está implementado.

    Android eliminó el método MutableCallSite.syncAll de su implementación porque no quería anunciar un método no implementado, aunque MutableCallSite sin syncAll no es una construcción útil. Sin embargo, parece poco probable que falte la funcionalidad de un método tan importante y proyectos como Nashorn y JRuby han hecho un uso intensivo de MutableCallSite y SwitchPoint sin encontrar ningún problema.

    Es posible que la funcionalidad faltante de MutableCallSite.syncAll sea proporcionada por la implementación de la JVM. Algunas implementaciones en la biblioteca de clases de Java pueden parecer incompletas porque partes de la magia son suministradas por la implementación de la JVM. Sin embargo, los detalles de esto no están claros.

    Los efectos de JMM de syncAll son prometedores, ya que obligan a todos los lectores futuros del destino de cada sitio de llamada a aceptar el valor almacenado más reciente. Sin embargo, el método puede bloquearse hasta que todos los lectores hayan eliminado caché de las versiones anteriores, y los hilos lectores pueden observar versiones anteriores del objetivo hasta que se haya realizado la llamada syncAll. Esto implica que la robustez de syncAll no está del todo clara.

    No está claro si el límite máximo de tiempo que puede tardar un hilo en ejecutar una acción de sincronización después de la escritura volátil se basa en el conocimiento de la implementación de la JVM. Si no hay funcionalidad faltante, puede valer la pena eliminar el comentario FIXME: NYI del código fuente y reemplazarlo con una explicación de lo que realmente sucede.

Comments are closed.