Sie sind auf Seite 1von 42

Procesadores de Lenguaje

Francisco Ortn Soler

Organizacin de la Memoria en
Ti
Tiempo
d
de Ej
Ejecucin
i

Lenguajes y Sistemas
Informticos

Universidad de Oviedo

Contenido

Introduccin
Representacin de los datos
Organizacin de la memoria durante la ejecucin
Memoria esttica
Memoria dinmica de pila
Memoria dinmica heap
Algoritmos de recoleccin de basura
Mecanismos para el paso de parmetros

Francisco Ortn Soler

Introduccin

Anlisis y Sntesis
Hasta ahora nos hemos centrado en la parte de anlisis
esttico (lxico, sintctico y semntico) de un programa
El principal objetivo de la fase de anlisis es validar que
el programa sea vlido, acorde a la descripcin del
lenguaje
El otro gran objetivo de un traductor es la sntesis de un
programa de igual semntica que el procesado, expresado
en otro lenguaje destino
Cdigo Fuente

Analizador Lxico

Anlisis

Analizador Sintctico
Tabla de
Smbolos

Gestin
de Errores

Analizador Semntico

Generador de Cdigo
(Intermedio )
Sntesis

Francisco Ortn Soler

Introduccin

Smbolos y Tipos

Los smbolos y tipos aparecan en el anlisis semntico


En anlisis semntico

Los smbolos se utilizaban validar la existencia de


declaraciones

Los tipos para realizar comprobaciones semnticas


Ahora, en la fase de generacin de cdigo

Los smbolos se utilizaban para saber cmo acceder a


las variables (conociendo su direccin base,
base su
desplazamiento y su tamao)

Los tipos indican el tamao y representacin de cada


variable

En concreto, almacena informacin del ambiente en


tiempo de ejecucin
Tipo

Simbolo
offset
dirBase
tamanio

1
asterisco()
1
de corc hete()
1 comparac ion() a
aritmetica()

Array

Char

Integer

Float

Pointer

Francisco Ortn Soler

Introduccin

Ambiente en Tiempo de Ejecucin

El ambiente en tiempo de ejecucin (runtime


environment) es la estructura de la memoria y
registros de la mquina (virtual) destino en
tiempo de ejecucin
Especifica cmo se debe administrar y utilizar
la memoria de la aplicacin en tiempo de
ejecucin
Aunque este mdulo no aparece como una fase
de la estructura de un traductor, est presente a
lo largo de todo el proceso de sntesis
Francisco Ortn Soler

Introduccin

Tareas de un Compilador
Un compilador deber tener en cuenta el
ambiente en tiempo de ejecucin para

En tiempo esttico (compilacin) asignar y conocer


la posicin que cada variable u objeto tendr en
tiempo de ejecucin
Generar cdigo encargado de mantener
di i
dinmicamente
t ell ambiente
bi t d
de ejecucin
j
i especfico
fi
del lenguaje procesado

La principal dificultad de un compilador es que la


estructura de datos que almacena la informacin
del ambiente en ejecucin (tabla de smbolos o
AST) no existe en tiempo de ejecucin
No tenemos acceso dinmico a la direccin base,
offset o tamao

En el caso de un intrprete esta informacin s


est presente en tiempo de ejecucin
Francisco Ortn Soler

Introduccin

Independencia de la Plataforma
Los traductores separan el proceso dependiente de la
plataforma destino (back-end) de la parte que es
independiente de sta (front-end)
Para ello generan inicialmente cdigo intermedio para una
mquina abstracta
El ambiente en tiempo de ejecucin tambin deber ser
para ser independiente
p
de la p
plataforma y
diseado p
arquitectura destino
Front-end
Analizador Semntico
rbol Sint. Decorado
Tabla de
Smbolos

Generador de Cdigo
Intermedio

Gestin
de Errores

Cdigo Intermedio
Generador de Cdigo
Back-end

Cdigo Destino

Francisco Ortn Soler

Contenido

Introduccin
Representacin de los datos
Organizacin de la memoria durante la ejecucin
Memoria esttica
Memoria dinmica de pila
Memoria dinmica heap
Algoritmos de recoleccin de basura
Mecanismos para el paso de parmetros

Francisco Ortn Soler

Representacin de los Datos

Tipos

Hemos comentado cmo los tipos y los


smbolos poseen responsabilidades de
generacin de cdigo
Comenzaremos con los tipos
Para definir el entorno en tiempo de ejecucin, se
deber definir, para cada tipo

Su tamao
Su representacin en memoria

Francisco Ortn Soler

Representacin de los Datos

Tipos Simples: Enteros


Un tipo simple es un tipo atmico cuya estructura interna no
puede ser modificada por el programador
En su representacin, cuando se utiliza ms de un byte, hay que
tener en cuenta su alineacin:
Little-endian (80x86): Primero bytes menos significativos
Big-endian (PPC) : Primero bytes ms significativos
En
E llas plataformas
l t f
fsicas,
f i
se suelen
l
trabajar
t b j con tamaos
t

mltiplo de la palabra (2, 4 u 8 bytes)


Respecto a los enteros, su tamao
Suelen venir representados por palabras de ordenador
En algunos lenguajes, como C, dependen de la implementacin
En otros, como Java son fijos (32 bits, incluso en la
implementacin de 64 bits)
z Normalmente utilizan plataformas virtuales o son
interpretados
Respecto a su representacin (formato): Signo-Magnitud,
complemento a 1, complemento a 2 (Java y 80x86)

Francisco Ortn Soler

Representacin de los Datos

Booleanos, Caracteres y Reales


Booleanos
Su tamao mnimo es un bit
z Por cuestin de alineacin y/o rendimiento, suelen
utilizar ms tamao
La p
plataforma Java utiliza un byte
y
Caracteres
Se suelen utilizar tablas de caracteres: ASCII reducido (7
bits + 1 de paridad), ASCII extendido de 8 bits (OEM y
ANSI), EBCDIC de 8 bits (IBM), Unicode (de 16 bits para
Java)
Reales
Formato: Hay varios formatos. El ms utilizado es el
IEEE 754 de 32 (float) y 64 bits (double) formato de
coma flotante (signo, exponente y mantisa)
Francisco Ortn Soler

Representacin de los Datos

Implementacin

a implementacin
p e e tac de un
u compilador
co p ado es
En la
necesario conocer el tamao en bytes de
cualquier tipo
Dnde asignaramos esta responsabilidad en
nuestro compilador?

Francisco Ortn Soler

Representacin de los Datos

Implementacin
Tipo
numeroBytes():int

Caracter

Entero

Real

numeroBytes():int

numeroBytes():int

numeroBytes():int

Francisco Ortn Soler

Representacin de los Datos

Tipos Compuestos: Punteros

Un tipo compuesto se crea a partir de un constructor de


tipo (array, pointer, record...) aplicado a otras expresiones
d ti
de
tipo
Punteros
Su tamao suele ser la palabra de un ordenador,
independientemente del tipo apuntado
A bajo nivel un puntero se representa como un entero
No posee valores negativos

Francisco Ortn Soler

Representacin de los Datos

Tipos Compuestos: Arrays


Puesto que es una coleccin de elementos de un mismo
tipo, el nmero de bytes que requiere ser
El producto de su tamao por el nmero de bytes del
tipo de sus elementos
Ejercicio: Cmo se implementara en el sistema de tipos?
Y los arrays multidimensionales?
de

Tipo

numeroBytes():int

Array
tamao:int

Puntero

numeroBytes():int

numeroBytes():int
Francisco Ortn Soler

Representacin de los Datos

Tipos Compuestos: Registros


Un registro est formado por un conjunto de
campos, teniendo cada uno de ellos un nombre y
un tipo
El tamao de un registro ser la suma de los
tamaos de los tipos de sus campos
La posicin de memoria relativa (offset) de cada
uno de los campos ser el sumatorio de los
tamaos de los tipos de los campos anteriores
z La ordenacin de los campos es
mayoritariamente dependiente de la
implementacin

Francisco Ortn Soler

Representacin de los Datos

Tipos Compuestos: Registros


Ejercicio
Cmo se implementa el clculo del tamao?
Implemntese
Dnde se ubicara el offset?
Cmo se calculara? Implemntese

Tipo

campos
*

numeroBytes():int

Campo
nombre:string

Registro
numeroBytes():int

Francisco Ortn Soler

Representacin de los Datos

Tipos Compuestos: Objetos

En lo referente al acceso a los atributos, no existe


diferencia de acceso respecto a los registros

Sin embargo, la herencia incluye un factor


adicional a tener en cuenta
Una instancia de una clase posee una estructura
compuesta por la concatenicacin de su clase y sus
clases base
Para generar cdigo eficiente, todos los offsets de
un atributo debern conocerse estticamente (en
tiempo de compilacin): a1=0, b1=4, b2=8, d1=12,
c1=4
A a=new B();
a.a1; // el offset de a1 debera ser siempre el mismo

A
a1 : int

Offsets:

C
c1 : int
B
b1 : int
b2 : int

D
d1 : int

0
4
8
12

:A

a1

:B

:C

:D

a1
b1
b2

a1
c1

a1
b1
b2
d1

Francisco Ortn Soler

Representacin de los Datos

Tipos Compuestos: Objetos


Cuando se emplea herencia mltiple, el
mantenimiento de los mismos offsets genera un
desaprovechamiento de memoria
A
a1 : int

B
b1 : int
b2 : int

:A
0

C
c1 : int

:B

a1

4
Offsets
Estticos: 8

:D

a1

a
b1
b2
c1
d1

b1
b2

12
16

:C

c1

d1 : int

:A

:B

:C

:D

a1

