Sei sulla pagina 1di 29

Introduzione

Supporto ai Generics
Conclusioni

Supporto alla programmazione generica nel


compilatore ILDJIT

Luca Rocchini

Relatore: Prof. Stefano Crespi Reghizzi


Correlatore: Ing. Simone Campanoni

1/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

La meta-programmazione

Capacità di scrivere software che manipolino programmi


Paradigmi
Programmazione riflessiva permette elaborazioni che hanno per
oggetto il programma stesso, e in particolare la
struttura del suo codice sorgente
Programmazione generica è una forma di polimorfismo
parametrico per lo sviluppo di librerie riutilizzabili

2/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Cos’è la programmazione generica

Permette la definizione di famiglie astratte di algoritmi o classi


parametriche rispetto a tipi o a costanti di compilazione
Obiettivi
Riusabilità: la famiglia può generare un numero arbitrario di
implementazioni concrete
Efficienza: la definizione è accompagnata da vincoli (Concepts)
che specificano i requisiti per l’esistenza e l’efficienza
dell’algoritmo

3/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

La programmazione generica nei linguaggi

//Template C++
//Requirements:
// T must have the identity value
// T must have an operator ’+’
// T must have an operator ’=’
T sum(T arr[], int n) { La programmazione generica è
T res = T();
for (int i = 0; i < n; ++i) supportata da numerosi linguaggi di
res = res + arr[i];
return res; programmazione:
}
linguaggi funzionali: ML,
//C# Generics
T sum<T>(T arr[], int n)
Haskell . . .
where T : new(), IArith<T> {
T res = T(); linguaggi imperativi: C++,
for (int i = 0; i < n; ++i)
res = res.plus(arr[i]); Java (Type-Erasure), C# . . .
return res;
}

4/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Application virtual machine

Static time

Python C Java
Ambiente di esecuzione per
Source compiler Source compiler Source compiler
applicazioni portabili su architetture
e sistemi operativi diversi:
CIL Bytecode CIL Bytecode CIL Bytecode

esegue tipicamente applicazioni


in formato Bytecode
Run time
Virtual Machine

fornisce servizi all’applicazione


(e.g. allocazione di memoria,
Windows Linux Mac ...
threading . . . )

Intel x86 ARM EM64T ...

5/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

.NET
Lo standard ECMA-335 (.NET) specifica un’application virtual
machine simile alla più conosciuta Java Virtual Machine
Comprende
Common Intermediate Language (Bytecode)
Virtual Execution Environment (Macchina virtuale)
Meta-dati (Descrizione dei tipi, metodi . . . )
...

