Hola gente!

Gracias por el detalle, a Andres y a Gerardo. 

Con respecto a lo que plantea Andres, no se resuelve gran parte de eso
adoptando como lenguaje de implementación algo sobre Java o .NET? Cuanto se
resolvería asi? Yo, en mi pet Project, no tengo que preocuparme de GC o de
FFI, simplemente accedo a .NET (como podria acceder a Java, si reimplemento
todo en Java).

Veo en los últimos anios varios lenguajes implementados asi (desde Clojure a
IronRuby, IronPython, IronScheme, etc..). Hasta creo recordar a Dan Ingalls
o Alan Kay, reimplementando un Smalltalk VM en Java.

Cuales serian los problemas que encontrarían o ya se encontraron, en ese
camino?

Independientemente de eso, alguien mas sobre un detalle de que incluir en
una VM?

Nos leemos!

Angel "Java" Lopez
http://www.ajlopez.com/
http://twitter.com/ajlopez

-----Mensaje original-----
De: [email protected] [mailto:[email protected]]
En nombre de Andres Valloud
Enviado el: lunes, 26 de julio de 2010 16:02
Para: [email protected]
Asunto: Re: [clubSmalltalk] RV: DNG-Win32 Bit VM

Antes de laburar en esto, tenia una idea bastante ingenua.  Pensaba
que "VM" queria decir "ejecutar bytecodes y todas las optimizaciones
que tienen que ver con eso" y nada mas.  Grave error...

Por ejemplo, si, hay que programar primitivas, pero no son todas
iguales.  Por ejemplo, tenes cosas como identityHash, basicAt:put:,
size, en algunos Smalltalks next/nextPut:,
replaceFrom:to:with:startingAt:, new, small integer, large integer,
float, double, y todo eso.  Hasta ahi viene mas o menos facil la mano.
 Pero tambien hay cosas como archivos, sockets, impresoras, mouse,
teclado, graficos, ventanas, eventos (digo de Windows)... eso ya es
mas pesado, en particular si tu VM tiene que andar en N plataformas.
Encima de eso hay cosas ya mas fuleras como signals (que te
interrumpen tu VM en cualquier momento, en particular mientras tu VM
esta en codigo JITeado), y timers asi te anda Delay.  Donde estan los
standards de esto para cada plataforma asi se pueden programar solo
una vez?  Los timers que estas usando son independientes del cambio de
hora o no?  Resolver eso, y dejar a la imagen andando "como siempre"
no es facil.  Como te las arreglas para que un signal *siempre*
interrumpa a Smalltalk asi la VM puede fijarse que paso y reaccionar
acorde, pero sin matar la performance ni hacer polls (por ejemplo,
salto un timer asociado con un delay, asi que ahora hay que hacerle
signal a un semaphore y correr de nuevo el process scheduler porque el
proceso que estaba esperando en el semaphore puede tener mas prioridad
que el proceso que esta corriendo ahora --- y si salta un timer
mientras te estas fijando que proceso correr (porque x ej la imagen
hizo Processor yield o Semaphore wait), que?)?

Tambien pensaba que el GC era bastante mas simple de lo que es.  Mas
que garbage collect hay que pensar en memory management.  Cuando la
imagen dice "new", donde pones ese objeto?  Como decidis eso rapido?
Si la imagen te dice "quiero mas memoria", que haces?  malloc()?
mmap()?  sbrk()?  Y si alguno de esos falla, que pasa?  Y si la
memoria que te da el sistema operativo no te sirve porque la direccion
no es la que queres, que pasa?  Esta bueno tener varios espacios de
objetos (new, old, fixed, etc).  Que pasa cuando la imagen hace un
become: entre objetos en diferentes espacios?  Que pasa con
oneWayBecome:?  Y si hay que copiar objetos y el nuevo no entra, que?
Como haces que la VM proteste cuando no hay espacio?  Esto requiere
una cantidad de laburo grande en la imagen para que funcione bien el
tandem.  Como se graba la imagen, y como la volves a cargar?  Eso
tampoco es facil, tener que manosear todos los punteros.  Mas espacios
de objetos tenes, mas complicado se pone.  Si tenes un incremental
garbage collector, mas complicado todavia.  Ademas le tenes que
agregar weak objects, ephemerons, y finalization.

