[MLton] Progress on AMD64/FreeBSD

Matthew Fluet fluet at tti-c.org
Sat Jun 23 17:46:48 PDT 2007


Jesper Louis Andersen wrote:
> However, this is not enough! Our runtime enters an infinite loop on the
> heap-allocation for any
> program. 

 From everything you've described, I'm guessing that this isn't quite an 
infinite loop.  I believe that things are looping in the createHeap 
function of runtime/gc/heap.c.  There are loops there trying to mmap at 
high or low addresses in order to help prevent fragmentation (and a 
future mmap failing).  That is, we don't want a heap allocated in the 
middle of the address space, preventing us from allocating another heap.

On a 64-bit machine, the address space is huge; so scanning through the 
address space at (size_t)0x08000000 increments takes a long time.  We 
don't usually expect these mmaps to fail.  And then, even if we do scan 
through the entire space without a successful mmap, we backoff on the 
allocation size and try again.  Eventually, one should get an out of 
memory type message and program termination.

All that being said, you might try replacing the whole
     for (i = 0; i <= count; i++) {
        ...
     }
loop with
       h->start = GC_mmapAnon (NULL, h->size);
       if ((void*)-1 == h->start)
         h->start = (void*)NULL;
       unless ((void*)NULL == h->start) {
         if (h->size > s->cumulativeStatistics.maxHeapSizeSeen)
           s->cumulativeStatistics.maxHeapSizeSeen = h->size;
         if (DEBUG or s->controls.messages)
           fprintf (stderr, "Created heap of size %s at "FMTPTR".\n",
                    uintmaxToCommaString(h->size),
                    (uintptr_t)h->start);
         assert (h->size >= minSize);
         return TRUE;
       }
That is, for each attempted heap size between desiredSize and minSize, 
only call mmap once, with a NULL address, to take any available memory.


 > I instrumented mllex with a debug runtime and added some printfs
