¿Qué habilidades se requieren para escribir una máquina virtual Java?

Si quieres competir con las implementaciones existentes, mira las otras respuestas.

Si desea una implementación pequeña que pueda ejecutar un subconjunto de aplicaciones Java, en realidad es muy factible. Todo lo que realmente necesita es leer los archivos de la clase, saber escribir un intérprete y las especificaciones de JVM.

Para el primero, es posible que tenga la suerte de encontrar una biblioteca que pueda analizar los archivos por usted, de lo contrario, deberá escribir un analizador a mano. Existen muchos recursos sobre cómo escribir un analizador sintáctico, o puede usar un generador de analizador sintáctico siempre que sea compatible con la entrada binaria. El hecho de que la JVM utilice un formato binario con longitudes codificadas significa que el análisis es en realidad más fácil de lo habitual.

Si nunca ha escrito un intérprete, escriba uno para Brainfuck antes de continuar. Puede intentar convertir el código de bytes en una estructura de árbol primero, pero es completamente opcional. Al final, el intérprete solo pasa por cada instrucción y realiza cualquiera que sea su operación. Para los campos de objetos, un simple hashmap debería ser suficiente.

La especificación JVM será su mejor amigo y asegúrese de mantenerla abierta en todo momento durante el proyecto. De particular mención es el capítulo 4, que será importante al escribir el analizador, y el capítulo 6, que será importante al escribir el bucle central en el intérprete. El Capítulo 5 también será útil si desea intentar ejecutar aplicaciones reales o con el tiempo de ejecución oficial.

Si le preocupan cosas como la recolección de basura, siempre puede tomar la opción simple: no lo haga. Es posible que se quede sin memoria o no recolecte basura, pero funcionará bien hasta entonces. Otra opción es aprovechar tu idioma de host. Mi primer proyecto JVM fue en Go, por lo que no tuve que hacer nada para administrar la memoria porque podía dejar que el tiempo de ejecución Go se encargara de eso.

Actualmente estoy trabajando en el segundo intento, esta vez en Kotlin. Y sí, Kotlin se ejecuta en la JVM. (Me especializo en lo poco práctico).

Tendría que entender cómo construir un intérprete para los códigos de bytes. Para hacerlo, debe emular lo que hace una computadora de hardware, aunque es una tarea mucho más fácil. Revisé un poco y hay 198 de ellos.

Para construir un intérprete, necesitaría la capacidad de ejecutar cada bytecode y modificar el estado de la máquina, la memoria, los registros, las variables de condición y demás.

El problema probable es que emular algunas partes, como los códigos que ejecutan métodos, o implementar puntos flotantes sería difícil. Al menos el punto flotante es difícil si no puede obtener el estado FP de la máquina subyacente que está ejecutando su código. El punto flotante IEEE es excelente, pero emularlo, incluidos los comportamientos alrededor de pasteles como NaN o más o menos infinito, es difícil, y lidiar con bits pegajosos es complicado. Para tener éxito, necesitaría la implementación de procesadores.

Más allá del intérprete, necesitaría algún tipo de gestión de memoria, es decir, recolección de basura. La respuesta más simple sería una marca y un barrido GC donde la máquina se detiene y todas las partes accesibles del montón de memoria se marcan si hay un objeto al que se puede acceder y luego esos objetos se copian en un montón de noticias. Los objetos no accesibles se finalizan y se recupera el montón anterior.

Incluso una JVM simple también necesitaría algún tipo de gestión de subprocesos.

Cuanto trabajo Supongo que incluso una JVM tonta llevaría un par de años. Recuerde, no solo se deben probar los códigos de bytes individuales, sino que se deben ejecutar programas completos para detectar interacciones que no forman parte de la JVM.

Sin embargo, debe recordar esto, aunque la JVM no lo incluye, un entorno java en ejecución también significa construir una cantidad sustancial de métodos escritos en código nativo.

Sin embargo, para construir un pseudo JVM de juguete que ejecute una pequeña cantidad de códigos de bytes, o incluso solo un emulador con un pequeño conjunto de instrucciones de la máquina y que no se pueda recolectar basura en unas pocas semanas. Me apegaría a las llamadas aritméticas, lógicas y de función (no llamadas a métodos). Emule algo como un 6800, 6502 o incluso un 8008.

No escribes una “Máquina virtual Java”, porque ya hay una, altamente eficiente … 🙂

¿Quieres escribir solo una “máquina virtual”, no? A menos que realmente quieras seguir la especificación JVM completa, ¡pero estás más allá del “pequeño juguete”!

¿Cantidad de trabajo? Ni idea, nunca lo intenté. Quizás no tanto. Apuesto a que pasarás más tiempo en el tablero de diseño que en la codificación en sí …

Habilidades: buen conocimiento de lo que se necesita para que un programa funcione, lo que necesita su idioma, etc.

Pongamos las cosas en perspectiva:

Hay alguna funcionalidad de nivel base. Una JVM que solo interpreta bytecode y realiza una recolección de basura rudimentaria: supongo que tiene de 6 a 12 meses de tiempo de implementación para una sola (empresa experimentada o desarrollador de c ++).

Pero para llegar a una JVM que pueda competir con los productos existentes (por ejemplo, con respecto a la compilación justo a tiempo) … Yo diría: una sola persona tendría que invertir 5 años o más.

Debe comprender que muchos años de investigación y millones y millones de dólares se destinaron a las JVM de hoy.

Es como preguntar “¿qué habilidades necesito para construir un automóvil y cuánto tiempo tomará?” Y sí, un buen ingeniero podría construir un automóvil por su cuenta, pero ¿crees que una sola persona podría construir un Porsche 911 desde cero, solo?

Esta presentación puede darle algunas pistas.