b1
b2

a1
c1

a
b1
b2
c1
d1

Si no fuese as, qu cdigo se


generara para this->c1 dentro
de C?
En C no se sabe si this es una
instancia de C o de D?Francisco Ortn Soler

Representacin de los Datos

Tipos Compuestos: Objetos


El desaprovechamiento se puede evitar (con un menor
rendimiento) incluyendo una indireccin
Todo objeto posee un puntero a una descripcin de la
clase, donde se le indica el offset real de cada uno de
sus atributos
:A
:B
:C
:D
Objetos
A
a1 : int

B
b1 : int
b2 : int

0
4
8
12
14
16

C
c1 : int

Descriptores
de Clases
(offsets estticos
fijos):

D
d1 : int

a1
b1
b2
c1
d1

a1

b1
b2

a1
c1

a
b1
b2
c1
d1

4
8
12
16
20

4
4
8

Francisco Ortn Soler

Representacin de los Datos

Tipos Compuestos: Objetos

En OO se ofrece enlace dinmico: el paso de un mensaje


provoca la invocacin del mtodo real del objeto
El mtodo a invocar est en funcin del tipo del objeto (no de
la clase)
La solucin es implementar una tabla de funciones virtuales
(vtable)

Esta informacin ir ubicada en el objeto

Cada objeto tendr un puntero a una tabla con tantas


entradas como mtodos virtuales (vtable)

Persona
dni : int
getDni() : int
toString() : String

...
Persona p1=new Persona(10000000),
p2=new Empleado(9999999,"Informtica");
System.out.println( p1.toString() );
System.out.println( p2.toString() );
...
Persona::toString

Objeto p1
vtable
dni

Empleado
departamento : String
toString() : String

toString
equals
hashcode

Object::equals
Object::hascode

vtable
dni
departamento
Objeto p2

toString
equals
hashcode

Empleado::toString
Francisco Ortn Soler

Contenido

Introduccin
Representacin de los datos
Organizacin de la memoria durante la
ejecucin
Memoria esttica
Memoria dinmica de pila
Memoria dinmica heap
Algoritmos de recoleccin de basura
Mecanismos para el paso de parmetros
Francisco Ortn Soler

Organizacin de la Memoria durante la Ejecucin

Memoria de un Proceso
Un programa, una vez compilado, ser ejecutado
por el sistema operativo creando un proceso
Un proceso tendr asignada una zona de
memoria, pudiendo crecer sta en tiempo de
j
ejecucin
La memoria de un procesador est divida en

Un conjunto de registros
La memoria de acceso directo (RAM), ms lenta
pero con mayor capacidad

El modo en el que se empleen dinmicamente la


memoria y registros para almacenar las variables
y objetos de un programa viene definido por su
ambiente en tiempo de ejecucin
Francisco Ortn Soler

Organizacin de la Memoria durante la Ejecucin

Memoria Esttica y Dinmica

La memoria de un proceso puede clasificarse del


g
modo
siguiente

Memoria esttica: Aqulla cuyo tamao


permanece constante a lo largo de la ejecucin del
proceso
Memoria dinmica: Aquella memoria que posee
un tamao que vara a lo largo de la ejecucin del
proceso

Francisco Ortn Soler

Organizacin de la Memoria durante la Ejecucin

Organizacin de la Memoria
El contenido de la memoria esttica est dividido en
instrucciones y datos
La memoria dinmica est organizada de dos formas
posibles
1.
Memoria de pila o stack: Se reserva y libera
dinmicamente siguiendo una poltica LIFO (Last Input,
p )
First Output)
2.
Memoria de montculo o heap: Se libera y reserva
siguiendo distintas estrategias, transparentes al
programador
Memoria Esttica
(tamao fijo)

rea de Cdigo
rea de datos Estticos
Heap

Memoria Dinmica
(tamao variable)
Pila
Francisco Ortn Soler

Contenido

Introduccin
Representacin de los datos
Organizacin de la memoria durante la ejecucin
Memoria esttica
Memoria dinmica de pila
Memoria dinmica heap
Algoritmos de recoleccin de basura
Mecanismos para el paso de parmetros

Francisco Ortn Soler

Memoria Esttica

Memoria Esttica
La memoria esttica es aqulla cuyo tamao
permanece constante a lo largo de la ejecucin
del proceso
El contenido de la memoria esttica est dividido
en instrucciones y datos

Este contenido acostumbra a estar


conceptualmente separado

El tamao del conjunto de instrucciones que


conforman un programa no vara en tiempo de
ejecucin, por lo que se incluye en la memoria
esttica del proceso
Francisco Ortn Soler

Memoria Esttica

Instrucciones en Memoria Esttica


El contenido de las instrucciones en memoria est dividido en
subrutinas (y etiquetas)
Puesto que su tamao no vara, es posible conocer
estticamente la direccin (relativa al proceso) dinmica de
cada subrutina
En cdigo intermedio, estas direcciones acostumbran a ser
los identificadores de las subrutinas o etiquetas
q
En la ltima fase de generacin de cdigo, los
identificadores son traducidos a su direccin numrica
reubicable
Direccin Proc. 1
Cdigo Procedimiento 1
Direccin Proc. 2
Cdigo Procedimiento 2
Direccin Proc. 3

Cdigo Procedimiento n
Francisco Ortn Soler

Memoria Esttica

Datos en Memoria Esttica


El tamao de la informacin (datos) esttica de un
programa no vara a lo largo de la ejecucin del proceso
Esta caracterstica hace que, al igual que los procedimientos, el
compilador conozca su direccin dinmica en tiempo de
compilacin
El proceso de acceso es similar al de las subrutinas:
Su identificador en cdigo intermedio
Su
S direccin
di
i numrica
i reubicable
bi bl en cdigo
di
destino
d ti
Los datos que un compilador suele incluir en la memoria
esttica son
Las variables globales
Las variables estticas y de clase (static en C++)
Variables constantes (const o final)
Determinadas constantes (literales):
z Los nmeros enteros y caracteres se emplean
directamente en cdigo
z Sin embargo, otras constantes como las cadenas de
caracteres y (a veces) nmeros reales suelen incluirse en
la memoria esttica y hacer referencia a su direccin
Francisco Ortn Soler

Memoria Esttica

Ejercicio: MAPL Esttico


MAPL tiene un direccionamiento separado para cdigo
y datos
Su palabra es de 2 bytes (16 bits)
En el segmento de cdigo, cada instruccin ocupa una
direccin
La memoria del segmento de datos (configurable por
lnea de comando) es de 512 bytes a 16 KB (1KB por
omisin)
Ofrece 3 registros de 16 bits
IP (segmento de cdigo): Direccin de la
instruccin actual
SP (segmento de datos): Direccin del tope de la
pila
BP (segmento de datos): Direccin del registro de
activacin (o marco de pila) de la funcin actual
Francisco Ortn Soler

10

Memoria Esttica

Ejercicio: MAPL Esttico (II)


Los datos estticos, de direcciones crecientes, empiezan en 0
Los datos dinmicos de pila, de direcciones decrecientes,
empiezan al final del segmento de datos
SP almacena la direccin tope de la pila
No ofrece primitivas de gestin heap

rea
d d
de
datos
t
Estticos
E tti
Libre

SP
BP

Pila

IP

Cdigo

Segmento
de Datos

...

Segmento de
Cdigo
Francisco Ortn Soler

Memoria Esttica

Ejercicio: MAPL Esttico (III)

En MAPL

La palabra es de 16 bits
Los caracteres ocupan un byte
Los enteros ocupan 2 bytes
Los reales ocupan 4 bytes

Francisco Ortn Soler

Memoria Esttica

Ejercicio: MAPL Esttico (IV)


Dada la siguiente seccin de una gramtica abstracta
(declaracin de variables globales)
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)

Programa:
Si b l
Simbolo:
TipoEntero:
TipoCaracter:
TipoReal:
TipoPuntero:
TipoArray:
TipoRegistro:
Campo:

programa -> declaracion* sentencia*


d l
declaracion
i
->
> ti
tipo ID
tipo -> INT
tipo -> CHAR
tipo -> DOUBLE
tipo -> tipo
tipo -> tipo CTE_ENTERA
tipo -> campo*
campo -> ID tipo
Francisco Ortn Soler

11

Memoria Esttica

Ejercicio: MAPL Esttico (V)