Caratteristiche
Supporto multi-linguaggio: object-oriented (e.g. C# . . . ),
funzionali (e.g. F# . . . )
Supporto multi-paradigma: programmazione riflessiva,
programmazione generica (Generics)
6/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

ILDJIT
L’implementazione del .NET sviluppata da:

Competitors
Mono
Microsoft .NET runtime

Caratteristiche innovative
Modularità
Parallelo e Distribuito
Multi-modalità: Ahead Of Time (AOT), Just In Time (JIT),
Dynamic Look Ahead (DLA)
7/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

ILDJIT: il CLI manager

Responsabile della gestione della semantica del .NET


Compiti
Tradurre il bytecode nella rappresentazione interna
Calcolare le rappresentazioni runtime dei tipi
Gestire l’accesso ai meta-dati
...
I Generics ha determinato una profonda revisione del modulo

8/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Traduzione delle classi generiche

Specializzazione: per ogni


parametrizzazione esiste una
rappresentazione dati e codice
specifica:
+ Qualità del codice
+ Dimensione del codice
Condivisione: esiste una
rappresentazione per tutte le
parametrizzazioni compatibili
(e.g. compatibilità binaria)
− Qualità del codice
− Dimensione del codice

9/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Traduzione delle classi generiche: specializzazione

ILDJIT usa la specializzazione per la traduzione dei Generics

10/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Traduzione delle classi generiche: specializzazione

ILDJIT usa la specializzazione per la traduzione dei Generics


Motivazione
Mascheramento dei ritardi: la tecnica DLA maschera la latenza
della traduzione
Informazione esplicite sui parametri: analisi dataflow più precise e
trasformazioni più aggressive
Estensione naturale del compilatore: soluzione migliore come
prima implementazione del supporto

10/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Gestione dei meta-dati

Accompagnano il bytecode
Il paradigma riflessivo permette
a runtime:
l’accesso alle descrizioni
emissione di nuovi meta-dati

11/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Gestione dei meta-dati

Accompagnano il bytecode
Il paradigma riflessivo permette
a runtime:
l’accesso alle descrizioni
emissione di nuovi meta-dati

Sistema critico
Efficienza nell’accesso →
Minore latenza di traduzione
Efficacia della descrizione →
Semplifica la riflessività

11/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Metodi virtuali

Identificano nella programmazione object-oriented i metodi che


possono essere ridefiniti nei tipi derivati
Invocazione
La risoluzione del metodo non può avvenire a compile-time →
Richiesto il dynamic dispatch (binding effettuato a runtime)

12/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Metodi virtuali

Identificano nella programmazione object-oriented i metodi che


possono essere ridefiniti nei tipi derivati
Invocazione
La risoluzione del metodo non può avvenire a compile-time →
Richiesto il dynamic dispatch (binding effettuato a runtime)

Virtual Table
Contiene gli indirizzi dei metodi il cui binding è dinamico
Richiede di conoscere compile-time il numero di metodi
Non permette ereditarietà multipla nella compilazione
incrementale (e.g JIT, DLA)

12/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Metodi virtuali generici

Problema
Quando la compilazione è incrementale (e.g. JIT, DLA) il numero
delle parametrizzazioni per metodi virtuali generici non è noto →
Virtual Table non è adatta

13/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Metodi virtuali generici

Problema
Quando la compilazione è incrementale (e.g. JIT, DLA) il numero
delle parametrizzazioni per metodi virtuali generici non è noto →
Virtual Table non è adatta

Tecniche alternative
2-Level Paged VTable è una estensione della Virtual Table per
gestire numero di parametrizzazione non noto
Interface Method Table permette di gestire ereditarietà multipla
e/o un numero non noto di metodi

13/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Metodi virtuali generici: dettaglio

2-Level Paged VTable Interface Method Table


1-Level contiene le famiglie Usa una tabella di Hash
di metodi Chiave: nome del metodo
2-Level contiene le La funzione di Hash è
parametrizzazioni utilizzate valutata a compile-time
14/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Risultati sperimentali

No runtime check nei test con 20x speed-up nelle interface call
contenitori generici rispetto alla versione senza
supporto ai Generics

15/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Risultati sperimentali: statistiche

Stato del progetto


Circa 300 000 linee di codice
318 file modificati
18 000 nuove linee di codice inserite
17 000 linee di codice rimosse

16/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Sviluppi futuri

Investigare la tecnica di condivisione del codice


Adottare schemi di traduzione specifici per ciascuna modalità
di compilazione
Implementare il Dynamic Language Runtime di Microsoft per
supportare linguaggi dinamici (e.g. Python, Ruby . . . )

17/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Domande?

18/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Sistema di Tipi

Categorie
Tipi valore: contengono direttamente i dati e sono allocati sullo
Stack (e.g. Integer, Float, Double . . . )
Tipi riferimento: riferimenti ad istanze del tipo allocate nello heap
(e.g. Object, String, Array . . . )

19/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Sistema di Tipi

Categorie
Tipi valore: contengono direttamente i dati e sono allocati sullo
Stack (e.g. Integer, Float, Double . . . )
Tipi riferimento: riferimenti ad istanze del tipo allocate nello heap
(e.g. Object, String, Array . . . )

Interoperabilità
Boxing: converte un istanza di tipo valore in un istanza di
tipo riferimento mantenendo la stessa struttura fisica
Unboxing: converte un istanza riferimento, il cui tipo dinamico è
un tipo valore, in un istanze di tipo valore
Le conversioni sono costose è presentano side-effects.
19/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Type-Erasure

Funzionamento
Mappa le parametrizzazione su un tipo non generico (raw type)
1 Sostituzione dei parametri con il tipo Object
2 Sostituzione delle parametrizzazioni con il raw type
...

Problema
Nessun informazione a runtime sui parametri →
impossibile sui parametri riflessività, Type Checking . . .
Richiede Boxing e Unboxing per gestire tipi valori e tipi
riferimento contemporaneamente

20/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Condivisione del codice

Utilizza strutture dati specifiche per ogni parametrizzazione per


contenere le oggetti che dipendo dai parametri
Strutture
Runtime Generic Context (RGCTX) contiene le oggetti che
dipendo solo da parametri della classe
Method Runtime Generic Context (MRGCTX) contiene le oggetti
che dipendo da almeno un parametro del metodo

Espressioni
Nome di Tipi (e.g. controlli di tipo)
Riferimenti ad oggetti statici (e.g. accesso ai campi statici)
Strutture dati necessarie per l’invocazione (e.g MGRCTX)
21/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Condivisione di codice: Runtime Generic Context

Permette la condivisioni di oggetti tra la gerarchia di tipi

Invocazione su tipo riferimento: RGCTX è accessibile attraverso


l’intestazione dell’oggetto su cui il metodo è invocato
Invocazione statica o su tipo valore: il caller passa RGCTX al
metodo come parametro addizionale
22/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Condivisione di codice: Method Runtime Generic Context

Tutti i metodi in un tipo con la stessa parametrizzazione


condividono lo stesso MRGCTX
Il caller passa MRGCTX al metodo come parametro
addizionale

23/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT
Introduzione
Supporto ai Generics
Conclusioni

Condivisione di codice: Inizializzazione

/* initialize slot with with corrispoding Type


Descriptor */
Due modalità di inizializzazione:
void * init rgctx type slot(...);
void * init mrgctx type slot(...); Totale: RGCTX e il MRGCTX
/* initialize slot with corrisponding static object */ sono popolati quando
void * init rgctx static object slot(...);
void * init mrgctx static object slot(...); vengono creati
/* initialize slot with corrispoding rgctx */ Parziale: Gli slot del RGCTX e
void * init rgctx generic rgctx slot(...);
void * init mrgctx generic rgctx slot(...); MRGCTX sono
/* initialize slot with corrispoding mrgctx */ popolati quando sono
void * init rgctx generic mrgctx slot(...);
void * init mrgctx generic mrgctx slot(...); acceduti per la prima
volta

24/24
Luca Rocchini Supporto alla programmazione generica nel compilatore ILDJIT

Potrebbero piacerti anche