Le ottimizzazioni WasmGC e delle chiamate al termine Wasm sono ora disponibili come base di riferimento

Data di pubblicazione: 29 gennaio 2025

Raccolta dei rifiuti di WebAssembly (WasmGC)

Esistono due tipi di linguaggi di programmazione: linguaggi con garbage collection e linguaggi che richiedono la gestione manuale della memoria. Esempi del primo, tra molti altri, sono Kotlin, PHP o Java. Esempi di quest'ultimo sono C, C++ o Rust. Come regola generale, i linguaggi di programmazione di alto livello hanno maggiori probabilità di avere la raccolta dei rifiuti come funzionalità standard.

In termini semplificati, la raccolta dei rifiuti è il tentativo di recuperare la memoria allocata dal programma, a cui non viene più fatto riferimento. Questa memoria è chiamata spazzatura. Esistono molte strategie per implementare la garbage collection. Uno dei più semplici da comprendere è il conteggio dei riferimenti, il cui obiettivo è conteggiare il numero di riferimenti agli oggetti in memoria.

Potrebbe sembrare un concetto astratto, ma i linguaggi di programmazione sono implementati in altri linguaggi di programmazione. Ad esempio, il runtime PHP è implementato principalmente in C. Se gli sviluppatori vogliono compilare un linguaggio come PHP in Wasm, in genere devono compilare tutte le parti, come il parser del linguaggio, il supporto della libreria, la raccolta dei rifiuti e altri componenti fondamentali.

Wasm viene eseguito nel browser nel contesto della lingua host JavaScript. In Chrome, JavaScript e Wasm vengono eseguiti in V8, il motore JavaScript open source di Google. Inoltre, V8 ha già un garbage collector. Ciò significa che gli sviluppatori che utilizzano, ad esempio, PHP compilato in Wasm, finiscono per inviare al browser un'implementazione del garbage collector del linguaggio portato (PHP) che ha già un garbage collector, il che è uno spreco. È qui che entra in gioco WasmGC.

Per scoprire di più su WasmGC, leggi l'articolo WebAssembly Garbage Collection (WasmGC) ora abilitata per impostazione predefinita in Chrome e, se vuoi approfondire, dai un'occhiata al post del blog V8 Un nuovo modo per portare in modo efficiente i linguaggi di programmazione con garbage collection a WebAssembly

Ottimizzazioni di chiamate al termine Wasm

Si dice che una chiamata sia in posizione finale se è l'ultima istruzione eseguita prima del ritorno dalla funzione corrente. I compilatori possono ottimizzare queste chiamate ignorando il frame del chiamante e sostituendo la chiamata con un salto. Questo è particolarmente utile per le funzioni ricorsive. Ad esempio, prendiamo questa funzione C che somma gli elementi di una lista connessa:

int sum(List* list, int acc) {
  if (list == nullptr) return acc;
  return sum(list->next, acc + list->val);
}

Con una chiamata normale, viene utilizzato uno spazio di stack O(n): ogni elemento dell'elenco aggiunge un nuovo frame allo stack delle chiamate. Con un elenco abbastanza lungo, questo potrebbe causare un overflow dello stack molto rapidamente. Sostituendo la chiamata con un salto, l'ottimizzazione delle chiamate finali trasforma efficacemente questa funzione ricorsiva in un ciclo che utilizza uno spazio di stack O(1):

int sum(List* list, int acc) {
  while (list != nullptr) {
    acc = acc + list->val;
    list = list->next;
  }
  return acc;
}

Questa ottimizzazione è particolarmente importante per i linguaggi funzionali. Si basano molto sulle funzioni ricorsive e quelle pure come Haskell non forniscono nemmeno strutture di controllo dei loop. Qualsiasi tipo di iterazione personalizzata utilizza in genere la ricorsione in un modo o nell'altro. Senza l'ottimizzazione delle chiamate finali, si verificherebbe molto rapidamente un overflow dello stack per qualsiasi programma non banale, che altrimenti esaurirebbe rapidamente lo spazio dello stack.

Inizialmente, WebAssembly non consentiva queste ottimizzazioni di chiamata finale, ma la situazione è cambiata con la proposta di estensione della chiamata finale. Per approfondire, leggi l'articolo Chiamate finali WebAssembly sul blog V8.

Conclusioni

Ora che WasmGC e le ottimizzazioni delle chiamate a coda sono disponibili come base di riferimento, un maggior numero di app può utilizzare queste funzionalità per migliorare le prestazioni, come ad esempio ha fatto Fogli Google eseguendo il porting del worker di calcolo di Fogli Google a WasmGC.