Suponiendo que se ha realizado el anlisis semntico:
La fase de identificacin
La fase de inferencia (y comprobacin) de tipos
Se pide
1.
Ampliar el diseo del sistema de tipos (UML) para
p
y
) de todos los
poder calcular los tamaos ((en bytes)
tipos
2.
Aadir reglas semnticas a la Gramtica Atribuida
completa para calcular los offsets de cada campo
3.
Aadir reglas semnticas a la Gramtica Atribuida
completa para calcular los offsets de los smbolos
(declaraciones) de las variables globales
4.
Implemntese los pasos 2 y 3 como un nuevo Visitor
del mdulo de generacin de cdigo, llamado
VisitorOffset
Francisco Ortn Soler

Memoria Esttica

Ambientes Totalmente Estticos


Algunos lenguajes de programacin poseen un ambiente de
ejecucin totalmente esttico (Fortran77, SDCC)
A lo largo de la ejecucin del proceso, el tamao de su
memoria permanece constante
En este tipo de ambientes, todas las variables (locales y
globales) son reservadas antes de ejecutarse el programa
Cada funcin tiene un registro de activacin nico
Por tanto, no es posible realizar invocaciones recursivas
Ni realizar programas con un nmero dinmico de hilos
rea de Cdigo

rea de Datos

Procedimiento Principal
Procedimiento 1

Procedimiento n
Datos Globales
RA Procedimiento 1

RA Procedimiento n

Francisco Ortn Soler

Memoria Esttica

Ejemplo de Ejecucin Fortran 77


En Fortran 77 todos los parmetros son pasados
por referencia
Por tanto, deber preverse en los registros
de activacin el nmero de valores
integer maximo
temporales necesarios en cada invocacin
real tabla(10),temp
program Test
common maximo

maximo=10
read *,tabla(1),tabla(2)
call proc(tabla,2,temp)
print *,temp
end
subrutine proc(a,tam,ret)
common maximo
integer maximo,tam
real a(tam),ret,aux
integer k
do 10 k=1,tam
Punto de
aux=aux+a(k)
Ejecucin
ret=aux/2
return
end

maximo
tabla(1)
( )
tabla(2)

tabla(10)
temp
2
a
tam
ret
direccion de retorno
aux
k
Francisco Ortn Soler

12

Contenido

Introduccin
Representacin de los datos
Organizacin de la memoria durante la ejecucin
Memoria esttica
Memoria dinmica de pila
Memoria dinmica heap
Algoritmos de recoleccin de basura
Mecanismos para el paso de parmetros

Francisco Ortn Soler

Memoria Dinmica de Pila

Memoria Dinmica
La memoria dinmica est organizada de dos
formas posibles
1.

2.

Memoria de pila o stack: Se reserva y libera


dinmicamente siguiendo una poltica LIFO (Last
Input, First Output)
Memoria de montculo o heap: Se libera y reserva
siguiendo distintas estrategias, transparentes al
programador
En funcin del lenguaje de programacin, la
asignacin (reserva) y liberacin de memoria
pueden ser explcitas y/o implcitas

Pueden darse ambos tipos de memorias, slo


una de ellas o ninguna
Francisco Ortn Soler

Memoria Dinmica de Pila

Memoria Dinmica

El tamao de la memoria de pila vara nicamente


por uno de sus extremos, empleando una poltica
LIFO

Tradicionalmente crece respecto a posiciones


negativas de la memoria (hacia abajo)
El montculo (heap) se asigna en funcin de los
bl
bloques
di
disponibles
ibl
En determinadas organizaciones, la pila y la heap se
encuentran en secciones separadas de memoria
Memoria Esttica
(tamao fijo)

rea de Cdigo
rea de datos Estticos
Heap

Memoria Dinmica
(tamao variable)
Pila
Francisco Ortn Soler

13

Memoria Dinmica de Pila

Memoria Dinmica de Pila


En la memoria de pila habitualmente se ubican
las variables locales y los argumentos
(parmetros) de una funcin, procedimiento o
mtodo
En el lenguaje fuente procesado, la reserva y
liberacin de esta memoria es transparente al
programador (implcita)

Sin embargo, un compilador deber generar el


cdigo de estas dos operaciones (reserva y
liberacin) de forma explcita en bajo nivel
El proceso de reserva (asignacin, assignment) de
la memoria se realiza previamente a la invocacin
de la funcin y al comienzo de sta (secuencia de
llamada)
El proceso de liberacin se realizar al finalizar la
funcin y, en ocasiones, al retornar de sta
Francisco Ortn Soler
(secuencia de retorno)

Memoria Dinmica de Pila

Marcos de Pila (Registros Activacin)


Un marco de pila (stack frame) o registro de activacin es la
unidad de reserva y liberacin de memoria dinmica de pila
Ser reservada al comienzo de la funcin y liberada tras su
finalizacin
Un marco de pila acostumbra a tener los siguientes elementos:
Argumentos (parmetros reales): Es necesario albergar el
resultado
l d d
de evaluar
l
cada
d uno de
d los
l argumentos, en la
l
ejecucin de la funcin
Informacin de administracin: Se almacena en la pila la
informacin necesaria para recuperar su estado previo
Variables locales: El ciclo de vida de estas variables es el
mismo que el de la ejecucin de la funcin; se crean en la
invocacin y se destruyen ante su finalizacin
En ocasiones los valores temporales requeridos por el cdigo
de la funcin son considerados parte del registro de activacin
El valor devuelto puede retornarse de diversas formas: en un
registro, en el tope de la pila o antes de los argumentos
Francisco Ortn Soler

Memoria Dinmica de Pila

Estructura de un Registro Activacin


La estructura y detalles de cada uno de los elementos
de un marco de pila dependen de
Las caractersticas del lenguaje a procesar
La plataforma destino
El diseo e implementacin del compilador
Posteriormente analizaremos
l
un conjunto d
de casos
prcticos
Espacio para valores temporales del
procedimiento
Contenido dinmico
de un marco de pila

Espacio para las variables locales


Espacio para la informacin de
administracin
Espacio para los argumentos
(parmetros reales)

Francisco Ortn Soler

14

Memoria Dinmica de Pila

Recursividad
Recordemos que los mbitos de ejecucin totalmente
estticos
no permiten recursividad
Reservan el mismo tamao de memoria (el mximo)
independientemente del flujo de ejecucin de la
aplicacin
La recursividad implica tantos registros de activacin como
invocaciones se hayan realizado en tiempo de ejecucin
El modo ms comn de ofrecer este mecanismo es
mediante un mbito de ejecucin basado en pila
Cada vez que se invoque a una funcin, se crea su
registro de activacin en el tope de la pila
Una vez finalizada la invocacin, se desapila su registro
de activacin
La pila de registros de activacin recibe el nombre de pila
de ejecucin
Francisco Ortn Soler

Memoria Dinmica de Pila

Ambientes Dinmicos de Pila


La informacin y administracin de los registros
de activacin en un lenguaje con mbito de pila,
dependen fuertemente de las caractersticas del
lenguaje procesado
Veremos los siguientes casos

Ambientes
A
bi t d
de ejecucin
j
i para lenguajes
l
j
sin
i
funciones locales: Aquellos lenguajes que no
permiten crear funciones locales a otras funciones
No es posible anidar funciones (C)
Ambientes de ejecucin para lenguajes con
funciones locales: Se permite declarar funciones
locales a otras funciones (Pascal)
En este caso, las reglas de mbito y ocultacin de
variables es ms compleja y deber ser tenida en
cuenta
Francisco Ortn Soler

Memoria Dinmica de Pila

Amb. de Pila sin Funciones Locales


En este tipo de lenguajes (C) las funciones son
siempre de mbito global
En el mbito de una funcin, nicamente se podr
acceder a
Las variables globales del programa: Al ser
estticas, su direccin es conocida en tiempo de
compilacin
Las variables locales de la funcin (y sus
argumentos): Variables dinmicas cuya direccin
efectiva slo puede ser conocida en tiempo de
ejecucin
Francisco Ortn Soler

15

Memoria Dinmica de Pila

Variables Locales y Argumentos


Por tanto, se deber generar cdigo que permita evaluar
las direcciones de las variables locales en tiempo de
ejecucin
Este proceso es llevado a cabo mediante una indireccin:
Se genera cdigo que mantenga dinmicamente la
direccin del registro de activacin en un registro
Este registro es comnmente denominado marco de pila, fp
(frame pointer) base pointer (bp) en i80x86
Las direcciones poseern desplazamientos estticos
(conocidos por el compilador) respecto este registro
void f(int argumento) {
int local;

}
Punto ejecucin

bp-4
bp
(fp)
bp+n

local

Informacin
Administracin

argumento

4
Francisco Ortn Soler

Memoria Dinmica de Pila

Modificacin del FP
Qu sucede en la siguiente ejecucin?

int g(int a) {
int n=1;
return a+n;
}
void f(int argumento) {
int local;
g(3);
local = argumento;
}

bp-4
bp
(fp)

Punto ejecucin

bp+n

local

Informacin
Administracin

argumento

Francisco Ortn Soler

Memoria Dinmica de Pila

Modificacin del FP
El valor de FP (BP) se actualiza (y se pierde)
bp-4
bp
int g(int a) {
(fp)
int n=1;
return a+n;
Punto ejecucin
}
bp+n
void f(int argumento) {
int local;
g(3);
local = argumento;
}

Informacin
Administracin

3
local

4
4

Informacin
Administracin

argumento

Cuando se retorne de g, cmo se podr acceder


a local y argumento?
Francisco Ortn Soler

16

Memoria Dinmica de Pila

Informacin de Administracin
Por tanto, ser necesario almacenar el registro fp antes
de la invocacin a una funcin
As, una vez retornado de dicha invocacin, podr
recuperarse el valor antiguo de fp pudiendo acceder a
las variables locales del registro de activacin actual

int g(int a) {
int n=1;
return a+n;
}
void f(int argumento) {
int local;
g(3);
local = argumento;
}

bp-4
bp
(fp)

n
bp (anterior)
Ms Info Admon.

bp+n

4
n

3
local
bp (anterior)

4
4

Ms Info Admon.

argumento

4
Francisco Ortn Soler

Memoria Dinmica de Pila

Informacin de Administracin
Cuando finaliza una funcin, cmo se retorna (salta) a la
invocacin a sta?
Tambin es necesario almacenar el registro contador
de instrucciones (IP) en el registro de activacin

int g(int a) {
int n=1;
return a+n;
}
void f(int argumento) {
int local;
g(3);
local = argumento;
}

bp(fp)
ip

n
bp (anterior)
ip (anterior)
Ms Info Admon.
3
local
bp (anterior)
ip (anterior)
Ms Info Admon.
argumento

Francisco Ortn Soler

Memoria Dinmica de Pila

Informacin de Administracin
Por tanto, en este tipo de lenguajes, la informacin de
administracin de un registro de activacin deber
almacenar
El valor anterior del fp (bp) antes de la creacin del
marco actual) tambin llamado vnculo de control
La direccin de retorno de la invocacin actual
En funcin de la implementacin, podra almacenarse otra
informacin como el valor de otros registros o el valor de
retorno
Espacio para las variables locales
FP (BP)
Direccin de Retorno
Argumentos (parmetros reales)
Francisco Ortn Soler