En VW, todo esto tiene que andar junto y bien: el scavenger de new
space, el IGC, el data compactor, el GC (mark/sweep), el global GC
(mark/sweep, pero tambien de perm space), weak objects, ephemerons,
finalization, los remember tables de turno, y tambien en 64 bits la
tabla de clases que es weak pero que durante un scavenge es strong si
esta funcionando el IGC.  Solo esto ya es complicado...

Ademas de que la imagen llame a cosas y permita callbacks, tambien
esta bueno que alguien llame a la VM y le diga cosas como "che fiera
ejecutame este codigo y decime que pasa".  O que te caiga un callback
que no pediste inmediatamente antes (o sea que se ejecuta en un thread
que no es el que lo pidio --- o sea que el thread ese no puede tocar
objetos porque en otro thread puede estar funcionando el garbage
collector, ouch).

Lo que si es la muerte es algo de lo que hable alla en Smalltalks: los
standards que rigen el mundo de C son demasiado grandes para una sola
persona (o para un grupo reducido de personas).  Mencione el manual de
GCC que en su momento tenia 662 paginas.  Bueno, porque la VM de Linux
en x86/64 se colgaba con SIGSEGV, mientras todas las otras VMs
andaban?  Porque el compilador era GCC, y ademas porque en 64 bits se
dan todas estas casualidades juntas:

1.  las entradas de la tabla de objetos tienen un bitfield al final.
2.  las entradas de la tabla de objetos estan contra el borde superior
de un cacho de memoria que te dio mmap() (o malloc(), o sbrk()...).
3.  el codigo C que lee esos bitfields resulta en diferente assembler
segun como cambia otro codigo C que no tiene nada que ver... o sea, el
estado interno del compilador resulta en unas instrucciones u otras
instrucciones.
4.  Algunas de esas instrucciones hacen, esencialmente,

mov 12+[objectTableEntryPtr], %eax

o si no

mov 13+[objectTableEntryPtr], %eax

Estoy haciendo el ejemplo asi no mas, pero esa es la idea: el
compilador hace un read, y despues hace shl y and de %eax para
conseguir el valor del bitfield que corresponde.  Cada object entry
tiene 16 bytes.  Que pasa cuando el objectTableEntryPtr apunta al
ultimo object table entry y el CPU trata de leer 4 bytes empezando en
13+objectTableEntryPtr?  El ultimo byte esta afuera del segmento
otorgado por el sistema operativo => SIGSEGV.  Y cuando ocurre el bug?
 Cuando la imagen le pide el identityHash a un objeto que tiene el
ultimo objectTableEntry en un segmento.  La imagen le pide
identityHash a los objetos con frecuencia?  Si, pero obviamente no a
todos... asi que si tenes suerte, no pasa nada.  Y si no tenes suerte,
bueh...

En 32 bits, no se dan todas las casualidades asi que las VMs
compiladas con GCC andan igual.  Pero si no te pasa el problema en 64
bits, tenes idea real de lo que esta pasando?  Igual hay que
arreglarlo, y para arreglar tenes que encontrar el error primero.
Podes pensar "jaja, es un error del optimizador, asi que ahora
compilamos con -O0", pero eso no es "encontrar el error" sino "voy a
cambiar cosas al azar hasta que el error desaparezca, y despues digo
que arregle lo que estaba mal".  Eso no esta bien.  Asi que hay que
ponerse a investigar.  Y, investigando, al final uno encuentra que el
manual de GCC dice claramente que esto es un problema del compilador:

============
# Accesses to bit-fields even in volatile objects works by accessing
larger objects, such as a byte or a word. You cannot rely on what size
of object is accessed in order to read or write the bit-field; it may
even vary for a given bit-field according to the precise usage.

