I recently got interested into OCaml and thought about
resurrecting the native m68k compiler for m68k, is the old
bitrotten code available somewhere?
Richard
-------------------
To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Yes, you can find it in release 2.04 (the last stable release before
m68k support was deprecated):
http://caml.inria.fr/distrib/ocaml-2.04/ocaml-2.04.tar.gz
Have fun,
- Xavier Leroy
In such case what about ocaml port for palm pilot?
Regards!
GNS
--
Gleb N. Semenov 111621, Muromskaya St. 21, apt. 2, Moscow, Russia
gl...@ahome.ru phone: +7(095)700.0172
François Rouaix did a Palm port of Caml Light (the "lean and mean"
ancestor of OCaml) a long time ago.
The main problem was that the data segment of a Palm OS program had to
fit in 64K, which is quite tight for Caml Light and definitely not
enough for OCaml. (The remainder of the RAM was either read-only code
blocks, or PalmOS "databases" that must be accessed through system calls.=
)
I don't know if this limitation was lifted in later versions of PalmOS.
Problem number 2 is that text-only apps aren't very usable on a
handheld, so you'd need to interface a large chunk of the GUI toolkit.
- Xavier Leroy
-------------------
To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.inr=
ia.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr=
- Dan Albro
Xavier Leroy wrote:
>>In such case what about ocaml port for palm pilot?
>
>
> François Rouaix did a Palm port of Caml Light (the "lean and mean"
> ancestor of OCaml) a long time ago.
>
> The main problem was that the data segment of a Palm OS program had to
> fit in 64K, which is quite tight for Caml Light and definitely not
> enough for OCaml. (The remainder of the RAM was either read-only code
> blocks, or PalmOS "databases" that must be accessed through system call=
s.)
> I don't know if this limitation was lifted in later versions of PalmOS.
>
> Problem number 2 is that text-only apps aren't very usable on a
> handheld, so you'd need to interface a large chunk of the GUI toolkit.
>
> - Xavier Leroy
>
> -------------------
> To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.i=
nria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.=
fr/FAQ/
ok, I got 2.0.4 working for m68k-linux, not very hard.
Speed is quite impressive, fib is faster than gcc code ?!
One thing that I need to verify is the interaction of the native
compiler and the strange m68k-linux ABI which is different from
SUN or BSD. The unusual part of m68k-linux ABI is that functions
returning pointer return their value in register a0, while integer
types are retuned in d0.
How does the code generated by the native compiler interact
with c-ABI functions?
Richard
Sure: gcc passes all parameters on the stack, ocamlopt passes the
first ones in registers.
> One thing that I need to verify is the interaction of the native
> compiler and the strange m68k-linux ABI which is different from
> SUN or BSD. The unusual part of m68k-linux ABI is that functions
> returning pointer return their value in register a0, while integer
> types are retuned in d0.
>
> How does the code generated by the native compiler interact
> with c-ABI functions?
C functions that can be called by Caml code must be declared with
return type "value", which is "long". So, the C compiler will arrange
for the result to be in D0, which is where ocamlopt-generated code
expects to find it.
- Xavier Leroy
a short update, adapting to 3.06 was not very difficult but
somehow triggered a few bugs in the code.
Simple examples like "fib" work fine, ocamlc.opt crashes in
parsing/linenum.ml so I am slowly adding debugging support to
code generation to find out details.
One of the bugs had to do with register reloading, pseudos
that was allocated hard register in previous version ended
up as stack slots (somehow a0 often isn't used for allocation
where it previously was). Emitting code didn't take this
possibility into account in some places generating assembly
code.. most likely the register constraints aren't good enough.
Does anyone have a test suite? What kind of problems had other
architectures between 2.04 and 3.06?
Richard
I have had some progress recently, ocamlc.opt works and
even produces working code now.
The remaining problem is a bit tougher though, not quite
deterministic it appears: running
./ocamlopt.opt -I stdlib fib.ml
segfaults in either
Queue__take_87
Cmmgen__transl_all_functions_1418
*or*
Reload__fundecl_338
Asmgen__regalloc_175
80% of the time it crashes in fundecl.
What could be the source of such indeterministic behaviour?
gc?
Richard
Byron
At 11:58 PM 9/5/2003 +0200, you wrote:
>Hi,
>
>I have had some progress recently, ocamlc.opt works and
>even produces working code now.
>
>The remaining problem is a bit tougher though, not quite
>deterministic it appears: running
> ./ocamlopt.opt -I stdlib fib.ml
>segfaults in either
> Queue__take_87
> Cmmgen__transl_all_functions_1418
>*or*
> Reload__fundecl_338
> Asmgen__regalloc_175
>
>80% of the time it crashes in fundecl.
>
>What could be the source of such indeterministic behaviour?
>gc?
>
>Richard
There's some useful information here on how to find out whether you have
a hardware problem:
http://www-106.ibm.com/developerworks/library/l-hw1/
http://www.bitwizard.nl/sig11/
Ben
> What could be the source of such indeterministic behaviour?
> gc?
I would guess it is related to GC or bad memory allocation (in case of C
code).
As far as I remember, OCaml GC is using usual libc malloc and free, so
you could activate libc checks to help find the bug (see mcheck(), there
is also an environment variable I don't remember). You could also take a
look at libefence.
Other things that might help is to zeroing data structures before
releasing them to free(). Sometimes, you reuse a datastructure that is
has been freed.
To make the port, what have you modified? Only Caml code or also C code?
My .2 euros,
Yours,
d.
--
David Mentré <dme...@linux-france.org>
http://www.linux-france.org/~dmentre/david-mentre-public-key.asc
GnuPG key fingerprint: A7CD 7357 3EC4 1163 745B 7FD3 FB3E AD7C 2A18 BE9=
E
-------------------
To unsubscribe, mail caml-lis...@inria.fr Archives: http://caml.inr=
ia.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr=
> What could be the source of such indeterministic behaviour?
There is at least one source of nondeterminism in the compiler:
the generation of temporary file names. And it can be influenced
by the contents of the /tmp directory, especially when a previous
compiler run has crashed and left its temporary files there...
There may be other sources of nondeterminism, but I can't think
of any off the top of my head.
> gc?
No, the GC is completely deterministic (thank God).
-- Damien
let l = ... a function building a long list ... in
let l' = List.map fn l in (* or fold or anything similar *)
... no more reference to l ...
Once the beginning of l has been read to compute l' (assuming List.map
starts from the beginning of l) is the GC able to collect the beginning
of l ?
If not how to write the code to ensure this behaviour of the GC ?
--
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex
tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christoph...@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI
---------------------------------------------
IMPORTANT: this mail is signed using PGP/MIME
At least Enigmail/Mozilla, mutt or evolution
can check this signature
---------------------------------------------
No it cannot since, AFAIK, l is not freed (i.e. assigned to 0) into
the stack (or local environment) before you leave the block where your
code occurs (normally the activation block of the function where it
appears in).
> If not how to write the code to ensure this behaviour of the GC ?
>
> Christophe Raffalli
Do not use let bindings, write function applications or function
compositions instead.
(Instead of writing
let l1 = f l0 in
let l2 = g l1 in
h l2
write
let i l = h (g (f l)) in
i l0)
Alternatively, use explicit references to lists and free them
explicitely in your code ! This is tractable when the flow of control
of the code is simple enough (for instance in the case of a
clear succession of passes where data from previous passes are clearly
unused in the following steps).
Hope this helps,
Pierre Weis
INRIA, Projet Cristal, Pierr...@inria.fr, http://pauillac.inria.fr/~weis/
And
let l' =
let l = ... a function building a long list ... in
List.map fn l
in
should work then (it is simpler to read than composition) ?
Short answer: with ocamlc, no. With ocamlopt, yes.
Longer answer: in the bytecoded implementation, every value in the VM
stack is a GC root. "let x = e in e'" pushes the value of e on the
stack just before evaluating e', and pops it at the end of e'. So,
the value of e remains a live GC root throughout the evaluation of e'.
In the native-code implementation, not all machine stack entries are
GC roots, but only the stack slots that hold a variable of type
address that is live at the point where the GC is called. ("Live"
here is in the sense of liveness analysis of local variables.)
In your example, "l" is not live across the call to "List.map fn l".
> If not how to write the code to ensure this behaviour of the GC ?
As other mentioned, removing the outer "let" gives the desired GC
behavior even in bytecode:
List.map fn l (... list builder ...)
In the OCaml sources, you can find this strange-looking idiom:
let (++) x f = f x
Pparse.file ppf inputfile Parse.implementation ast_impl_magic_number
++ print_if ppf Clflags.dump_parsetree Printast.implementation
++ Typemod.type_implementation sourcefile prefixname modulename env
++ Translmod.transl_implementation modulename
++ print_if ppf Clflags.dump_rawlambda Printlambda.lambda
++ Simplif.simplify_lambda
++ print_if ppf Clflags.dump_lambda Printlambda.lambda
++ Bytegen.compile_implementation modulename
++ print_if ppf Clflags.dump_instr Printinstr.instrlist
++ Emitcode.to_file oc modulename;
which is a nicer way of writing
Emitcode.to_file oc modulename
(print_if ....
(Bytegen.compile_implementation ...
(print_if ...
(...
))))
and gives better GC behavior than the obvious:
let x1 = Pparse.file ppf inputfile Parse.implementation ast_impl_magic_number in
let x2 = print_if ppf Clflags.dump_parsetree Printast.implementation p x1 in
let x3 = Typemod.type_implementation sourcefile prefixname modulename env x2 in
...
- Xavier Leroy