17

Memoria Dinmica de Pila

Caso Prctico
Analizaremos el siguiente caso void f(int a) {
int b;
prctico
b=a*2;
Lenguaje C
Direcciones bajas
}
Compilador GNU para Win32
sobre i386
Sobre esta plataforma, el registro EBP-4
b
d marco de
de
d pila
il se llama
ll
EBP
EBP
Sobre esta plataforma, el registro
EBP
de activacin est compuesto por
Dir. Ret.
Argumentos (a es EBP+8) de
EBP+8
derecha a izquierda
a
Direccin de retorno
...
EBP anterior
Variables locales (b es EBP-4)
El valor de retorno se devuelve
en EAX (en st0 si es real)

4
4
4
4

Direcciones altas
Francisco Ortn Soler

Memoria Dinmica de Pila

Ejercicio: MAPL Dinmico de Pila


En MAPL la pila decrece, comenzando por la
ltima direccin del segmento de datos (1KB por
omisin)

SP (2 bytes) indica el tope de la pila


Ell registro d
de marco d
de pila
l se ll
llama BP (2
( b
bytes))

rea de datos Estticos


Libre

SP
Pila
Francisco Ortn Soler

Memoria Dinmica de Pila

Ejercicio: MAPL Dinmico de Pila (II)

El registro de activacin consta de (por orden de direcciones decreciente)


1.
Argumentos (de izquierda a derecha)
2.
Direccin de retorno
3.
BP anterior
4.
Variables Locales

Apuntando BP a la direccin del registro de activacin donde est


guardado el BP anterior

(4)
(3)
(2)
(1)
Francisco Ortn Soler

18

Memoria Dinmica de Pila

Ejercicio: MAPL Dinmico de Pila (III)


Dada la siguiente gramtica abstracta

(1) Funcion:
funcion tipo ID declaracion* sentencia*
(2) Simbolo:
declaracion tipo ID

(3) TipoFuncion: tipo1 tipo3 tipo2*

(4) Identificador: expresion ID


Se pide, suponiendo que se ha realizado el anlisis semntico
(fases identificacin e inferencia)
1.
Ampliarla para definir un GA completa que calcule los
offsets de todos los smbolos asociados a las variables
locales y parmetros
2.
Implementarla como parte del VisitorOffset
Francisco Ortn Soler

Memoria Dinmica de Pila

Mantenimiento Ambiente Ejecucin


Los criterios de acceso a los registros de
activacin debern mantenerse en tiempo de
ejecucin

Un compilador deber generar cdigo para que la


informacin de los registros de activacin sea
coherente en todo momento

Para ello, deber definir claramente:

La secuencia de llamada: Secuencia de


operaciones que deben ocurrir en la invocacin de
un procedimiento o funcin
La secuencia de retorno: Secuencia de
operaciones realizadas en el regreso de una funcin

El generador de cdigo deber generar las


operaciones de la secuencia de llamada y retorno
para que se cumpla el ambiente de ejecucin
Francisco Ortn Soler

Memoria Dinmica de Pila

Secuencia de Llamada
Direcciones bajas

En los lenguajes basados en pila sin


funciones locales, la secuencia de llamada
se define:
1.
Apilar los argumentos en el registro de
activacin
fp
(bp)
2.
Apilar la direccin de ejecucin actual
(direccin de retorno)
3.
Realizar el salto a la funcin invocada
4.
Guardar en la pila el valor del frame
pointer (fp o bp)
5.
Actualizar el valor de fp al tope de la pila
6.
Reservar en la pila tamao para las
variables locales

variables
locales
fp antiguo
Direccin
de retorno
argumentos
...
Direcciones altas
Francisco Ortn Soler

19

Memoria Dinmica de Pila

Secuencia Llamada (Instrucciones)

Los pasos del la secuencia de llamada se realizan mediante


instrucciones del lenguaje ensamblador de la plataforma:
1.
Apilar los argumentos en el registro de activacin
2.
Apilar la direccin de ejecucin actual (direccin de
retorno)
3.
Realizar el salto a la funcin invocada
4.
Guardar en la pila el valor del frame pointer (fp o bp)
5.
Actualizar el valor de fp al tope de la pila
6.
Reservar en la pila tamao para las variables locales

Paso

g++/win32/i386

MAPL

Evaluacin de expresiones

Evaluacin de expresiones

call

id

call

id

call

id

call

id

push

ebp

call

id

mov

ebp,esp

call

id

sub

esp,bytes_var_loc

enter

bytes_var_loc

Francisco Ortn Soler

Memoria Dinmica de Pila

Secuencia de Retorno

En los lenguajes basados en pila sin


funciones locales, la secuencia de
llamada se define:
1.
Poner el tope de la pila en el valor
de fp o bp (se eliminan las
variables locales)
2
2.
Desapila el fp antiguo,
antiguo
restaurando su valor anterior
3.
Desapila la direccin de ejecucin
previa a la invocacin
4.
Realiza el salto de retorno
5.
Suma el tope de la pila para
liberar los argumentos
6.
(Opcional) Apila el resultado
Veremos cmo generar este cdigo
en el captulo de generacin de
cdigo

Direcciones bajas

variables
locales
fp
(bp)

fp antiguo
Direccin
de retorno
argumentos
...
Direcciones altas
Francisco Ortn Soler

Memoria Dinmica de Pila

Secuencia de Retorno (Instrucciones)

Paso

Instrucciones para los siguientes pasos del la secuencia de


retorno:
1.
Poner el tope de la pila en el valor de fp o bp (se eliminan las
variables locales)
2.
Desapila el fp antiguo, restaurando su valor anterior
3.
Desapila la direccin de ejecucin previa a la invocacin
4.
Realiza el salto de retorno
5.
Suma el tope de la pila para liberar los argumentos
6.
(Opcional) Apila el resultado
g++/win32/i386

add

pop

ebp

ret

bytes_var_loc

ret

bytes_var_loc

add

esp, bytes_params

push

eax

MAPL

esp,bytes_var_loc

ret bytes_retorno, bytes_locales, bytes_params

Francisco Ortn Soler

20

Memoria Dinmica de Pila

Amb. de Pila con Funciones Locales


Hemos analizado los ambientes dinmicos de pila para
lenguajes sin funciones locales (anidadas)
Los lenguajes que permiten anidar funciones (Pascal o
Ada), requieren un ambiente de ejecucin ms complejo
En el mbito de una funcin, es posible acceder a
Todas sus variables locales
Las variables globales
Las variables locales de las funciones
jerrquicamente superiores (dentro de las que la
actual haya sido anidada)
En el ltimo caso, las variables
No poseen un direccin conocida en tiempo de
compilacin (no son estticas)
Poseen desplazamientos dependientes de la
ejecucin (en funcin del flujo de ejecucin)
Francisco Ortn Soler

Memoria Dinmica de Pila

Ejemplo
program programa;

Dos puntos de ejecucin del procedimiento q:


q
r
p
main

procedure p;
var n: integer;
procedure q;
begin
end; (* q *)

fp

procedure r(m:integer);
begin;
q;
end; (* r *)
begin (* p *)
n:=1;
r(2);
q;
end;(* p *)
begin (* main *)
p;
end.

En ambos casos, el
acceso a la variable
n sera distinto

q
p
main

fp ant.
dir. ret.
di
t
fp ant.
dir. ret.
m=2

fp

fp ant.
dir. ret.

n=1
fp ant.
dir. ret.

n=1
fp ant.
dir. ret.

Reg. Act.
main

Reg. Act.
main
Francisco Ortn Soler

Memoria Dinmica de Pila

Enlaces de Acceso o Esttico


La solucin a este problema es aadir un elemento ms a la
parte de informacin de administracin del registro de
activacin: el enlace o vnculo de acceso
Esta referencia apuntar a la funcin donde se defini
la funcin actual como local (su funcin padre)
Ntese que no apunta al marco de pila anterior (dinmico),
sino al marco de pila que en el que est anidado su cdigo
fuente (marco de pila de su funcin padre)
Por representar precisamente esta informacin esttica,
en ocasiones se denomina vnculo esttico
En la secuencia de llamada, este enlace deber aadirse
a la informacin de administracin (apilarse) antes del valor
antiguo de fp
En la secuencia de retorno deber desapilarse
Francisco Ortn Soler

21

Memoria Dinmica de Pila

Ejemplo
q
r
p
main

program programa;
procedure p;
var n: integer;
procedure q;
begin
end; (* q *)

Ahora la variable n es
accesible desde ambas
invocaciones a q (adems
de serlo desde r)

fp

procedure r(m:integer);
fp antiguo
begin;
enlace acceso
q;
dir. retorno
end; (* r *)

fp

m=2

fp antiguo
enlace acceso
dir. retorno

n=1
fp ant.
enlace acceso
dir. retorno

n=1
fp ant.
enlace acceso
dir. retorno

Registro de
Activacin main

Registro de
Activacin main

begin (* p *)
n:=1;
r(2);
q;
end;(* p *)
begin (* main *)
p;
end.

q
p
main

fp antiguo
enlace acceso
dir. retorno

Francisco Ortn Soler

Memoria Dinmica de Pila

