La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Memoria gestita staticamente: allocata dal compilatore prima dellesecuzione in una zona fissa della memoria (stabilita dal compilatore) –variabili globali.

Presentazioni simili


Presentazione sul tema: "Memoria gestita staticamente: allocata dal compilatore prima dellesecuzione in una zona fissa della memoria (stabilita dal compilatore) –variabili globali."— Transcript della presentazione:

1 memoria gestita staticamente: allocata dal compilatore prima dellesecuzione in una zona fissa della memoria (stabilita dal compilatore) –variabili globali – istruzioni del codice oggetto – costanti – tabelle del compilatore per il supporto a run-time del linguaggio (gestione nomi, type checking, garbage collection) –informazioni locali alle procedure (se non è supportata la ricorsione): variabili locali, parametri indirizzo di ritorno

2

3 memoria gestita dinamicamente (pila a run-time); blocchi in-line A: {int a = 1; int b = 0; B: {int c = 2; int b = 3; } b = a+1; } push a; push b pop push c; push b pop

4

5

6

7 record di attivazione (frame): lo spazio di memoria allocato sulla pila e dedicato a un blocco in-line (o a una procedura attivata); per i blocchi in-line contiene: – risultati intermedi (risultati senza nome esplicito) – variabili locali (interne al blocco, dimensione nota) – puntatore di catena dinamica (link dinamico o di controllo; punta al precedente RdA sulla pila)

8

9

10 per le procedure contiene: – risultati intermedi (risultati senza nome esplicito) – variabili locali (interne al blocco e di dimensione nota non array dinamici, per esempio) – puntatore di catena dinamica (link dinamico o di controllo; punta al precedente RdA sulla pila) – puntatore di catena statica (informazioni per gestire lo scope statico) – indirizzo di ritorno, indirizzo del risultato; – parametri; i nomi sono memorizzati nel RdA ? offset rispetto allindirizzo del blocco in cui la variabile è memorizzata

11

12

13 gestione a run-time della pila di sistema il compilatore inserisce frammenti di codice prima o dopo la chiamata di procedura (o di un blocco) – sequenza di chiamata: codice aggiunto al chiamante ed eseguito prima della chiamata di procedura e dopo la terminazione della procedura chiamata – prologo: codice aggiunto al chiamato ed eseguito subito dopo la chiamata – epilogo: codice aggiunto al chiamato ed eseguito al termine della procedura chiamata come sono distribuite queste attività ?

14 sequenza di chiamata (chiamante) e prologo (chiamato) – modifica del program counter (e salvataggio del vecchio valore per mantenere lindirizzo di ritorno) – allocazione spazio sulla pila (e modifica del puntatore alla memoria libera sulla pila) – modifica del puntatore al (nuovo) RdA – passaggio dei parametri (fatto dal chiamante) – salvataggio dei registri (fra cui il vecchio puntatore al RdA) – esecuzione codice di inizializzazione

15 epilogo (chiamato) e sequenza di chiamata (chiamante) – ripristino del program counter – restituzione dei valori (parametri o valore funzione) – ripristino registri (fra cui il vecchio puntatore al RdA) – esecuzione codice di finaizzazione – deallocazione spazio sulla pila (il RdA della procedura terminata è rimosso dalla pila) di quali strutture dati ho bisogno per implementare questa gestione? cosa succede se posso allocare e deallocare esplicitamente la memoria?

16 memoria gestita dinamicamente (heap) int *p, *q; p = malloc(sizeof(int)); q = malloc(sizeof(int)); *p = 0; *q = 1; free(p); free(q): heap: zona di memoria usata per gestire allocazioni esplicite di memoria (con blocchi a dimensione fissa o variabile) le operazioni di deallocazione della memoria sono fatte nello stesso ordine di quelle di allocazione; no gestione LIFO

17 heap con blocchi di dimensione fissa (lista libera)

18

19 heap con blocchi di dimensione variabile se il linguaggio permette lallocazione a run-time di memoria di dimensione variabile, la LL non è adeguata due esigenze contrastanti: – migliorare loccupazione della memoria (frammentazione interna ed esterna) – velocizzare la gestione dello heap tecniche di allocazione: – unica lista libera – liste libere multiple

20

21 unica lista libera - un unico blocco di memoria contiene lintero heap; se è richiesta lallocazione di n parole di memoria, il puntatore avanza di n (analogo per le richieste successive) - i blocchi deallocati sono collegati in una lista libera; quando lo heap finisce si passa allo spazio deallocato, in due modi: utilizzando direttamente la lista libera: si cerca nella lista un blocco con dimensione adeguata, seguendo due principi: first fit (miglior tempo di gestione) best fit (migliore occupazione di memoria) compattando la memoria libera: tutti i blocchi attivi spostati allestremità dello heap (si può fare sempre?)

22 liste libere multiple - più liste libere, ognuna delle quali con blocchi di dimensioni diverse se è richiesta lallocazione di n parole di memoria, è selezionata la lista che contiene blocchi di dimensione appropriata - le dimensioni dei blocchi possono essere statiche o dinamiche buddy system le dimensioni dei blocchi sono potenze di 2; richiedo un blocco pari a n; se k è tale che 2 k n, allora si cerca un blocco libero in lista 2 k ; altrimenti, si prende un blocco in 2k+1, si divide in due, uno è occupato e laltro entra nella lista 2k; quando un blocco è liberato, si cerca il suo compagno e si riunificano heap di Fibonacci come sopra, ma con numeri di Fibonacci (che crescono di meno)

