Fix a bug which sometimes caused extra major GCs to be performed
[ghc-hetmet.git] / rts / Linker.c
index 2119262..f701377 100644 (file)
@@ -224,6 +224,7 @@ typedef struct _RtsSymbolVal {
 
 #if !defined(PAR)
 #define Maybe_Stable_Names      SymI_HasProto(mkWeakzh_fast)                   \
+                               SymI_HasProto(mkWeakForeignEnvzh_fast)          \
                                SymI_HasProto(makeStableNamezh_fast)            \
                                SymI_HasProto(finalizzeWeakzh_fast)
 #else
@@ -492,7 +493,9 @@ typedef struct _RtsSymbolVal {
 
 #if !defined(mingw32_HOST_OS)
 #define RTS_USER_SIGNALS_SYMBOLS \
-   SymI_HasProto(setIOManagerPipe)
+   SymI_HasProto(setIOManagerPipe) \
+   SymI_NeedsProto(blockUserSignals) \
+   SymI_NeedsProto(unblockUserSignals)
 #else
 #define RTS_USER_SIGNALS_SYMBOLS     \
    SymI_HasProto(sendIOManagerEvent) \
@@ -689,6 +692,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(noDuplicatezh_fast)                        \
       SymI_HasProto(atomicModifyMutVarzh_fast)         \
       SymI_HasProto(newPinnedByteArrayzh_fast)         \
+      SymI_HasProto(newAlignedPinnedByteArrayzh_fast)  \
       SymI_HasProto(newSpark)                          \
       SymI_HasProto(orIntegerzh_fast)                  \
       SymI_HasProto(performGC)                         \
@@ -855,6 +859,7 @@ typedef struct _RtsSymbolVal {
       SymI_NeedsProto(rts_stop_on_exception)           \
       SymI_HasProto(stopTimer)                         \
       SymI_HasProto(n_capabilities)                    \
+      SymI_HasProto(traceCcszh_fast)                    \
       RTS_USER_SIGNALS_SYMBOLS
 
 #ifdef SUPPORT_LONG_LONGS
@@ -1302,6 +1307,7 @@ mmapForLinker (size_t bytes, nat flags, int fd)
    void *map_addr = NULL;
    void *result;
    int pagesize, size;
+   static nat fixed = 0;
 
    pagesize = getpagesize();
    size = ROUND_UP(bytes, pagesize);
@@ -1315,10 +1321,11 @@ mmap_again:
 #endif
 
    result = mmap(map_addr, size, PROT_EXEC|PROT_READ|PROT_WRITE,
-                   MAP_PRIVATE|TRY_MAP_32BIT|flags, fd, 0);
+                   MAP_PRIVATE|TRY_MAP_32BIT|fixed|flags, fd, 0);
 
    if (result == MAP_FAILED) {
-       sysErrorBelch("mmap");
+       sysErrorBelch("mmap %lu bytes at %p",(lnat)size,map_addr);
+       errorBelch("Try specifying an address with +RTS -xm<addr> -RTS");
        stg_exit(EXIT_FAILURE);
    }
    
@@ -1329,8 +1336,16 @@ mmap_again:
        } else {
            if ((W_)result > 0x80000000) {
                // oops, we were given memory over 2Gb
-               // ... try allocating memory somewhere else?;
-               barf("loadObj: failed to mmap() memory below 2Gb; asked for %lu bytes at %p, got %p.  Try specifying an address with +RTS -xm<addr> -RTS", size, map_addr, result);
+#if defined(freebsd_HOST_OS)
+               // Some platforms require MAP_FIXED.  This is normally
+               // a bad idea, because MAP_FIXED will overwrite
+               // existing mappings.
+               munmap(result,size);
+               fixed = MAP_FIXED;
+               goto mmap_again;
+#else
+               barf("loadObj: failed to mmap() memory below 2Gb; asked for %lu bytes at %p.  Try specifying an address with +RTS -xm<addr> -RTS", size, map_addr, result);
+#endif
            } else {
                // hmm, we were given memory somewhere else, but it's
                // still under 2Gb so we can use it.  Next time, ask
@@ -1733,7 +1748,7 @@ static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
     if( m > n ) // we need to allocate more pages
     {
         oc->symbol_extras = mmapForLinker(sizeof(SymbolExtra) * count, 
-                                          MAP_ANONYMOUS, 0);
+                                          MAP_ANONYMOUS, -1);
     }
     else
     {