Displays
Como hemos visto, el acceso a las variables de un nivel de
anidamiento menor se hace mediante una indireccin por
cada cambio de mbito, empleando el enlace de acceso
Si los niveles de anidamiento son elevados, esto provoca
una prdida de rendimiento
Por lo g
general,, no suele ser comn un nivel de
anidamiento mayor de dos
En el caso de que se d un nmero elevado de
anidamientos, puede emplearse una estructura de datos
tipo display:
Se aumenta el registro de activacin con tantos enlaces
de acceso como nivel de anidacin tenga la funcin (un
vector)
Conociendo en la tabla de smbolos el nivel de
anidamiento de toda variable local, se emplear el
display para que todos accesos tendrn sola indireccin

Francisco Ortn Soler

Contenido

Introduccin
Representacin de los datos
Organizacin de la memoria durante la ejecucin
Memoria esttica
Memoria dinmica de pila
Memoria dinmica heap
Algoritmos de recoleccin de basura
Mecanismos para el paso de parmetros

Francisco Ortn Soler

22

Memoria Dinmica Heap

Memoria Dinmica Montculo (Heap)


Los ambientes de ejecucin basados en pila ofrecen al
programador una transparencia a la hora de administrar la
memoria en tiempo de ejecucin (siguen una poltica LIFO)
Sin embargo, en ocasiones esa transparencia puede
representar un inconveniente a la hora de programar
char *bloque(int tam) {
char v[tam];
return v;
}
La memoria dinmica heap permite manejar memoria cuyo
tamao slo se conoce en tiempo de ejecucin
Los tamaos de memoria de pila estn especificados de un
modo esttico (en el cdigo fuente)
La asignacin de la memoria con una poltica LIFO limita las
posibilidades de un lenguaje respecto al ciclo de vida de las
variables

Francisco Ortn Soler

Memoria Dinmica Heap

Memoria Heap
La memoria dinmica heap permite

Manejar memoria cuyo tamao slo se conoce en


tiempo de ejecucin
Controlar el ciclo de vida de las variables de un
modo distinto a una poltica LIFO (dependiente del
lenguaje)

Una primera clasificacin de gestin de memoria


heap es respecto al modo en el que se asigna y
libera

Asignacin y/o liberacin explcita: El


programador especifica de un modo explcito
cundo un bloque de memoria ha de ser reservado
y/o liberado
Asignacin y/o liberacin implcita: El sistema
reserva y/o libera los bloques de memoria de un
modo automtico, transparente al programador
Francisco Ortn Soler

Memoria Dinmica Heap

Gestin Explcita e Implcita


Existen lenguajes con asignacin y liberacin
explcita

C, C++ o Pascal
Permiten controlar exactamente el ciclo de vida de
las variables u objetos

En
estn
E lla actualidad,
t lid d llos llenguajes
j
iimperativos
ti
t
optando por asignacin explcita y liberacin
implcita

Java, C# o Python
La liberacin de la memoria es llevada a cabo por
un hilo denominado recolector de basura

Hay lenguajes que ofrecen asignacin y


liberacin de memoria heap implcita

Lisp o ML

Francisco Ortn Soler

23

Memoria Dinmica Heap

Longitud de Bloques
Otra clasificacin de la gestin de bloques heap en
lenguajes de programacin es en funcin de la longitud de
sus bloques
Gestin de bloques de longitud fija
Gestin de bloques de longitud variable
La gestin de bloques de longitud fija consiste en
asignar bloques de un (o varios) tamao(s) fijo(s)
Este tipo de gestin de memoria heap slo es posible en un
tipo determinado de lenguajes
Lisp permite manejar estructuras dinmicas de lista
cuyos bloques son todos del mismo tipo y tamao (o un
tomo o una lista)
Supone un mecanismo muy sencillo de implementar
No produce el problema de la fragmentacin de la memoria
(que veremos a continuacin)
Francisco Ortn Soler

Memoria Dinmica Heap

Bloques de Tamao Variable

La mayora de los lenguajes de programacin ofrece la


asignacin y liberacin de bloques heap de tamao
variable

La operacin de asignacin recibir (invocada


explcita o implcitamente) un parmetro tamao y
devolver la direccin del bloque reservado

La operacin de liberacin recibir una direccin de


memoria de un bloque previamente asignado
Un mecanismo muy empleado para coleccionar los boques
es mediante una lista circular
Cada bloque posee
1.
Un puntero al siguiente bloque
2.
El nmero de bytes asignados
3.
El nmero de bytes libres
4.
La memoria del bloque (asignada y/o libre)
Los tres primeros elementos se denominan la cabecera del
bloque

Francisco Ortn Soler

Memoria Dinmica Heap

Estructura de un Bloque

Una implementacin sencilla:

typedef struct bloque {


struct bloque *siguiente;
unsigned asignado, libre;
} Bloque;

Inicialmente se parte de un nico bloque totalmente libre cuyo


siguiente es l mismo
q
bloque
siguiente
asignado=0
char memoria[TAM]; // Tomada del SO
libre=n
Bloque *bloque=(Bloque*)memoria;
bloque->siguiente=bloque;
bloque->asignado=0;
bloque->libre = TAM*sizeof(char)sizeof(Bloque);

libre

Francisco Ortn Soler

24

Memoria Dinmica Heap

Asignacin de un Bloque

La primera vez que se asigna un bloque de tamao i, se toma


del bloque inicial
En consecutivas peticiones, se crean nuevos bloques con la parte
libre del ltimo

Se actualiza el puntero del ltimo bloque


siguiente
asignado=0
libre=n

siguiente
asignado=i
asignado
i
libre=0

siguiente
asignado=i
libre=n-i
asignado

libre

n
n-i

libre

asignado

siguiente
asignado=j
libre=m
asignado
libre

i
m

Francisco Ortn Soler

Memoria Dinmica Heap

Fragmentacin de Memoria

El proceso descrito anteriormente se sigue cada vez que se


solicite asignar un nuevo bloque de memoria
Cuando se estime oportuno, se invocar (explcita o
implcitamente) a la operacin de liberacin

En funcin de qu bloques sean liberados, podr darse


una fragmentacin de la memoria
asignado

asignado

libre

asignado

asignado

asignado

asignado

libre

libre

asignado

asignado

asignado

libre

libre

libre
Francisco Ortn Soler

Memoria Dinmica Heap

Fragmentacin Externa
Este proceso de
descomposicin de la memoria
total disponible se denomina
fragmentacin externa

Se denomina externa porque


los fragmentos estn fuera de
cada
d bl
bloque (pertenecen
(
t
a la
l
memoria total)

Su principal problema es que


puede darse el caso que

Le pidamos un bloque de
tamao m
Posea ms de m bytes libres
Sin embargo no puede asignar
un bloque de dicho tamao
(por la fragmentacin)

libre
asignado
libre
asignado
libre

Francisco Ortn Soler

25

Memoria Dinmica Heap

Fragmentacin Interna

Si a la hora de asignar un bloque se opta por emplear un


bloque libre de tamao mayor al solicitado

Se volver a crear un nuevo bloque libre de tamao igual


a la diferencia de los tamaos (tamao bloque original
tamao solicitado)
Si la parte libre de este bloque no se puede volver a usar,
esta fragmentacin se denomina fragmentacin interna

Puesto que el fragmento era parte de un bloque


asignado

asignado

libre

asignado
libre

asignado

asignado

libre

libre
Francisco Ortn Soler

Memoria Dinmica Heap

Asignacin de Memoria
El grado de fragmentacin de la memoria est fuertemente
ligado al modo en el que sta se asigna
Veremos una serie de tcnicas empleadas para asignar la
memoria
La idoneidad de cada una de ellas es dependiente de las
caractersticas del lenguaje
g
p
p ((first-fit))
Asignacin
primero el q
que cumpla
Asigna el primer bloque que sea mayor o igual al pedido
(partiendo del puntero de la lista)
Es un mtodo con un alto rendimiento
Produce una elevada fragmentacin interna
Asignacin primero que cumpla circular (next-fit)
Modificacin del primero que cumpla
Contina las bsqueda en el punto en el que finaliz la
anterior asignacin
Eficiente y distribuye los bloques pequeos
(fragmentacin interna) a lo largo de toda la lista
(facilita la fusin de bloques)
Francisco Ortn Soler

Memoria Dinmica Heap

Asignacin de Memoria
El resto de algoritmos se basan en la ordenacin de los
bloques en funcin de distintos criterios
Su rendimiento es menor que los dos anteriores
Asignacin mejor que cumpla u ptimo (best-fit)
Ordenacin de bloques por tamao ascendentemente
(menor rendimiento)
Se toma el bloque que realice un menor
desaprovechamiento de la memoria
Reduce la fragmentacin interna
Asignacin peor que cumpla (worst-fit)
Ordenacin de bloques por tamao descendentemente
No genera una elevada fragmentacin interna
Posee un bajo rendimiento
Etiquetas lmite
Ordenacin de bloques por su direccin de memoria
Reduce la fragmentacin externa, puesto que los asigna
de un modo ordenado (permitiendo fusionar bloques)
Francisco Ortn Soler

26

Memoria Dinmica Heap

Mtodo del Embrin


Hemos visto la gestin de memoria de bloques de tamao
fijo o variable
La tcnica del embrin restringe el tamao de los bloques
a un conjunto determinado de tamaos
Estos tamaos pueden combinarse y dividirse para
formar nuevos tamaos
Es, por tanto, un mtodo intermedio entre la gestin de
bloques de tamao fijo y variable
Todos los bloques de un mismo tamao se encadenan en un
mismo contenedor
Se aumenta as la velocidad en la bsqueda
Si se requiere un bloque de tamao m, se emplean el
tamao nm ms cercano a m
De este modo a) se reduce la fragmentacin interna
b) con un elevado rendimiento
Francisco Ortn Soler