23 implementazione regole di scope (come risolvere un riferimento non locale) scope statico o scope annidato più vicino lambiente in qualsiasi punto e in qualsiasi momento dipende SOLO dalla struttura sintattica del programma (il RdA collegato dal puntatore di catena dinamica NON è il record in cui cercare per risolvere un riferimento non locale) scope dinamico lassociazione valida per un nome X, in un punto P di un programma, è la più recente associazione creata (in senso temporale) per X che sia ancora attiva quando il flusso di esecuzione arriva a P

24 scope statico: la catena statica A: {int y = 0; B: {int x = 0; void pippo(int n) { x = n+1; y = n+2; } C: {int x = 1; pippo(2); write(x); } write(x); } scope statico: x (non locale in pippo) è quella dichiarata nel blocco B, non in C

25 scope statico: la catena statica

26

27 con la sequenza di chiamate A B C D E C, si ha

28 la gestione della catena statica è fatta nella sequenza di chiamata, nel prologo e nellepilogo; il chiamante calcola il puntatore di catena statica del chiamato e lo passa al chiamato; due casi: – chiamato allinterno del chiamante: il chiamante passa al chiamato il puntatore al proprio RdA – chiamato allesterno del chiamante: il chiamante calcola il puntatore di catena statica deferenziando k+1 volte il proprio puntatore di catena statica, con k = distanza di livello di annidamento fra chiamato e chiamante (nota a compile-time) il chiamato riceve il puntatore di catena statica e lo memorizza nel proprio RdA

29 la tabella dei simboli contiene - i livelli di annidamento di blocchi o procedure - in generale, i nomi usati nel programma (il tipo e il numero che indica lo scope che contiene la dichiarazione per tale nome) quindi, si può calcolare a compile-time la distanza fra lo scope della chiamata e lo scope della dichiarazione

30 come risolvere riferimenti non locali senza fare ricerche sulla pila? basta risalire la catena statica di un numero di link pari alla distanza dichiarazione-chiamata si può risolvere un riferimento non locale completamente a compile-time? no, non sappiamo staticamente il numero di RdA sulla pila

31 scope statico: la catena statica A: {int y = 0; B: {int x = 0; void pippo(int n) { x = n+1; y = n+2; } C: {int x = 1; pippo(2); write(x); } write(x); } il compilatore sa che per usare y deve risalire di due blocchi; basta memorizzare a compile-time questo numero e usarlo a run-time.

32 scope statico: il display nome non locale, dichiarato in un blocco esterno di k livelli k accessi alla memoria (a run-time) per scorrere la catena statica e trovare il RdA in cui è dichiarato display (riduce a 2 il numero di accessi): – vettore di tanti elementi quanti sono i livelli di annidamento dei blocchi – lelemento k-esimo del display contiene il puntatore al RdA di livello di annidamento k attualmente attivo – se cerco un oggetto non locale dichiarato in un blocco di livello k, accedo alla posizione k del vettore e seguo il puntatore

33

34

35 entrando in (o uscendo da) una procedura di livello k, occorre: – aggiornare il display in posizione k con il valore del puntatore al RdA del chiamato – salvare il vecchio valore (nel RdA del chiamato) due casi: – chiamato allinterno del chiamante: se il chiamante è a livello n, entrambi condividono il display, a cui si aggiunge un nuovo valore in posizione n+1; – chiamato esterno al chiamante: se il chiamante è a livello n e il chiamato a livello m (m

36 scope dinamico per risolvere un riferimento a un nome x si risale la pila fino a trovare il blocco che contiene x; le associazioni nome-oggetto sono memorizzate nel RdA

37

38

39 scope dinamico: lista di associazioni le associazioni nome-oggetto possono essere memorizzate in una A(ssociation)-list, gestita come una pila

40

41 due inconvenienti: – occorre memorizzare i nomi in strutture presenti a tempo di esecuzione (al contrario dello scope statico); è ovvio per la A-list anche per il caso RdA, perche uno stesso nome può essere memorizzato in posti diversi in diversi RdA – inefficienza della ricerca a run-time

42 tabella centrale dellambiente (limita i due inconvenenti): tutti i blocchi del programma fanno riferimento a una sola tabella (CRT), che contiene: – tutti nomi usati nel programma, e per ogni nome – un flag che indica se lassociazione per il nome è attiva – un puntatore alle informazioni sulloggetto – i nomi hanno posizioni fisse in tabella (perché tutti gli identificatori usati nel programma sono noti), quindi laccesso a run-time è costante – se dal blocco A si entra in B, la CRT è modificata per descrivere il nuovo ambiente di B; le associazioni deattivate devono essere salvate (per quando esco da B)

43 – a ogni nome della CRT è associata una pila che contiene nella prima posizione lassociazione valida e (nelle successive) quelle disattivate – oppure si usa una sola pila nascosta per memorizzare tutte le associazioni deattivate per ogni nome

44

45

46

47 usando la CRT (con pila nascosta o no) per conoscere una associazione dellambiente occorre: – accedere alla tabella (diretto) – accedere alla memoria con il puntatore trovato nella tabella – non serve nessuna ricerca a run-time


Scaricare ppt "Memoria gestita staticamente: allocata dal compilatore prima dellesecuzione in una zona fissa della memoria (stabilita dal compilatore) –variabili globali."

Presentazioni simili


Annunci Google