If you care about controlling the amount of memory that is accessed,
use volatile but do not use bit-fields.
============

http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Disappointments.html#Disappointm
ents

Pero quien se lee todo el manual de GCC con cada version nueva que
sacan ANTES DE USARLO?  Y quien se lee todo MSDN, la documentacion de
Apple, etc?  Eso si que es dificil: te la pasas leyendo documentacion
para ver si lo que estas haciendo esta bien o mal.  Invariablemente,
como cada cosita que haces esta relacionada con alguna otra cosa, eso
te lleva de documento en documento como si estuvieras webeando en la
Wikipedia --- pero esta vez tenes que estudiar!

Por ejemplo: muchas funciones comunes de Unix te dicen como fallaron a
traves de un coso que se llama errno.  A veces tambien tenes que usar
esas funciones en signal handlers.  El standard de turno te dice
cuales podes usar y cuales no en un signal handler (printf(), por
ejemplo, no se puede).  Esas funciones tambien manosean el valor de
errno si fallan.  Y que pasa si un signal handler interrumpe tu codigo
justo despues de que falla una funcion pero antes de que el codigo se
fije el valor de errno, y el signal handler llama a una funcion que
tambien falla y cambia el valor de errno?  Cuando vuelve el signal
handler a tu programa, te podes encontrar que no pudiste abrir un
archivo porque (para inventar) la ultima vez que dividiste un numero
de punto flotante por otro el resultado fue NaN...

Para mi, el problema mas serio es que determinar que algo esta
Bien(TM) es MUY DIFICIL.  Esa investigacion constante lleva un monton
de tiempo y esfuerzo.  Por eso me parece mas valioso lo que esta
tratando de hacer Alan Kay... que se pueda programar una computadora
de manera decente pero que tengas que estudiar, como mucho, 20 mil
lineas de codigo.  20 mil lineas no es nada!

Ah, pero como, habia que ejecutar bytecodes?... :).  Bueno,
exactamente que haces cuando en el JIT tenes que hacer shl %cl, %reg,
y resulta que

1.  %ecx lo estas usando para otra cosa,
2.  %reg puede ser %ecx,
3.  no podes hacer push/pop,
4.  no hay registros disponibles (estan todos asignados),
5.  y ademas te tenes que guardar una copia de %reg antes de hacer el
shift en algun lado.

Ahi te pones a investigar la papeleria de Intel y descubris que aun
hoy solo se puede hacer shl/shr/sar usando a %cl.  Y ahora?... a
investigar de nuevo...

Andres.

2010/7/26 Gerardo Richarte <[email protected]>:
> On 07/26/2010 09:25 AM, Angel "Java" Lopez wrote:
>> Andres, interesante... Podrias enumerar por aquí una lista de lo que hace
>> una VM?
>>
> che, a mi también me interesa mucho la verdad, ya a esta idea nos fuimos
> armando una idea, pero estaría bueno escuchar tu opinion. Para mi en
> este momento, con toda la experiencia que ganaste en estos años siendo
> el que está a cargo [una] de las VM de Smalltalk más usadas [la de VW]
> tu palabra vale mucho.
>
> Yo tiro algo, veamos:
>
> . Bytecode execution engine (interprete y/o JIT)
> . primitives
> . garbage collection
> . method lookup
> . FFI
> . Process scheduler (?)
> . Callback mechanism (?)
>
>    a ver?
>    saludos
>
> --
> To post to this group, send email to [email protected]
> To unsubscribe from this group, send email to
[email protected]
>
> http://www.clubSmalltalk.org

-- 
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]

http://www.clubSmalltalk.org
No virus found in this incoming message.
Checked by AVG - www.avg.com 
Version: 8.5.441 / Virus Database: 271.1.1/3029 - Release Date: 07/26/10
06:36:00

-- 
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]

http://www.clubSmalltalk.org

Responder a