[MLton-commit] r6401

Matthew Fluet fluet at mlton.org
Wed Feb 13 21:08:04 PST 2008


Integrate Wesley Teprstra's address space patch:

 On AMD64, not all 64 bits are actually accessible to userspace
 applications. The CPU itself has a limit well below this, and win64
 imposes further a limit of 43 bits. This would be academic except that
 MLton carefully tries to position its heap by trying to map at 32
 locations linearly across the address space. Since all of the attempted
 address are larger than the maximum possible in 43 bits, this fails. On
 linux the failure is not so important because mmap(0) succeeds. However,
 this code has a purpose: to prevent fragmentation. In the distant future,
 this might matter again.

 The attached patch fixes this by introducing POINTER_BITS and
 ADDRESS_BITS (which is less than POINTER_BITS). POINTER_BITS is the
 number of bits in a pointer, and ADDRESS_BITS is how many of those are
 actually useful as an address. Also, checking the value of UINTPTR_MAX
 with UINT64_MAX is a preprocessor friendly and portable way to configure
 POINTER_BITS (the old code used a non-portable __WORDSIZE).

Some changes from the original patch:
 * use COMPILE_TIME_ASSERT in cenv.h to validate POINTER_BITS and
   ADDRESS_BITS, rather than assert in gen-sizes.c.
 * only win64 limits user mode virtual memory addresses to 43bits;
   linux allows user mode virtual memory addresses to be 48bits;
   I'm not sure about other OSes, and gave them 40bits (won't make a
   practical difference).


----------------------------------------------------------------------

U   mlton/trunk/runtime/cenv.h
U   mlton/trunk/runtime/gc/heap.c
U   mlton/trunk/runtime/gc/model.h
U   mlton/trunk/runtime/gc.h
U   mlton/trunk/runtime/platform/amd64.h
U   mlton/trunk/runtime/util/pointer.h

----------------------------------------------------------------------

Modified: mlton/trunk/runtime/cenv.h
===================================================================
--- mlton/trunk/runtime/cenv.h	2008-02-14 04:53:11 UTC (rev 6400)
+++ mlton/trunk/runtime/cenv.h	2008-02-14 05:08:02 UTC (rev 6401)
@@ -116,6 +116,20 @@
 #error unknown platform arch
 #endif
 
+#ifndef POINTER_BITS
+#if UINTPTR_MAX == UINT32_MAX
+#define POINTER_BITS 32
+#elif UINTPTR_MAX == UINT64_MAX
+#define POINTER_BITS 64
+#else
+#error Platform did not set POINTER_BITS and could not guess it.
+#endif
+#endif
+
+#ifndef ADDRESS_BITS
+#define ADDRESS_BITS POINTER_BITS
+#endif
+
 #include "gmp.h"
 
 COMPILE_TIME_ASSERT(sizeof_uintptr_t__is__sizeof_voidStar, 
@@ -124,5 +138,9 @@
                     sizeof(uintptr_t) == sizeof(size_t));
 COMPILE_TIME_ASSERT(sizeof_uintptr_t__is__sizeof_ptrdiff_t, 
                     sizeof(uintptr_t) == sizeof(ptrdiff_t));
+COMPILE_TIME_ASSERT(sizeof_voidStar__is__pointer_bits,
+                    sizeof(void*)*CHAR_BIT == POINTER_BITS);
+COMPILE_TIME_ASSERT(address_bits__lte__pointer_bits,
+                    ADDRESS_BITS <= POINTER_BITS);
 
 #endif /* _MLTON_CENV_H_ */