Memoria Dinmica Heap

Mtodo del Embrin


Si se requiere una asignacin cuyo tamao superior ms
cercano no posee un bloque disponible
Un bloque mayor se divide en 2 o ms bloques
(embriones) para obtener el tamao deseado
Si no existen tamaos superiores a dividir, embriones
contiguos se combinan para obtener un nuevo bloque
del tamao deseado
Los posibles tamaos de esta tcnica se especifican
mediante patrones numricos como por ejemplo
La serie de Fibonacci
Potencias de 2 (embrin binario)
Este es ms complejo que los anteriores pero
Ofrece un mayor rendimiento que los que ordenan los
bloques
Controla la fragmentacin interna
Francisco Ortn Soler

Memoria Dinmica Heap

Liberacin de Memoria
Al igual que la asignacin de memoria, la
liberacin puede ser llevada a cabo

Explcitamente, por parte del programador


(Pascal o C)
Implcitamente, por parte del entorno de
ejecucin (Java o Lisp)

A continuacin nos centraremos en la liberacin


explcita

La implcita la veremos en el siguiente punto

Una tcnica empleada en la liberacin de


memoria para evitar la fragmentacin externa es
la fusin de bloques libres

Si se libera un bloque que posee algn otro bloque


libre contiguo, stos se fusionan para crear un
bloque libre de tamao mayor

Francisco Ortn Soler

27

Memoria Dinmica Heap

Fusin de Bloques
En el ejemplo, una liberacin de memoria sin fusin de
bloques generara tres bloques libres
Con fusin de boques se obtendra un nico bloque libre de
mayor tamao (la suma de los tres anteriores)

asignado
i
d

asignado
i
d

asignado

asignado

libre
libre
asignado
libre

Liberacin
del bloque
Francisco Ortn Soler

Memoria Dinmica Heap

Compactacin de Memoria
Otra tcnica utilizada para evitar la fragmentacin externa es la
compactacin de memoria
Todos los bloques usados se mueven a otra zona de memoria
Se consigue eliminar toda la fragmentacin externa
Sin embargo, es necesario
1.
Tener ms memoria heap disponible
2.
Modificar todos los punteros o referencias del programa
3.
Ralentiza la ejecucin del programa
Este mecanismo es ms empleado en la liberacin implcita de
memoria (recoleccin de basura)
libre

asignado

asignado
Compactacin

asignado

libre
libre
asignado
Francisco Ortn Soler

Memoria Dinmica Heap

Implementacin

La mayora de implementaciones ofrecen la


gestin dinmica de memoria como parte del
runtime

C lo ofrece en su librera estndar mediante las


funciones malloc y free
C++ aade estos servicios mediante los
operadores new y delete
Java y C# lo aaden a la plataforma (JVM y CLI)
MAPL no ofrece gestin dinmica heap

Francisco Ortn Soler

28

Contenido

Introduccin
Representacin de los datos
Organizacin de la memoria durante la ejecucin
Memoria esttica
Memoria dinmica de pila
Memoria dinmica heap
Algoritmos de recoleccin de basura
Mecanismos para el paso de parmetros

Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Recoleccin de Basura
Como hemos visto con anterioridad, existen lenguajes
que ofrecen liberacin implcita de memoria
El programador no deber especificar ni cundo ni
qu memoria se ha de liberar
Aquellos bloques de memoria que no sean accesibles
desde ninguna referencia (puntero) del programa
reciben el nombre de basura (garbage)
La memoria basura deber ser liberada por un
lenguaje con liberacin implcita de memoria heap
Este proceso de liberacin implcita de memoria recibe
el nombre de recoleccin de basura (garbage
collection)
La recoleccin de basura es un proceso dinmico
En el caso de un compilador, deber generar cdigo
encargado de realizar esta operacin (D, Go)
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Ejemplo
El siguiente programa Java posee bloques inaccesibles
(basura) en el punto de ejecucin indicado
Heap
class Lista {
int valor;
Lista sig;
public Lista(int v,
Lista s) {
valor=v;
sig=s;
}
}
Variables

1
Basura

class Arbol {
int valor;
Arbol izq,der;
public Arbol(int v,
Arbol i,Arbol d) {
valor=v;
izq=i;
der=d;
}
}

public class Basura {


static Lista crearLista() {
Lista l=new Lista(1,null),
l2=new Lista(2,l);
l i l2
l.sig=l2;
return l;
}
static Arbol crearArbol() {
return new Arbol(3,
new Arbol(4,null,null),
new Arbol(5,null,null));
}
public static void main(
String[] args) {
crearLista();
Arbol a=crearArbol();
}
}

Punto de Ejecucin
Francisco Ortn Soler

29

Algoritmos de Recoleccin de Basura

Algoritmos de Recoleccin
Veremos las siguientes tcnicas de recoleccin de
basura

Marcar y borrar (mark and sweep)


Contadores de referencias
Recoleccin con copia (copying collection)
Recoleccin
l
generacionall
Recoleccin incremental y concurrente

Se ejecutan cuando se solicita un bloque de


memoria y se detecta que sta es escasa

El grado de escasez es parametrizable en funcin


del algoritmo

Si despus de llamar a la recoleccin de basura


no se obtiene beneficio, se debe pedir ms
memoria al sistema operativo
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Marcar y Borrar (Mark & Sweep)


Los bloques heap en memoria forman un grafo
dirigido
Las variables locales y globales de un programa
de tipo referencia (puntero) constituyen la raz
de dicho grafo
El algoritmo
l
i
d
de marcar y b
borrar realiza
li un
recorrido en profundidad del grafo de bloques

Parte de las races (variables)


Todo nodo del grafo que haya visitado lo marca
como no basura

Una vez finalizado el recorrido del grafo,

Todos aquellos nodos que no hayan sido marcados


son basura
stos son incluidos en la lista de bloques libres
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Ejemplo
Heap
1

Variables

a
...
5

Bloques Libres

Francisco Ortn Soler

30

Algoritmos de Recoleccin de Basura

Caractersticas de Algoritmo
El algoritmo de marcar y borrar

Posee una complejidad proporcional al nmero total


de bloques de la memoria heap
El nico modo que tiene para controlar la
fragentacin externa es mediante la fusin de
bloques
No requiere elevadas cantidades de memoria heap
para ser implementada

Implementaciones

Versiones antiguas de Lisp (diseado por John


McCarthy, creador del Lisp)
Combinado con otros algoritmos, en mltiples
implementaciones como, por ejemplo, Java
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Contador de Referencias
La primera parte del algoritmo marcar y borrar detecta si
los bloques heap son accesibles desde las variables
referencia
El algoritmo de contador de referencias se basa mantener
esta informacin a lo largo de la ejecucin del programa
Todo bloque es aumentado con un campo contador de
referencias
Cada vez que a una referencia se le asigne el valor de un
bloque, su contador ser incrementado
Cada vez que se deje de hacer referencia a un bloque
(se elimina la referencia o pasa a apuntar a otro bloque)
su contador ser decrementado
Si el contador de referencias de un bloque alcanza el valor 0
ste es aadido a la lista de bloques libres
Se decrementan todas los contadores de las referencias
que existan en dicho bloque
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Contador de Referencias
Heap

Este algoritmos es sencillo de


implementar pero posee dos
graves inconvenientes
1.

2.

No elimina los bloques basura que


tengan referencias mutuas
directas o indirectas (cclicas)
El incremento y decremento de los
contadores de referencia es muy
costoso (bajo rendimiento)
Debe generarse cdigo extra cada
vez que se modifica el valor de
una referencia

3
Variables

a
4
1

5
1

Francisco Ortn Soler

31

Algoritmos de Recoleccin de Basura

Contador de Referencias
Hay dos posibles soluciones al problema de las
referencias cclicas

Combinar esta tcnica ocasionalmente con otro


algoritmo de recoleccin como marcar y borrar
Especificar esta caracterstica en el manual de
referencia del lenguaje y hacer responsable al
programador de evitar estos escenarios
z En este caso, no estaramos en un punto
intermedio entre gestin implcita y explcita

En general, los dos inconvenientes de esta


tcnica hacen que apenas se emplee
Existen implementaciones para los lenguajes
Smalltalk, Modula-2, awk y Perl
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Recoleccin con Copia


El principal problema del algoritmo de marcar y borrar es la
fragmentacin externa que genera
Los bloques libres estn entremezclados con los bloques
asignados
El algoritmo de recoleccin con copia (copying collection)
elimina totalmente la fragmentacin externa
Divide la memoria heap en dos secciones de igual tamao
La zona origen (from) posee todos los bloques
asignados (tambin puede tener libres)
La zona destino (to) nicamente constituye una zona
de memoria libre compacta
La operacin de asignacin de memoria se lleva a cabo en
la zona origen, mediante alguno de los algoritmos vistos en
el punto anterior (asignacin de memoria heap)
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Recoleccin con Copia


Cuando se solicite un bloque de memoria y no
haya memoria disponible en la zona origen, se
ejecutar el recolector de basura

Se recorre el grafo partiendo de sus races


Cada vez que se visita un nodo (accesible) se
mueve a la zona destino
Las referencias (puntero) al bloque medido son
actualizadas a la nueva direccin

Una vez finalizado el proceso

El bloque origen posee toda su memoria libre


(basura)
El bloque destino a) tiene toda la memoria
asignada, b) no posee basura y c) no est
fragmentada
En este momento el bloque destino para a ser
origen y el origen destino (cambio de roles)
Francisco Ortn Soler

32

Algoritmos de Recoleccin de Basura

Ejemplo Recoleccin con Copia