> since I couldn't figure
> out the maze in the C code for adding DEBUG of the GC.
> 
> We are looping with:
> 
> ogre% ./build/bin/mllex | head -n 60
> physMem: 1061425152
> Couldn't map 0, 94208
> Couldn't map f8000000, 94208
> Couldn't map f0000000, 94208
> Couldn't map e8000000, 94208
> Couldn't map e0000000, 94208
> Couldn't map d8000000, 94208
> Couldn't map d0000000, 94208
> Couldn't map c8000000, 94208
> Couldn't map c0000000, 94208
> Couldn't map b8000000, 94208
> Couldn't map b0000000, 94208
> Couldn't map a8000000, 94208
> Couldn't map a0000000, 94208
> Couldn't map 98000000, 94208
> Couldn't map 90000000, 94208
> Couldn't map 88000000, 94208
> Couldn't map 80000000, 94208
> Couldn't map 78000000, 94208
> Couldn't map 70000000, 94208
> Couldn't map 68000000, 94208
> Couldn't map 60000000, 94208
> Couldn't map 58000000, 94208
> Couldn't map 50000000, 94208
> Couldn't map 48000000, 94208
> Couldn't map 40000000, 94208
> Couldn't map 38000000, 94208
> Couldn't map 30000000, 94208
> Couldn't map 28000000, 94208
> Couldn't map 20000000, 94208
> Couldn't map 18000000, 94208
> Couldn't map 10000000, 94208
> Couldn't map 8000000, 94208
> Couldn't map 0, 94208
> Couldn't map f8000000, 94208
> Couldn't map f0000000, 94208
> Couldn't map e8000000, 94208
> ...
> 
> Where I instrumented a print of the address and size of the failing mmap()
> call inside
> the code. GDB:
> 
> Breakpoint 1, 0x000000003813e5c0 in mmap () from /lib/libc.so.6
> (gdb) bt
> #0  0x000000003813e5c0 in mmap () from /lib/libc.so.6
> #1  0x000000000044bb4f in mmapAnon (start=0xf7fffffff8000000,
>    length=94208) at platform/mmap.c:2
> #2  0x000000000044bb29 in GC_mmapAnon (
>    start=0xf7fffffff8000000, length=94208)
>    at platform/use-mmap.c:12
> #3  0x00000000004453d4 in createHeap (s=0x2c68, h=0x567308,
>    desiredSize=17870283321271910400, minSize=5658496)
>    at gc/heap.c:184
> #4  0x0000000000446039 in initWorld (s=0x566f20)
>    at gc/init-world.c:144
> #5  0x0000000000446e56 in GC_init (s=0x566f20, argc=1, argv=0x1)
>    at gc/init.c:334
> #6  0x000000000044b3fe in MLton_init (argc=1,
>    argv=0x7fffffffe598, s=0xf7fffffff8000000) at platform.c:20
> #7  0x0000000000402ed8 in main (argc=-134217728, argv=0x17000)
>    at /tmp/file0NuI7N.3.c:1562
> (gdb) down
> #3  0x00000000004453d4 in createHeap (s=0x2c68, h=0x567308,
>    desiredSize=17870283321271910400, minSize=5658496)
>    at gc/heap.c:184
> 184           h->start = GC_mmapAnon ((pointer)address, h->size);
> (gdb) print address
> $1 = 17870283321271910400
> (gdb) print h->size
> $2 = 94208
> 
> ogre% git-branch
>  freebsd-fix-runtime-bugs
> * freebsd-port-branch
>  master
>  mlton-2005
>  mlton-trunk
>  port-amd64-freebsd
>  ssa-tree-cleanup
> 
> git-log -20 output:
> commit 467cdf0a4b20f6913838aa7e0e78da949f03c09b
> Author: Jesper Louis Andersen <jesper.louis.andersen at gmail.com>
> Date:   Sat Jun 23 21:15:22 2007 +0200
> 
>    Get rid of #include <assert.h> again.
> 
> commit f3ba5ec5d8d65a319ed419d79b837c054e35d281
> Author: Jesper Louis Andersen <jesper.louis.andersen at gmail.com>
> Date:   Sat Jun 23 21:10:58 2007 +0200
> 
>    Make sysctl use a size_t rather than a int. Should fix a 32/64-bit
> problem.
> 
> commit a0110af4c457d1b2c506b3de5bf497a38b1f09cf
> Author: Jesper Louis Andersen <jesper.louis.andersen at gmail.com>
> Date:   Sat Jun 23 16:07:11 2007 +0200
> 
>    Adding a check to the runtime.
> 
> commit 6aeba2ddd5289ea75394560b516f52881aff3ee3
> Author: Jesper Louis Andersen <jesper.louis.andersen at gmail.com>
> Date:   Sat Jun 23 00:35:04 2007 +0200
> 
>    Make the runtime aware of the differences between i386 and amd64
> FreeBSD.
> 
> commit d63bd90db659f6b58c450c96f9ef075362fba57e
> Author: Jesper Louis Andersen <jesper.louis.andersen at gmail.com>
> Date:   Sat Jun 23 00:05:02 2007 +0200
> 
>    FreeBSD uses the machine specifier of 'amd64' for amd64. Alter
> bin/platform
> 
>    to understand this.
> -------------
> 
> ogre% git-diff trunk
> ---
> diff --git a/bin/platform b/bin/platform
> index 73ab3c7..5b58e2e 100755
> --- a/bin/platform
> +++ b/bin/platform
> @@ -76,6 +76,9 @@ x86_64*)
> i?86_64)
>         HOST_ARCH=amd64
> ;;
> +amd64)
> +        HOST_ARCH=amd64
> +;;
> arm*)
>         HOST_ARCH=arm
> ;;
> diff --git a/runtime/platform/freebsd.c b/runtime/platform/freebsd.c
> index c182532..f4c9927 100644
> --- a/runtime/platform/freebsd.c
> +++ b/runtime/platform/freebsd.c
> @@ -18,7 +18,13 @@ void GC_displayMem () {
> static void catcher (__attribute__ ((unused)) int sig,
>                      __attribute__ ((unused)) siginfo_t *sip,
>                      ucontext_t *ucp) {
> +#if (defined (__x86_64__))
> +        GC_handleSigProf ((code_pointer) ucp->uc_mcontext.mc_rip);
> +#elif (defined (__i386__))
>         GC_handleSigProf ((code_pointer) ucp->uc_mcontext.mc_eip);
> +#else
> +#error Profiling handler is missing for this architecture
> +#endif
> }
> 
> void GC_setSigProfHandler (struct sigaction *sa) {
> diff --git a/runtime/platform/sysctl.c b/runtime/platform/sysctl.c
> index f7381de..2b7ebdf 100644
> --- a/runtime/platform/sysctl.c
> +++ b/runtime/platform/sysctl.c
> @@ -12,7 +12,7 @@ size_t GC_pageSize (void) {
> }
> 
> size_t GC_totalRam (void) {
> -  int physMem;
> +  size_t physMem;
>   size_t len;
>   int mib[2];
> ----
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> MLton mailing list
> MLton at mlton.org
> http://mlton.org/mailman/listinfo/mlton




More information about the MLton mailing list