Modified: mlton/trunk/runtime/gc/heap.c
===================================================================
--- mlton/trunk/runtime/gc/heap.c	2008-02-14 04:53:11 UTC (rev 6400)
+++ mlton/trunk/runtime/gc/heap.c	2008-02-14 05:08:02 UTC (rev 6401)
@@ -171,7 +171,12 @@
   for (h->size = desiredSize; h->size >= minSize; h->size -= backoff) {
     const unsigned int countLog2 = 5;
     const unsigned int count = 0x1 << countLog2;
-    const size_t step = (size_t)0x1 << ((POINTER_SIZE * CHAR_BIT) - countLog2);
+    const size_t step = (size_t)0x1 << (ADDRESS_BITS - countLog2);
+#if ADDRESS_BITS == POINTER_BITS
+    const size_t address_end = 0;
+#else
+    const size_t address_end = (size_t)0x1 << ADDRESS_BITS;
+#endif
 
     static bool direction = TRUE;
     unsigned int i;
@@ -182,7 +187,11 @@
 
       address = (size_t)i * step;
       if (direction)
-        address = (size_t)0x0 - address;
+        address = address_end - address;
+      /* Always use 0 in the last step. */
+      if (i == count)
+        address = 0;
+
       h->start = GC_mmapAnon ((pointer)address, h->size);
       if ((void*)-1 == h->start)
         h->start = (void*)NULL;

Modified: mlton/trunk/runtime/gc/model.h
===================================================================
--- mlton/trunk/runtime/gc/model.h	2008-02-14 04:53:11 UTC (rev 6400)
+++ mlton/trunk/runtime/gc/model.h	2008-02-14 05:08:02 UTC (rev 6401)
@@ -150,7 +150,7 @@
 #define GC_MODEL_HEADER_SIZE 64
 #define GC_MODEL_ARRLEN_SIZE 64
 #else
-#error GC_MODEL_* unspecified
+#error GC_MODEL_* undefined
 #endif
 
 #define GC_MODEL_MINALIGN_SHIFT max(2, GC_MODEL_OBJPTR_SHIFT + 1)

Modified: mlton/trunk/runtime/gc.h
===================================================================
--- mlton/trunk/runtime/gc.h	2008-02-14 04:53:11 UTC (rev 6400)
+++ mlton/trunk/runtime/gc.h	2008-02-14 05:08:02 UTC (rev 6401)
@@ -15,19 +15,13 @@
 typedef struct GC_state *GC_state;
 typedef GC_state GCState_t;
 
-#if defined(__WORDSIZE)
-#if __WORDSIZE == 32
+#if POINTER_BITS == 32
 #define GC_MODEL_NATIVE32
-#elif __WORDSIZE == 64
+#elif POINTER_BITS == 64
 #define GC_MODEL_NATIVE64
 #else
-#error unknown __WORDSIZE
+#error POINTER_BITS not defined
 #endif
-#elif defined(__LP64__)
-#define GC_MODEL_NATIVE64
-#else
-#define GC_MODEL_NATIVE32
-#endif
 
 #include "gc/debug.h"
 

Modified: mlton/trunk/runtime/platform/amd64.h
===================================================================
--- mlton/trunk/runtime/platform/amd64.h	2008-02-14 04:53:11 UTC (rev 6400)
+++ mlton/trunk/runtime/platform/amd64.h	2008-02-14 05:08:02 UTC (rev 6401)
@@ -1 +1,10 @@
 #define MLton_Platform_Arch_host "amd64"
+
+#define POINTER_BITS 64
+#if (defined (__CYGWIN__) || defined (__MINGW32__))
+#define ADDRESS_BITS 43
+#elif (defined (__linux__))
+#define ADDRESS_BITS 48
+#else
+#define ADDRESS_BITS 40
+#endif

Modified: mlton/trunk/runtime/util/pointer.h
===================================================================
--- mlton/trunk/runtime/util/pointer.h	2008-02-14 04:53:11 UTC (rev 6400)
+++ mlton/trunk/runtime/util/pointer.h	2008-02-14 05:08:02 UTC (rev 6401)
@@ -11,19 +11,12 @@
 typedef unsigned char pointerAux __attribute__ ((aligned (4), may_alias));
 typedef pointerAux* pointer;
 
-#define POINTER_SIZE sizeof(pointer)
-#if defined(__WORDSIZE)
-#if __WORDSIZE == 32
+#if POINTER_BITS == 32
 #define FMTPTR "0x%08"PRIxPTR
-#elif __WORDSIZE == 64
+#elif POINTER_BITS == 64
 #define FMTPTR "0x%016"PRIxPTR
 #else
-#error __WORDSIZE unknown
+#error POINTER_BITS undefined
 #endif
-#elif defined(__LP64__)
-#define FMTPTR "0x%016"PRIxPTR
-#else
-#define FMTPTR "0x%08"PRIxPTR
-#endif
 
 typedef const unsigned char* code_pointer;




More information about the MLton-commit mailing list