GC Intrinsics para el Backend LLVM
Archivo: src/gc_intrinsics.rs (274 líneas)
¿Por qué existe?
Define las intrínsecas de LLVM necesarias para integrar el GC generacional (gc.rs) con código compilado por el backend LLVM. Para que el GC pueda pausar la ejecución y escanear el stack, el compilador debe decirle en qué puntos del código es seguro colectar y qué slots del stack contienen punteros GC. Este módulo modela esos contratos: safe points, stack maps, registros GC y write barriers.
Componentes
El módulo cubre cuatro mecanismos que LLVM expone vía intrinsics: safe points (puntos donde el GC puede pausar la ejecución), stack maps (qué slots contienen punteros), write barriers (llamadas antes de escribir punteros GC al heap) y GC roots (raíces registradas en cada safe point).
| Componente | Descripción |
|---|---|
GcStackSlot | Un slot del stack que contiene un puntero GC: offset desde el frame pointer y flag is_root |
StackMap | Mapa de una función: function_id, safe_point_offset, slots gc_slots y registros gc_registers con punteros GC |
GcRegister | Registro que contiene un puntero GC: name (RAX, RCX, etc.) y flag is_root |
WriteBarrier | Clasifica la barrera necesaria para una escritura: None, RememberedSet o YoungOnly |
SafePoint | Descriptor de un safe point: pc_offset, stack_map asociado y frame_depth |
GcIntrinsicsManager | Registra y consulta stack maps y safe points por función |
LlvmGcPatterns | Helpers que generan el patrón LLVM IR para safe points y write barriers |
Clasificación de write barriers
WriteBarrier::for_write(obj_gen, val_gen) decide qué barrera se necesita para una escritura: old→young requiere registrar en el RememberedSet; cualquier escritura a un objeto young no necesita barrera (YoungOnly); old→old tampoco (None).
Patrones LLVM IR
LlvmGcPatterns expone los nombres de intrinsics usados y genera el IR textual:
| Método | Salida |
|---|---|
statepoint_pattern() | llvm.experimental.gc.statepoint |
relocate_pattern() | llvm.experimental.gc.relocate |
result_pattern() | llvm.experimental.gc.result |
emit_safe_point(...) | Comentario con el número de raíces + call void @llvm.experimental.gc.safepoint() |
emit_write_barrier(...) | call void @__gc_write_barrier(ptr %obj, ptr %val) para RememberedSet; comentario para los demás casos |
Cómo se integra
Es el puente entre el backend LLVM y el runtime GC: el backend registra un StackMap por función compilada (new_function_id → register_stack_map), marca los safe points (register_safe_point) e inserta las write barriers según WriteBarrier::for_write. En runtime, el GC usa find_stack_map para localizar el mapa más cercano a un PC dado y is_safe_point para saber si puede pausar.
function_ids únicos (desde 1) y soporta búsqueda del stack map más cercano a un PC, incluso cuando el PC cae entre safe points.