Origen

Destino

Destino

3
Variables

Recoleccin
con copia

Origen

Variables

Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Caractersticas del Algoritmo


El algoritmo de recoleccin con copia
Posee una complejidad proporcional al nmero de
bloques accesibles (marcar y borrar era proporcional al
nmero total de bloques)
Evita la fragmentacin, puesto que en todo proceso de
recoleccin se lleva a cabo un proceso de compactacin
Requiere una mayor cantidad de memoria heap que el
marcar y borrar
z Ntese que no es el doble, puesto que al evitar la
fragmentacin hace que se pueda utilizar toda la
memoria libre
En la actualidad, la mayor parte de sus implementaciones
utiliza generaciones (prximo punto)
Existen implementaciones antiguas de Lisp, Scheme y
ML
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Recoleccin Generacional
Esta tcnica se apoya sobre una serie de criterios
empricos detectados en la mayora de los
lenguajes de programacin [Lieberman]
En la mayora de programas se produce que
1.

2.

Los bloques con mayor probabilidad de constituir


basura son los recin creados ((jvenes)
j
)
Aquellos bloques que han superado un mayor
nmero de recogidas de basura tienen una
elevada probabilidad de seguir siendo accesibles

Esto implica que el proceso de recoleccin de


basura debera aplicarse en mayor medida a los
bloques ms jvenes

Jerarquizando los objetos en funcin del tiempo


transcurrido tras su creacin se obtendr un
mayor rendimiento (no es necesario procesar
todos los bloques en todas las recolecciones)
Francisco Ortn Soler

33

Algoritmos de Recoleccin de Basura

Recoleccin Generacional
En esta tcnica la memoria heap es dividida en
generaciones (Gi)

En Go estn los bloques ms jvenes


Todo bloque que Gj posee es mayor a los bloques
Gj-1
Un criterio emprico
p
comnmente empleado
p
es
utilizar tamaos de generaciones exponencialmente
mayores que el tamao de la generacin anterior

Cuando se solicita la asignacin de memoria y no


existen bloques libres en G0,

Se lleva a cabo la recoleccin de basura comenzado


nicamente por aquellas variables raz que apunten
a bloques en G0
El algoritmo de recoleccin slo realiza en G0
Sobre este bloque se aplica uno de los algoritmos
de recoleccin vistos previamente
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Caso Especial
Existe un caso especial a tener en cuenta que provoca que
bloques accesibles sean identificados como basura
Este caso se da cuando hay una referencia de otra
generacin apuntando a un bloque de G0
Por el modo en le que se construyen los objetos y
variables en los lenguajes de programacin, se ha
demostrado empricamente que este caso se produce en
escasas ocasiones [Lieberman]
La
pasa por almacenar
este
L solucin
l i a este
t problema
bl
l
t tipo
ti
de referencias y aadirlas a las variables raz antes del
proceso de recoleccin
variables

variables

G0

Recoleccin
Generacional

G1
G2

G0

G1
G

Francisco 2Ortn Soler

Algoritmos de Recoleccin de Basura

Recoleccin Generacional
Tras una serie de recolecciones de G0, en G1 se podr haber
generado una serie de bloques basura
Puesto que existir un conjunto de enlaces entre los elementos del
mdulo G0 y los de G1, ser menos costoso realizar la recoleccin
para ambas generaciones simultneamente
Toda recoleccin en Gi se realiza junto a todas sus
generaciones anteriores
Un
U bloque
bl
promociona

i
de
d Gi a Gi+1 tras sobrevivir
b
i i a2o3
recolecciones de Gi
Esta promocin puede realizarse de un modo sencillo
empleando recoleccin con copia (evitando adems la
fragmentacin)
Los estudios empricos con lenguajes funcionales y OO con
recoleccin de basura han concluido
Se elimina en torno al 90% de los bloques de G0 cada vez que
se pasa el recolector
Llevar a cabo este proceso supone una complejidad logartmica
respecto al nmero de bloques (las generaciones crecen
Francisco Ortn Soler
exponencialmente)

34

Algoritmos de Recoleccin de Basura

Ejemplo: JSDK 1.5


Existen mltiples implementaciones comerciales de
lenguajes con GC generacional: Lisps, Modula-3, SML/NJ,
Glasgow Haskell, Smalltalk, Java y C#
Java, en su versin de referencia JSDK 1.5, utiliza un
recolector de basura:
Basado en tres generaciones:
z Generacin young (tambin llamada eden)
z Generacin tenured (definitiva)
z Generacin permanent para elementos internos de
representacin de la JVM
z Los tamaos, porcentajes y umbrales son
parametrizables y dinmicos
Con distintos algoritmos de liberacin:
z Con copia (por omisin)
z Marcar y borrar (para versiones concurrentes)
Secuencial, incremental y concurrente (prximo
punto)
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Ejemplo: JSDK 1.5


public class GC {
public static void main(String[] args) {
if (args.length==0) {
System.err.println("Dame un nmero");
return;
}
int elementos=Integer.parseInt(args[0]);
GC[] v=new GC[elementos/10];
long de=System.currentTimeMillis();
for (int i=0;i<elementos;i++) {
GC gc=new GC();
if (i%10==0)
v[i/10]=gc;
}
long a=System.currentTimeMillis();
System.out.println(""+(a-de)+" milisegundos.");
}
}
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Ejemplo: JSDK 1.6


Generacional (young, tenured, permanent), con copia y
secuencial:
java -verbose:gc -XX:+PrintGCDetails GC 15000000
Con basura -> Sin basura
Salida:

Tiempo empleado
[GC [DefNew: 147K->63K(576K), 0.0069869 secs]
[Tenured: 31K->95K(1408K), 0.0510101 secs]
Se ampla la tenured!
147K->95K(1984K), 0.0582292 secs]
(promocin de bloques)
[GC [DefNew: 512K->51K(576K), 0.0060298 secs]]
[GC [
[
[DefNew: 563K->51K(576K),
(
), 0.0076222 secs]]
]] Se recoje el 90%
[GC [DefNew: 563K->51K(576K), 0.0076088 secs]]
[GC [DefNew: 563K->51K(576K), 0.0076518 secs]]
[GC [DefNew: 563K->51K(576K), 0.0086422 secs]]
Tamaos Disponibles
...
[GC [DefNew: 563K->51K(576K), 0.0077566 secs]
[Tenured: 1448K->1499K(1536K), 0.1011562 secs]
1960K->1499K(2112K), 0.1091994 secs]
[GC [DefNew: 512K->51K(576K), 0.0047098 secs]]
[GC [DefNew: 563K->51K(576K), 0.0076496 secs]]
[GC [DefNew: 563K->51K(576K), 0.0077122 secs]]
[GC [DefNew: 563K->51K(576K), 0.0076499 secs]]
[GC [DefNew: 563K->51K(576K), 0.0076999 secs]]
...
781 milisegundos.
Francisco Ortn Soler

35

Algoritmos de Recoleccin de Basura

Rec. Incremental y Concurrente

La ejecucin del recolector de basura supone una


interrupcin de la ejecucin de la aplicacin
Para determinados lenguajes interactivos o en tiempo
real, esta interrupcin puede no ser tolerable
Los algoritmos de recoleccin incrementales y
concurrentes son aquellos que entrelazan la
j
g
del p
programa
recoleccin de basura con la ejecucin
Cabe destacar dos conceptos:
1.
El modificador es la parte de la ejecucin de la
aplicacin que modifica la estructura del grafo de
bloques (por ejemplo, asignando referencias)
2.
El recolector es el programa encargado de eliminar
los bloques basura
Un algoritmo recolector de basura ser:

Incremental si el recolector se ejecuta nicamente


cuando el modificador lo solicita

Concurrente si el recolector se ejecuta entre o


durante la ejecucin del modificador

Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Rec. Incremental y Concurrente


Estos algoritmos de basura emplean las
tcnicas vistas anteriormente (marcado y
borrado, de copia o generacional)
Lo que aportan principalmente es evitar la
interrupcin de ejecucin normal de una
aplicacin
Existen diversas tcnicas de cooperacin
incremental o concurrente entre el recolector y
el modificador

Dijkstra y Lamport
Steele
Boehm, Demers & Dhenker
Baker
Appel, Ellis & Li

Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Algoritmo Incremental de Baker


El algoritmo incremental de Baker es una
modificacin del algoritmo de recoleccin con
copia (generacional)
Efecta una iteracin incremental entre el
modificador y el recolector

Una vez detectada la necesidad de recoger la


basura, los roles de zona origen (from) y
destino (to) son intercambiadas
El nuevo bloque es obtenido de la zona origen
Cada vez que se solicita la asignacin de un
nuevo bloque, ste es creado en la zona origen
y un conjunto de bloques son movidos a la
nueva zona origen (incremental)
La recoleccin finaliza cuando no quedan
bloques por mover

Francisco Ortn Soler

36

Algoritmos de Recoleccin de Basura

Ejemplo: Algoritmo de Baker


Origen
Destino

Destino
Origen

6
7

Se solicita un
nuevo bloque

3
2

4
3
Variables

a
8
4

Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Ejemplo: JSDK 1.6


La plataforma de referencia JSDK 1.6 de Java
est parametrizada con un conjunto de opciones
-XX no estndar
Su uso principal es controlar y parametrizar la
ejecucin del recolector de basura
Ejemplos:

Ejecucin incremental con algoritmos


generacionales de copia
java -verbose:gc -XX:+UseParallelGC
-XX:+PrintGCDetails GC 15000000

Ejecucin concurrente con algoritmos concurrentes


