Los compiladores, especialmente los JIT para lenguajes dinámicos como Ruby y Python, se enfrentan al problema de los métodos pequeños: al operar sobre unidades de código reducidas, carecen del contexto necesario para optimizar eficazmente. El inlining, que consiste en copiar el cuerpo de la función invocada dentro de la invocante, es la palanca que desbloquea otras optimizaciones como la eliminación de carga-almacenamiento o el análisis de escape. Sin embargo, aplicar inlining de forma incorrecta puede inflar el tamaño del código, degradar el rendimiento de la caché, interferir con otras optimizaciones y alargar el tiempo de compilación. El autor presenta un estudio exhaustivo de las heurísticas de inlining empleadas en compiladores JIT reales (YJIT, SpiderMonkey, JavaScriptCore, Cinder) y en la literatura académica.
El artículo comienza con un ejemplo ilustrativo: la clase Point en Ruby, cuyo método distance realiza ocho llamadas a métodos y dos asignaciones en el montón, a pesar de ser una operación matemática simple. Sin inlining, optimizaciones avanzadas no pueden actuar porque prácticamente todo escapa y tiene efectos secundarios. Luego describe el desafío fundamental: el compilador debe decidir qué métodos inlinear basándose en criterios locales (tamaño, frecuencia de llamada) pero enfrentando impactos no locales. Las heurísticas comunes incluyen límites de tamaño, recuento de llamadas, y el uso de perfiles de tipo o contexto de llamada.
Entre las técnicas analizadas destacan: el splitting por tipo de YJIT (que clona código compilado según los tipos de los argumentos), el 'trial inlining' de SpiderMonkey (que permite al invocante compartir memoria de perfiles con el candidato a inlineado) y el inlineado a nivel de bytecode de JavaScriptCore. El autor también menciona la importancia de los perfiles con contexto de llamada para evitar que información de otros invocantes contamine la toma de decisiones. Concluye que implementar la mecánica básica del inlining puede hacerse en meses, pero afinar las heurísticas lleva años, y que el equilibrio entre rendimiento, tamaño de código y tiempo de compilación es un reto abierto.