en el que la generacin tenured se ejecuta con
marcar y borrar
java -verbose:gc -XX:+UseConcMarkSweepGC
-XX:+PrintGCDetails GC 15000000
Francisco Ortn Soler

Algoritmos de Recoleccin de Basura

Ejemplo: JSDK 1.6


java -verbose:gc -XX:+UseParallelGC
-XX:+PrintGCDetails GC 15000000

Cada vez que salta el recolector


para eden, realiza parte de
recoleccin de la tenured

[GC [PSYoungGen: 3072K->416K(3584K)]


8931K->6275K(33856K), 0.0102820 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen: 3488K->512K(6656K)]
9347K->6567K(36928K), 0.0136218 secs]
[Times: user=0.02 sys=0.00, real=0.02 secs]
[GC [PSYoungGen: 6656K->512K(6656K)]
12711K->7187K(36928K), 0.0218528 secs]
[Times: user=0.03 sys=0.00, real=0.03 secs]
[GC [PSYoungGen: 6656K->512K(12800K)]
13331K->7807K(43072K), 0.0221889 secs]
[Times: user=0.02 sys=0.00, real=0.02 secs]
[GC [PSYoungGen: 12800K->512K(12800K)]
20095K->9043K(43072K), 0.0370296 secs]
[Times: user=0.03 sys=0.00, real=0.03 secs]

...
672 milisegundos (781 ms, la versin secuencial)
Francisco Ortn Soler

37

Algoritmos de Recoleccin de Basura

Ejemplo: JSDK 1.6


Mark & Sweep, haciendo
java -verbose:gc -XX:+UseConcMarkSweepGC la
recoleccin de tenured
-XX:+PrintGCDetails GC 15000000
en paralelo
[GC [DefNew: 13184K->824K(14784K), 0.0256379 secs]
13184K->6685K(63936K), 0.0257527 secs] [Times:
user=0.01 sys=0.00, real=0.02 secs]
...
[GC [1 CMS-initial-mark: 26531K(49152K)] 27849K(63936K),
0.0043073 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-mark:
user=0.13
[CMS
t
k 0.129/0.129
0 129/0 129 secs]] [Times:
[Ti
0 13
sys=0.00, real=0.13 secs]
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00
sys=0.00, real=0.00 secs]
[GC[YG occupancy: 1318 K (14784 K)][Rescan (non-parallel)
[grey object rescan, 0.0002112 secs][root rescan, 0.0039611
secs], 0.0042463 secs][weak refs processing, 0.0000237 secs]
[1 CMS-remark: 26531K(49152K)] 27849K(63936K),
0.0043911 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-sweep: 0.031/0.031 secs] [Times: user=0.03
sys=0.00, real=0.03 secs]
[CMS-concurrent-reset: 0.002/0.002 secs] [Times: user=0.01
sys=0.00, real=0.02 secs]...
953 milisegundos (781 ms, la versin secuencial)Francisco Ortn Soler

Contenido

Introduccin
Representacin de los datos
Organizacin de la memoria durante la ejecucin
Memoria esttica
Memoria dinmica de pila
Memoria dinmica heap
Algoritmos de recoleccin de basura
Mecanismos para el paso de parmetros

Francisco Ortn Soler

Mecanismos para el Paso de Parmetros

Paso de Parmetros
Hemos visto cmo en la llamada a una funcin, los
argumentos (parmetros reales) corresponden a valores
existentes en el registro de activacin
Estos valores son almacenados en la secuencia de
llamada previamente a la invocacin
De este modo
modo, un parmetro (formal) representa dentro
del cdigo de una funcin un modo de acceder a los valores
de los argumentos
El modo de acceso es mediante desplazamientos
(offsets) dentro del registro de activacin
El lenguaje de programacin describir el mecanismo que
establece la dependencia entre los valores de los
argumentos y de los parmetros
Esta dependencia se define como el mecanismo de
paso de parmetros
Francisco Ortn Soler

38

Mecanismos para el Paso de Parmetros

Tipos de Pasos de Parmetros

Los distintos mecanismos existentes de


paso de parmetros son:

Paso por valor


Paso por referencia
Paso por valor-resultado
Paso por nombre
Paso por necesidad (evaluacin diferida o
perezosa)
Francisco Ortn Soler

Mecanismos para el Paso de Parmetros

Paso por Valor


Los argumentos son expresiones evaluadas en el
momento de la llamada
Los parmetros obtendrn el valor resultante de dichas
evaluaciones
Mecanismo empleado por C, Java y disponible en Pascal y
Ada
En algunos lenguajes como Ada, estos parmetros

poseen
valores que no pueden ser modificados
En otros lenguajes como C o Pascal, representan
variables similares a las variables locales
No requiere una implementacin compleja
No es posible modificar el argumento dentro del cdigo de
la funcin
void inc(int x) { ++x; } // No tiene utilidad
El programador, puede conseguirlo con indirecciones:
void inc(int *x) { ++(*x); } // Se invocaFrancisco
inc(&a)
Ortn Soler

Mecanismos para el Paso de Parmetros

Paso por Referencia


En el paso por referencia, el argumento ha de ser un
lvalue
Se pasa a la funcin la ubicacin de la variable
El parmetro se convierte en un alias del argumento
Cualquier cambio en el parmetro supone un cambio en
el argumento
Fortran77
F t
77 slo
l permite
it paso por referencia.
f
i Pascal
P
l lo
l ofrece
f
con la palabra reservada var y en C++ se obtiene con el
concepto de referencia (&)

void inc(int &x) { ++x; }


Este paso de parmetros requiere que el compilador calcule
la direccin del argumento y la almacene en el registro de
activacin
La utilizacin de los parmetros sern accesos a los
parmetros a travs de su direccin
Es ms rpido y ocupa menos memoria que el paso por
valor, para tipos construidos

Francisco Ortn Soler

39

Mecanismos para el Paso de Parmetros

Ejercicio

En la prctica de la asignatura, tanto los


registros
i t
como los
l arrays se han
h
de
d pasar por
referencia
Cmo tendremos en cuenta esto para calcular
el offset de las variables locales en MAPL
(VisitorOffset)?

Francisco Ortn Soler

Mecanismos para el Paso de Parmetros

Paso por Valor-Resultado


Se obtiene un resultado similar al paso por referencia, pero
sin establecer realmente un alias real
El valor del argumento es copiado en la pila y utilizado en
la funcin (parmetro)
Una vez finalizada la ejecucin de la funcin, el valor del
p
p
p
parmetro es empleado
para sobrescribir el valor del
argumento
Este mtodo tambin es denominado copia de entrada,
copia de salida
Ada implementa este paso de parmetros cuando se declara
ste como in y out
Con la sintaxis de C, el siguiente ejemplo con paso por
valor-resultado hace que a tenga un valor igual a 2

void inc2(int x,int y) { ++x; ++y; }


int a a=1; inc2(a,a); // a == 2
Francisco Ortn Soler

Mecanismos para el Paso de Parmetros

Paso por Nombre


El argumento no es evaluado hasta su uso real (como
un parmetro) en la funcin invocada
La interpretacin del paso por nombre es como sigue

La expresin que representa el argumento de una


invocacin
es contemplada como una funcin

(thunk)

Cada vez que se accede al parmetro desde la


funcin, se invoca al thunk creado
De este modo, el efecto que se produce es el mismo al
obtenido si se reemplaza el nombre del parmetro por
la representacin textual del argumento
Este paso de parmetros es ofrecido por Algol60
Francisco Ortn Soler

40

Mecanismos para el Paso de Parmetros

Paso por Nombre


Empleando la sintaxis de C, la siguiente funcin
void inc(int x) { ++x; }

en la invocacin inc(a[i]), obtendr el mismo efecto de


evaluar ++(a[i])
De esta forma, el programa
int i;
; int a[10];
[ ];
void p(int x) { ++i; ++x; }

int main () { i=1; a[1]=1; a[2]=2;


p(a[i]); // a[2]==3 y a[1] no se modifica
}

Posee tres inconvenientes


1.
Es poco intuitivo
2.
Es muy complejo de implementar
3.
Es poco eficiente, puesto que se llama al thunk tantas
veces como accesos se realicen del parmetro

Francisco Ortn Soler

Mecanismos para el Paso de Parmetros

Paso por Necesidad o Perezoso


El paso por necesidad (by need), tambin
llamado perezoso (lazy) es una modificacin del
paso por nombre
Este paso de parmetro memoriza el valor
devuelto en la primera invocacin del thunk

En sucesivas invocaciones devuelve este valor


almacenado, sin volver a evaluar el thunk

Obtiene una mayor eficiencia que el paso de


parmetros por nombre
En ocasiones puede resultar ms eficiente que
otros paso de parmetros, puesto que si no se
accede al parmetro dinmicamente, ste no se
evala
Lenguajes que utilizan evaluacin perezosa son
Haskell y Miranda
Francisco Ortn Soler

Bibliografa
Construccin de Compiladores Principios y
Prctica.
K.C. Louden.
Thomson. 2004.
Modern compiler implementation in Java.
A Appel
A.
Cambridge University Press. 2002.
Programming Language Processors in Java.
D.A. Watt, D.F. Brown.
Prentice Hall, 2000.
Intrpretes y Diseo de Lenguajes de
Programacin.
J.E. Labra, J.M. Cueva, R. Izquierdo, A.A. Juan,
M.C. Luengo, F. Ortn.
Servitec. 2003.

Francisco Ortn Soler

41

Procesadores de Lenguaje
Francisco Ortn Soler

Organizacin de la Memoria en
Ti
Tiempo
d
de Ej
Ejecucin
i

Lenguajes y Sistemas
Informticos

Universidad de Oviedo

42

Das könnte Ihnen auch gefallen