Index: head/lang/ghc/Makefile =================================================================== --- head/lang/ghc/Makefile +++ head/lang/ghc/Makefile @@ -3,7 +3,6 @@ PORTNAME= ghc PORTVERSION= ${GHC_VERSION} -PORTREVISION= 1 CATEGORIES= lang haskell MASTER_SITES= http://www.haskell.org/ghc/dist/${PORTVERSION}/:source \ LOCAL/arrowd/:boot \ @@ -21,279 +20,12 @@ ONLY_FOR_ARCHS= aarch64 amd64 armv6 armv7 i386 -GHC_VERSION= 8.4.3 +GHC_VERSION= 8.4.4 HSCOLOUR_VERSION= 1.24.4 +LLVM_VERSION= 50 -DATADIR= ${PREFIX}/share/ghc-${GHC_VERSION} -EXAMPLESDIR= ${PREFIX}/share/examples/ghc-${GHC_VERSION} +CONFLICTS_INSTALL= ghc-7.4.* ghc-7.6.* ghc-7.8.* ghc-7.10.* ghc-8.0.* ghc-8.4.3 -CONFLICTS= ghc-7.4.* ghc-7.6.* ghc-7.8.* ghc-7.10.* ghc-8.0.* +.include "${.CURDIR}/../../lang/ghc/bsd.ghc.mk" -LIB_DEPENDS+= libgmp.so:math/gmp - -USES= autoreconf gmake iconv:translit localbase:ldflags ncurses perl5 tar:xz -USE_LOCALE= en_US.UTF-8 -USE_PERL5= build -NO_CCACHE= ccache: error: Failed to create directory /nonexistent/.ccache/tmp: Permission denied - -# The configure process accepts,filters and canonicalises -# the CONFIGURE_TARGET variable. You can read the files -# ${WRKSRC}/configure and ${WRKSRC}/config.sub. -# This is better fixed in files/build.mk.in -GNU_CONFIGURE= yes - -CONFIGURE_ARGS= --with-gmp-includes=${LOCALBASE}/include \ - --with-gmp-libraries=${LOCALBASE}/lib \ - --with-iconv-includes=${LOCALBASE}/include \ - --with-iconv-libraries=${LOCALBASE}/lib - -SUB_FILES= build.mk \ - build.boot.mk -SUB_LIST= GHC_VERSION=${GHC_VERSION} \ - NCURSESINC="${NCURSESBASE}/include" NCURSESLIB="${NCURSESLIB}" \ - CFLAGS="${CFLAGS}" - -OPTIONS_GROUP= BOOTSTRAP -BOOTSTRAP_DESC= Bootsrap using installed ghc -OPTIONS_GROUP_BOOTSTRAP=BOOT -OPTIONS_DEFINE= DYNAMIC PROFILE DOCS -OPTIONS_SUB= yes - -OPTIONS_DEFAULT= PROFILE DYNAMIC -# ghci segfaults on arm when dynamic linking is used -OPTIONS_EXCLUDE_armv6= DYNAMIC -OPTIONS_EXCLUDE_armv7= DYNAMIC -OPTIONS_EXCLUDE_aarch64= DYNAMIC - -BOOT_DESC= Use installed GHC for bootstrapping -PROFILE_DESC= Add support for performance profiling -DYNAMIC_DESC= Add support for dynamic linking -DOCS_DESC= Install HTML documentation - -DYNAMIC_CONFIGURE_ARGS= --with-system-libffi \ - --with-ffi-includes=${LOCALBASE}/include \ - --with-ffi-libraries=${LOCALBASE}/lib -# The version number is needed as lang/gcc installs a different version -DYNAMIC_LIB_DEPENDS= libffi.so.6:devel/libffi - -# Append substitutions for build.mk -BOOT_SUB_LIST= HSC2HS=${LOCALBASE}/bin/hsc2hs -BOOT_SUB_LIST_OFF= HSC2HS=${BOOT_HSC2HS} - -DOCS_BUILD_DEPENDS+= sphinx-build:textproc/py-sphinx - -DYNAMIC_SUB_LIST= WITH_DYNAMIC="YES" -DYNAMIC_SUB_LIST_OFF= WITH_DYNAMIC="NO" - -PROFILE_SUB_LIST= WITH_PROFILE="YES" -PROFILE_SUB_LIST_OFF= WITH_PROFILE="NO" - -DOCS_SUB_LIST= WITH_DOCS="YES" -DOCS_SUB_LIST_OFF= WITH_DOCS="NO" - -LOCALBASE?= /usr/local - -.include - -.if empty(PORT_OPTIONS:MBOOT) -BOOT_GHC_VERSION= 8.4.2 -DISTFILES+= ghc-${BOOT_GHC_VERSION}-boot-${ARCH}-freebsd${EXTRACT_SUFX}:boot -.endif # MBOOT - -.if ${ARCH} == aarch64 || ${ARCH} == armv6 || ${ARCH} == armv7 -# CONFIGURE_TARGET must to be the same as the llvm triple -CONFIGURE_TARGET= ${ARCH}-unknown-freebsd${"${ARCH:Maarch64}" != "":?:-gnueabihf} -EXTRA_PATCHES+= ${PATCHDIR}/extra-patch-aclocal.m4 -BUILD_DEPENDS+= ld.gold:devel/binutils \ - llc50:devel/llvm50 -RUN_DEPENDS+= ld.gold:devel/binutils \ - llc50:devel/llvm50 -USE_GCC= yes -CONFIGURE_ENV+= OPT=opt50 LLC=llc50 - -. if ${OSVERSION} < 1200064 -IGNORE= lang/ghc on ARM requires at least __FreeBSD_version 1200064 -. endif - -. ifdef QEMU_EMULATING -IGNORE= qemu-user-static isn't able to build lang/ghc, but it builds fine on a real hardware -. endif -.endif - -# Turn off for a while, see PR 228727 -CONFIGURE_ARGS+= --enable-dtrace=0 -.if ${OSVERSION} < 1200000 -USE_GCC= yes -.else -LD= ld.bfd -.endif -CONFIGURE_ENV+= CC=${CC} LD=${LD} - -DOCSDIR= ${PREFIX}/share/doc/${DISTNAME} -GHC_LIBDIR= ${STAGEDIR}${PREFIX}/lib/ghc-${GHC_VERSION} -GHC_LIBDIR_REL= lib/ghc-${GHC_VERSION} - -PLIST_SUB+= GHC_VERSION=${GHC_VERSION} GHC_LIBDIR=${GHC_LIBDIR_REL} - -HACKAGE_SITE?= http://hackage.haskell.org/package/ - -.if empty(PORT_OPTIONS:MBOOT) -BOOT_DIR= ${WRKDIR}/ghc-${BOOT_GHC_VERSION}-boot -BOOT_GHC= ${BOOT_DIR}/bin/ghc-${BOOT_GHC_VERSION} -BOOT_GHC-PKG= ${BOOT_DIR}/bin/ghc-pkg-${BOOT_GHC_VERSION} -BOOT_HSC2HS= ${BOOT_DIR}/bin/hsc2hs - -SLAVE_CMD= ${SETENV} PATH=${BOOT_DIR}/bin:${PATH} - -CONFIGURE_ARGS_BOOT+= --prefix=${BOOT_DIR} -CONFIGURE_ARGS+= --with-ghc=${BOOT_GHC} -.else # MBOOT -SLAVE_CMD= # empty -CONFIGURE_ARGS+= --with-ghc=${LOCALBASE}/bin/ghc -.endif # MBOOT - -# override TMPDIR because /tmp often doesn't have enough space -# to build some of the larger libraries. -TMPDIR= ${WRKSRC}/tmp - -# Defining with documentation: -# An in place installation and registration of hscolour will be -# activated. In this way it's possible to use it directly into -# the build tree, without needing to install it. At the end -# you could view the output of: ${BOOT_GHC} describe hscolour - -SLAVES_PREFIX= ${WRKDIR}/slaves_prefix -SLAVES_WRKDIRPREFIX= ${WRKDIR}/slaves_wrkdirprefix - -MAKE_ENV+= PATH=${SLAVES_PREFIX}/bin:${PATH} -CONFIGURE_ENV+= PATH=${SLAVES_PREFIX}/bin:${PATH} - -post-extract: -# don't use the "wrap" trick on arches that use post-ino64 bootstrap binaries (arm*) -.if empty(PORT_OPTIONS:MBOOT) && ${OPSYS} == FreeBSD && ${OSVERSION} >= 1200031 && \ - ${ARCH} != aarch64 && ${ARCH} != armv6 && ${ARCH} != armv7 - @${REINPLACE_CMD} -e 's|@SettingsCCompilerLinkFlags@|& -Wl,--wrap=readdir_r,--wrap=stat,--wrap=lstat,--wrap=fstat,--wrap=mknod|' ${BOOT_DIR}/settings.in -.endif - -# %%PORTDOCS%%%%DOCSDIR%%/html/libraries/doc-index-V.html -post-install-script: - ${FIND} -ds ${GHC_LIBDIR} -type f -print | ${SED} -E \ - -e 's,^${STAGEDIR}${PREFIX}/?,,' \ - -e '/^${GHC_LIBDIR:C/\//\\\//g}\/package.conf.d\/package\.cache/s|^|@comment |g' \ - >> ${TMPPLIST} - ${FIND} -ds ${STAGEDIR}${DOCSDIR} -type f -print | ${SED} -E \ - -e 's,^${STAGEDIR}${PREFIX}/?,,' \ - -e '/^${STAGEDIR:C/\//\\\//g}${DOCSDIR:C/\//\\\//g}\/html\/libraries\/doc-index-[^.]+\.html/s|^|@comment |g' \ - -e '/^${STAGEDIR:C/\//\\\//g}${DOCSDIR:C/\//\\\//g}\/html\/libraries\/index[^\/.]*\.html/s|^|@comment|g' \ - -e '/^${STAGEDIR:C/\//\\\//g}${DOCSDIR:C/\//\\\//g}\/html\/libraries\/[^\/]+\.png/s|^|@comment |g' \ - >> ${TMPPLIST} -.if ${PORT_OPTIONS:MDOCS} - # Cleanup the indexen created by gen_contents_index - ${ECHO} "@postunexec ${RM} %D/${DOCSDIR_REL}/html/libraries/doc-index-*.html" >> ${TMPPLIST} - ${ECHO} "@postunexec ${RM} %D/${DOCSDIR_REL}/html/libraries/index*.html" >> ${TMPPLIST} - ${ECHO} "@postunexec ${RM} %D/${DOCSDIR_REL}/html/libraries/*.png" >> ${TMPPLIST} -.endif - ${ECHO} '@postunexec ${RM} %D/${GHC_LIBDIR_REL}/package.conf.d/package.cache' >>${TMPPLIST} - ${ECHO} "@postexec %D/bin/ghc-pkg recache" >>${TMPPLIST} -.if ${PORT_OPTIONS:MDOCS} - ${ECHO} '@postexec ${SH} -c "cd %D/${DOCSDIR_REL}/html/libraries && ./gen_contents_index"' >> ${TMPPLIST} -.endif - -post-patch: - @${REINPLACE_CMD} -e 's|%%CC%%|${CC}|; \ - s|%%AR%%|${AR}|; \ - s|%%LD%%|${LD}|' \ - ${WRKSRC}/libraries/Cabal/Cabal/Distribution/Simple/Program/Builtin.hs -# we must use binutils:ld on arm -.if ${ARCH} == aarch64 || ${ARCH} == armv6 || ${ARCH} == armv7 - @${REINPLACE_CMD} -e 's|LD_NO_GOLD=ld|LD_NO_GOLD=${LOCALBASE}/bin/ld|' \ - ${WRKSRC}/aclocal.m4 -.endif - -.if empty(PORT_OPTIONS:MBOOT) - @${REINPLACE_CMD} -e '/^mandir/d' ${BOOT_DIR}/mk/build.mk - @${REINPLACE_CMD} -e '/^infodir/d' ${BOOT_DIR}/mk/build.mk - @${REINPLACE_CMD} -e '/^docdir/d' ${BOOT_DIR}/mk/build.mk - @${REINPLACE_CMD} -e '/^htmldir/d' ${BOOT_DIR}/mk/build.mk -.endif - -pre-configure: apply-slist - # Copy the subbed build.mk to the proper position - ${CP} ${WRKDIR}/build.mk ${WRKSRC}/mk/build.mk - - @${MKDIR} ${TMPDIR} -.if empty(PORT_OPTIONS:MBOOT) && ${OPSYS} == FreeBSD && \ - ${OSVERSION} >= 1200031 && \ - ${ARCH} != aarch64 && ${ARCH} != armv6 && ${ARCH} != armv7 - ${CC} ${CFLAGS} -c -o ${BOOT_DIR}/wrap.o ${PATCHDIR}/wrap.c - for x in ${BOOT_DIR}/rts/dist/build/libCffi*.a; do \ - ${AR} q $$x ${BOOT_DIR}/wrap.o; ${RANLIB} $$x; \ - done - rm ${BOOT_DIR}/wrap.o -.endif # Do not merge, prev condition need to grow OSVER check. -.if empty(PORT_OPTIONS:MBOOT) - @(cd ${BOOT_DIR} && ${CONFIGURE_ENV} ${CONFIGURE_CMD} ${CONFIGURE_ARGS_BOOT}) - @(cd ${BOOT_DIR} && PACKAGES='' ${MAKE_CMD} install) -.endif - -.if ${PORT_OPTIONS:MDOCS} - @${ECHO_MSG} -e "\a" - @${ECHO_MSG} "======================================================================" - @${ECHO_MSG} " WARNING: Now HsColour will be built, the respective port will not " - @${ECHO_MSG} " be installed, but an in-place installation and " - @${ECHO_MSG} " registration of both takes place. " - @${ECHO_MSG} "======================================================================" - @${ECHO_MSG} "" -. if !(defined(PACKAGE_BUILDING) || defined(BATCH)) - @sleep 3 -. endif - - @${MKDIR} ${SLAVES_PREFIX} - @${MKDIR} ${SLAVES_WRKDIRPREFIX} - - @(cd ${SLAVES_WRKDIRPREFIX} && \ - ${TAR} xvf ${DISTDIR}/hscolour-${HSCOLOUR_VERSION}.tar.gz && \ - cd hscolour-${HSCOLOUR_VERSION} && \ - ${SLAVE_CMD} ghc --make -o Setup Setup.hs -package Cabal && \ - ${SLAVE_CMD} ./Setup configure --ghc --prefix=${SLAVES_PREFIX} --with-gcc=${CC} --with-ld=${LD} && \ - ${SLAVE_CMD} ./Setup build && \ - ${SLAVE_CMD} ./Setup install) -.endif - -_EXECUTABLES= ${GHC_LIBDIR}/bin/unlit \ - ${GHC_LIBDIR}/bin/hpc \ - ${GHC_LIBDIR}/bin/ghc-iserv \ - ${GHC_LIBDIR}/bin/ghc-pkg \ - ${GHC_LIBDIR}/bin/hsc2hs \ - ${GHC_LIBDIR}/bin/runghc \ - ${GHC_LIBDIR}/bin/ghc \ - ${GHC_LIBDIR}/bin/hp2ps - -.if ${PORT_OPTIONS:MPROFILE} -_EXECUTABLES+= ${GHC_LIBDIR}/bin/ghc-iserv-prof -.endif -.if ${PORT_OPTIONS:MDYNAMIC} -_EXECUTABLES+= ${GHC_LIBDIR}/bin/ghc-iserv-dyn -.endif -.if ${PORT_OPTIONS:MDOCS} -_EXECUTABLES+= ${GHC_LIBDIR}/bin/haddock -.endif - -post-install: - ${RM} ${STAGEDIR}${PREFIX}/bin/haddock -.if ${PORT_OPTIONS:MDOCS} - ${LN} -sf haddock-ghc-${GHC_VERSION} ${STAGEDIR}${PREFIX}/bin/haddock -.endif - (for f in ${_EXECUTABLES} $$(${FIND} ${GHC_LIBDIR} -name '*.so*'); do \ - ${STRIP_CMD} $$f; done) - .include - -# Create a bootstrap compiler tar ball: run this in an interactive poudriere jail -.PHONY: create-bootstrap -create-bootstrap: - cd ${WRKSRC} \ - && gmake binary-dist TAR_COMP=xz \ - && mv ${WRKSRC}/ghc-${GHC_VERSION}-${ARCH}-portbld-freebsd.tar.xz /tmp/ghc-${GHC_VERSION}-boot-${ARCH}-freebsd.tar.xz - && sha256 ghc-${GHC_VERSION}-boot-${ARCH}-freebsd.tar.xz - && stat -f %z ghc-${GHC_VERSION}-boot-${ARCH}-freebsd.tar.xz Index: head/lang/ghc/bsd.cabal.options.mk =================================================================== --- head/lang/ghc/bsd.cabal.options.mk +++ head/lang/ghc/bsd.cabal.options.mk @@ -18,7 +18,7 @@ HADDOCK_CMD?= ${LOCALBASE}/bin/haddock HSCOLOUR_CMD?= ${LOCALBASE}/bin/HsColour -GHC_VERSION?= 8.4.3 +GHC_VERSION?= 8.4.4 HSCOLOUR_VERSION= 1.24.4 Index: head/lang/ghc/bsd.ghc.mk =================================================================== --- head/lang/ghc/bsd.ghc.mk +++ head/lang/ghc/bsd.ghc.mk @@ -0,0 +1,278 @@ +# $FreeBSD$ +# +# bsd.ghc.mk -- Common code for various versions of GHC ports. +# +# Maintained by: haskell@FreeBSD.org +# + +DATADIR= ${PREFIX}/share/ghc-${GHC_VERSION} +EXAMPLESDIR= ${PREFIX}/share/examples/ghc-${GHC_VERSION} + +LIB_DEPENDS+= libgmp.so:math/gmp + +USES= autoreconf gmake iconv:translit localbase:ldflags ncurses perl5 tar:xz +USE_LOCALE= en_US.UTF-8 +USE_PERL5= build +NO_CCACHE= ccache: error: Failed to create directory /nonexistent/.ccache/tmp: Permission denied + +# The configure process accepts,filters and canonicalises +# the CONFIGURE_TARGET variable. You can read the files +# ${WRKSRC}/configure and ${WRKSRC}/config.sub. +# This is better fixed in files/build.mk.in +GNU_CONFIGURE= yes + +CONFIGURE_ARGS= --with-gmp-includes=${LOCALBASE}/include \ + --with-gmp-libraries=${LOCALBASE}/lib \ + --with-iconv-includes=${LOCALBASE}/include \ + --with-iconv-libraries=${LOCALBASE}/lib + +SUB_FILES= build.mk \ + build.boot.mk +SUB_LIST= GHC_VERSION=${GHC_VERSION} \ + NCURSESINC="${NCURSESBASE}/include" NCURSESLIB="${NCURSESLIB}" \ + CFLAGS="${CFLAGS}" + +OPTIONS_GROUP= BOOTSTRAP +BOOTSTRAP_DESC= Bootsrap using installed ghc +OPTIONS_GROUP_BOOTSTRAP=BOOT +OPTIONS_DEFINE= DYNAMIC PROFILE DOCS +OPTIONS_SUB= yes + +OPTIONS_DEFAULT= PROFILE DYNAMIC +# ghci segfaults on arm when dynamic linking is used +OPTIONS_EXCLUDE_armv6= DYNAMIC +OPTIONS_EXCLUDE_armv7= DYNAMIC +OPTIONS_EXCLUDE_aarch64= DYNAMIC + +BOOT_DESC= Use installed GHC for bootstrapping +PROFILE_DESC= Add support for performance profiling +DYNAMIC_DESC= Add support for dynamic linking +DOCS_DESC= Install HTML documentation + +DYNAMIC_CONFIGURE_ARGS= --with-system-libffi \ + --with-ffi-includes=${LOCALBASE}/include \ + --with-ffi-libraries=${LOCALBASE}/lib +# The version number is needed as lang/gcc installs a different version +DYNAMIC_LIB_DEPENDS= libffi.so.6:devel/libffi + +# Append substitutions for build.mk +BOOT_SUB_LIST= HSC2HS=${LOCALBASE}/bin/hsc2hs +BOOT_SUB_LIST_OFF= HSC2HS=${BOOT_HSC2HS} + +DOCS_BUILD_DEPENDS+= sphinx-build:textproc/py-sphinx + +DYNAMIC_SUB_LIST= WITH_DYNAMIC="YES" +DYNAMIC_SUB_LIST_OFF= WITH_DYNAMIC="NO" + +PROFILE_SUB_LIST= WITH_PROFILE="YES" +PROFILE_SUB_LIST_OFF= WITH_PROFILE="NO" + +DOCS_SUB_LIST= WITH_DOCS="YES" +DOCS_SUB_LIST_OFF= WITH_DOCS="NO" + +LOCALBASE?= /usr/local + +.include + +.if empty(PORT_OPTIONS:MBOOT) +BOOT_GHC_VERSION= 8.4.2 +DISTFILES+= ghc-${BOOT_GHC_VERSION}-boot-${ARCH}-freebsd${EXTRACT_SUFX}:boot +.endif # MBOOT + +.if ${ARCH} == aarch64 || ${ARCH} == armv6 || ${ARCH} == armv7 +# CONFIGURE_TARGET must to be the same as the llvm triple +CONFIGURE_TARGET= ${ARCH}-unknown-freebsd${"${ARCH:Maarch64}" != "":?:-gnueabihf} +EXTRA_PATCHES+= ${PATCHDIR}/extra-patch-aclocal.m4 +BUILD_DEPENDS+= ld.gold:devel/binutils \ + llc${LLVM_VERSION}:devel/llvm${LLVM_VERSION} +RUN_DEPENDS+= ld.gold:devel/binutils \ + llc${LLVM_VERSION}:devel/llvm${LLVM_VERSION} +USE_GCC= yes + +. if ${OSVERSION} < 1200064 +IGNORE= lang/ghc on ARM requires at least __FreeBSD_version 1200064 +. endif + +. ifdef QEMU_EMULATING +IGNORE= qemu-user-static isn't able to build lang/ghc, but it builds fine on a real hardware +. endif +.endif + +# Turn off for a while, see PR 228727 +CONFIGURE_ARGS+= --enable-dtrace=0 +.if ${OSVERSION} < 1200000 +USE_GCC= yes +.else +LD= ld.bfd +.endif +CONFIGURE_ENV+= CC=${CC} LD=${LD} + +DOCSDIR= ${PREFIX}/share/doc/${DISTNAME} +GHC_LIBDIR= ${STAGEDIR}${PREFIX}/lib/ghc-${GHC_VERSION} +GHC_LIBDIR_REL= lib/ghc-${GHC_VERSION} + +PLIST_SUB+= GHC_VERSION=${GHC_VERSION} GHC_LIBDIR=${GHC_LIBDIR_REL} + +HACKAGE_SITE?= http://hackage.haskell.org/package/ + +.if empty(PORT_OPTIONS:MBOOT) +BOOT_DIR= ${WRKDIR}/ghc-${BOOT_GHC_VERSION}-boot +BOOT_GHC= ${BOOT_DIR}/bin/ghc-${BOOT_GHC_VERSION} +BOOT_GHC-PKG= ${BOOT_DIR}/bin/ghc-pkg-${BOOT_GHC_VERSION} +BOOT_HSC2HS= ${BOOT_DIR}/bin/hsc2hs + +SLAVE_CMD= ${SETENV} PATH=${BOOT_DIR}/bin:${PATH} + +CONFIGURE_ARGS_BOOT+= --prefix=${BOOT_DIR} +CONFIGURE_ARGS+= --with-ghc=${BOOT_GHC} +.else # MBOOT +SLAVE_CMD= # empty +CONFIGURE_ARGS+= --with-ghc=${LOCALBASE}/bin/ghc +.endif # MBOOT + +# override TMPDIR because /tmp often doesn't have enough space +# to build some of the larger libraries. +TMPDIR= ${WRKSRC}/tmp + +# Defining with documentation: +# An in place installation and registration of hscolour will be +# activated. In this way it's possible to use it directly into +# the build tree, without needing to install it. At the end +# you could view the output of: ${BOOT_GHC} describe hscolour + +SLAVES_PREFIX= ${WRKDIR}/slaves_prefix +SLAVES_WRKDIRPREFIX= ${WRKDIR}/slaves_wrkdirprefix + +MAKE_ENV+= PATH=${SLAVES_PREFIX}/bin:${PATH} +CONFIGURE_ENV+= PATH=${SLAVES_PREFIX}/bin:${PATH} + +post-extract: +# don't use the "wrap" trick on arches that use post-ino64 bootstrap binaries (arm*) +.if empty(PORT_OPTIONS:MBOOT) && ${OPSYS} == FreeBSD && ${OSVERSION} >= 1200031 && \ + ${ARCH} != aarch64 && ${ARCH} != armv6 && ${ARCH} != armv7 + @${REINPLACE_CMD} -e 's|@SettingsCCompilerLinkFlags@|& -Wl,--wrap=readdir_r,--wrap=stat,--wrap=lstat,--wrap=fstat,--wrap=mknod|' ${BOOT_DIR}/settings.in +.endif + +# %%PORTDOCS%%%%DOCSDIR%%/html/libraries/doc-index-V.html +post-install-script: + ${FIND} -ds ${GHC_LIBDIR} -type f -print | ${SED} -E \ + -e 's,^${STAGEDIR}${PREFIX}/?,,' \ + -e '/^${GHC_LIBDIR:C/\//\\\//g}\/package.conf.d\/package\.cache/s|^|@comment |g' \ + >> ${TMPPLIST} + ${FIND} -ds ${STAGEDIR}${DOCSDIR} -type f -print | ${SED} -E \ + -e 's,^${STAGEDIR}${PREFIX}/?,,' \ + -e '/^${STAGEDIR:C/\//\\\//g}${DOCSDIR:C/\//\\\//g}\/html\/libraries\/doc-index-[^.]+\.html/s|^|@comment |g' \ + -e '/^${STAGEDIR:C/\//\\\//g}${DOCSDIR:C/\//\\\//g}\/html\/libraries\/index[^\/.]*\.html/s|^|@comment|g' \ + -e '/^${STAGEDIR:C/\//\\\//g}${DOCSDIR:C/\//\\\//g}\/html\/libraries\/[^\/]+\.png/s|^|@comment |g' \ + >> ${TMPPLIST} +.if ${PORT_OPTIONS:MDOCS} + # Cleanup the indexen created by gen_contents_index + ${ECHO} "@postunexec ${RM} %D/${DOCSDIR_REL}/html/libraries/doc-index-*.html" >> ${TMPPLIST} + ${ECHO} "@postunexec ${RM} %D/${DOCSDIR_REL}/html/libraries/index*.html" >> ${TMPPLIST} + ${ECHO} "@postunexec ${RM} %D/${DOCSDIR_REL}/html/libraries/*.png" >> ${TMPPLIST} +.endif + ${ECHO} '@postunexec ${RM} %D/${GHC_LIBDIR_REL}/package.conf.d/package.cache' >>${TMPPLIST} + ${ECHO} "@postexec %D/bin/ghc-pkg recache" >>${TMPPLIST} +.if ${PORT_OPTIONS:MDOCS} + ${ECHO} '@postexec ${SH} -c "cd %D/${DOCSDIR_REL}/html/libraries && ./gen_contents_index"' >> ${TMPPLIST} +.endif + +post-patch: + @${REINPLACE_CMD} -e 's|%%CC%%|${CC}|; \ + s|%%AR%%|${AR}|; \ + s|%%LD%%|${LD}|' \ + ${WRKSRC}/libraries/Cabal/Cabal/Distribution/Simple/Program/Builtin.hs +# we must use binutils:ld on arm +.if ${ARCH} == aarch64 || ${ARCH} == armv6 || ${ARCH} == armv7 + @${REINPLACE_CMD} -e 's|LD_NO_GOLD=ld|LD_NO_GOLD=${LOCALBASE}/bin/ld|' \ + ${WRKSRC}/aclocal.m4 +.endif + + @${REINPLACE_CMD} -e 's/@SettingsLlcCommand@/llc${LLVM_VERSION}/' ${WRKSRC}/settings.in + @${REINPLACE_CMD} -e 's/@SettingsOptCommand@/opt${LLVM_VERSION}/' ${WRKSRC}/settings.in + +.if empty(PORT_OPTIONS:MBOOT) + @${REINPLACE_CMD} -e '/^mandir/d' ${BOOT_DIR}/mk/build.mk + @${REINPLACE_CMD} -e '/^infodir/d' ${BOOT_DIR}/mk/build.mk + @${REINPLACE_CMD} -e '/^docdir/d' ${BOOT_DIR}/mk/build.mk + @${REINPLACE_CMD} -e '/^htmldir/d' ${BOOT_DIR}/mk/build.mk +.endif + +pre-configure: apply-slist + # Copy the subbed build.mk to the proper position + ${CP} ${WRKDIR}/build.mk ${WRKSRC}/mk/build.mk + + @${MKDIR} ${TMPDIR} +.if empty(PORT_OPTIONS:MBOOT) && ${OPSYS} == FreeBSD && \ + ${OSVERSION} >= 1200031 && \ + ${ARCH} != aarch64 && ${ARCH} != armv6 && ${ARCH} != armv7 + ${CC} ${CFLAGS} -c -o ${BOOT_DIR}/wrap.o ${PATCHDIR}/wrap.c + for x in ${BOOT_DIR}/rts/dist/build/libCffi*.a; do \ + ${AR} q $$x ${BOOT_DIR}/wrap.o; ${RANLIB} $$x; \ + done + rm ${BOOT_DIR}/wrap.o +.endif # Do not merge, prev condition need to grow OSVER check. +.if empty(PORT_OPTIONS:MBOOT) + @(cd ${BOOT_DIR} && ${CONFIGURE_ENV} ${CONFIGURE_CMD} ${CONFIGURE_ARGS_BOOT}) + @(cd ${BOOT_DIR} && PACKAGES='' ${MAKE_CMD} install) +.endif + +.if ${PORT_OPTIONS:MDOCS} + @${ECHO_MSG} -e "\a" + @${ECHO_MSG} "======================================================================" + @${ECHO_MSG} " WARNING: Now HsColour will be built, the respective port will not " + @${ECHO_MSG} " be installed, but an in-place installation and " + @${ECHO_MSG} " registration of both takes place. " + @${ECHO_MSG} "======================================================================" + @${ECHO_MSG} "" +. if !(defined(PACKAGE_BUILDING) || defined(BATCH)) + @sleep 3 +. endif + + @${MKDIR} ${SLAVES_PREFIX} + @${MKDIR} ${SLAVES_WRKDIRPREFIX} + + @(cd ${SLAVES_WRKDIRPREFIX} && \ + ${TAR} xvf ${DISTDIR}/hscolour-${HSCOLOUR_VERSION}.tar.gz && \ + cd hscolour-${HSCOLOUR_VERSION} && \ + ${SLAVE_CMD} ghc --make -o Setup Setup.hs -package Cabal && \ + ${SLAVE_CMD} ./Setup configure --ghc --prefix=${SLAVES_PREFIX} --with-gcc=${CC} --with-ld=${LD} && \ + ${SLAVE_CMD} ./Setup build && \ + ${SLAVE_CMD} ./Setup install) +.endif + +_EXECUTABLES= ${GHC_LIBDIR}/bin/unlit \ + ${GHC_LIBDIR}/bin/hpc \ + ${GHC_LIBDIR}/bin/ghc-iserv \ + ${GHC_LIBDIR}/bin/ghc-pkg \ + ${GHC_LIBDIR}/bin/hsc2hs \ + ${GHC_LIBDIR}/bin/runghc \ + ${GHC_LIBDIR}/bin/ghc \ + ${GHC_LIBDIR}/bin/hp2ps + +.if ${PORT_OPTIONS:MPROFILE} +_EXECUTABLES+= ${GHC_LIBDIR}/bin/ghc-iserv-prof +.endif +.if ${PORT_OPTIONS:MDYNAMIC} +_EXECUTABLES+= ${GHC_LIBDIR}/bin/ghc-iserv-dyn +.endif +.if ${PORT_OPTIONS:MDOCS} +_EXECUTABLES+= ${GHC_LIBDIR}/bin/haddock +.endif + +post-install: + ${RM} ${STAGEDIR}${PREFIX}/bin/haddock +.if ${PORT_OPTIONS:MDOCS} + ${LN} -sf haddock-ghc-${GHC_VERSION} ${STAGEDIR}${PREFIX}/bin/haddock +.endif + (for f in ${_EXECUTABLES} $$(${FIND} ${GHC_LIBDIR} -name '*.so*'); do \ + ${STRIP_CMD} $$f; done) + +# Create a bootstrap compiler tar ball: run this in an interactive poudriere jail +.PHONY: create-bootstrap +create-bootstrap: + cd ${WRKSRC} \ + && gmake binary-dist TAR_COMP=xz \ + && mv ${WRKSRC}/ghc-${GHC_VERSION}-${ARCH}-portbld-freebsd.tar.xz /tmp/ghc-${GHC_VERSION}-boot-${ARCH}-freebsd.tar.xz + && sha256 ghc-${GHC_VERSION}-boot-${ARCH}-freebsd.tar.xz + && stat -f %z ghc-${GHC_VERSION}-boot-${ARCH}-freebsd.tar.xz Index: head/lang/ghc/distinfo =================================================================== --- head/lang/ghc/distinfo +++ head/lang/ghc/distinfo @@ -1,6 +1,6 @@ -TIMESTAMP = 1530033471 -SHA256 (ghc-8.4.3-src.tar.xz) = ae47afda985830de8811243255aa3744dfb9207cb980af74393298b2b62160d6 -SIZE (ghc-8.4.3-src.tar.xz) = 11315068 +TIMESTAMP = 1541010521 +SHA256 (ghc-8.4.4-src.tar.xz) = 11117735a58e507c481c09f3f39ae5a314e9fbf49fc3109528f99ea7959004b2 +SIZE (ghc-8.4.4-src.tar.xz) = 11319500 SHA256 (ghc-8.4.2-boot-amd64-freebsd.tar.xz) = 8fe44700c0b765b38a2072c8ea9ddb1da18b4a738397c9ceddcce80708900e4f SIZE (ghc-8.4.2-boot-amd64-freebsd.tar.xz) = 72751016 SHA256 (ghc-8.4.2-boot-i386-freebsd.tar.xz) = 673230735fc459a3c05cf845ef7beeeb6eab9576bc03471b9fb50bd3fe29d911 Index: head/lang/ghc/files/patch-configure.ac =================================================================== --- head/lang/ghc/files/patch-configure.ac +++ head/lang/ghc/files/patch-configure.ac @@ -10,15 +10,3 @@ # If 'host' and 'target' differ, then this means we are building a cross-compiler. if test "$TargetPlatform" != "$HostPlatform" ; then CrossCompiling=YES -@@ -1163,6 +1158,11 @@ if test "$ac_cv_sizeof_void_p" -eq 8 ; t - # The flag MAP_NORESERVE is supported for source compatibility reasons, - # but is completely ignored by OS mmap - use_large_address_space=no -+ elif test "$ghc_host_os" = "freebsd" ; then -+ # FreeBSD does not support mmap with MAP_NORESERVE, removed in r273250. -+ # The flag MAP_NORESERVE is supported for source compatibility reasons, -+ # but is completely ignored by OS mmap -+ use_large_address_space=no - else - AC_CHECK_DECLS([MAP_NORESERVE, MADV_FREE, MADV_DONTNEED],[],[], - [ Index: head/lang/ghc/files/patch-fix-build-on-arm =================================================================== --- head/lang/ghc/files/patch-fix-build-on-arm +++ head/lang/ghc/files/patch-fix-build-on-arm @@ -0,0 +1,231 @@ +From d8495549ba9d194815c2d0eaee6797fc7c00756a Mon Sep 17 00:00:00 2001 +From: Kavon Farvardin +Date: Sun, 28 Oct 2018 12:11:49 -0400 +Subject: [PATCH] Fix for T14251 on ARM + +We now calculate the SSE register padding needed to fix the calling +convention in LLVM in a robust way: grouping them by whether +registers in that class overlap (with the same class overlapping +itself). + +My prior patch assumed that no matter the platform, physical +register Fx aliases with Dx, etc, for our calling convention. + +This is unfortunately not the case for any platform except x86-64. + +Test Plan: +Only know how to test on x86-64, but it should be tested on ARM with: + +`make test WAYS=llvm && make test WAYS=optllvm` + +Reviewers: bgamari, angerman + +Reviewed By: bgamari + +Subscribers: rwbarton, carter + +GHC Trac Issues: #15780, #14251, #15747 + +Differential Revision: https://phabricator.haskell.org/D5254 +--- + compiler/llvmGen/LlvmCodeGen/Base.hs | 123 ++++++++++++++++++++++---------- + compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 6 +- + 2 files changed, 90 insertions(+), 39 deletions(-) + +diff --git a/compiler/llvmGen/LlvmCodeGen/Base.hs b/compiler/llvmGen/LlvmCodeGen/Base.hs +index ec91bac..0a40b73 100644 +--- compiler/llvmGen/LlvmCodeGen/Base.hs ++++ compiler/llvmGen/LlvmCodeGen/Base.hs +@@ -26,7 +26,7 @@ module LlvmCodeGen.Base ( + + cmmToLlvmType, widthToLlvmFloat, widthToLlvmInt, llvmFunTy, + llvmFunSig, llvmFunArgs, llvmStdFunAttrs, llvmFunAlign, llvmInfAlign, +- llvmPtrBits, tysToParams, llvmFunSection, padLiveArgs, isSSE, ++ llvmPtrBits, tysToParams, llvmFunSection, padLiveArgs, isFPR, + + strCLabel_llvm, strDisplayName_llvm, strProcedureName_llvm, + getGlobalPtr, generateExternDecls, +@@ -47,6 +47,7 @@ import CodeGen.Platform ( activeStgRegs ) + import DynFlags + import FastString + import Cmm hiding ( succ ) ++import CmmUtils ( regsOverlap ) + import Outputable as Outp + import Platform + import UniqFM +@@ -58,8 +59,7 @@ import ErrUtils + import qualified Stream + + import Control.Monad (ap) +-import Data.List (sort) +-import Data.Maybe (mapMaybe) ++import Data.List (sort, groupBy, head) + + -- ---------------------------------------------------------------------------- + -- * Some Data Types +@@ -152,36 +152,91 @@ llvmFunArgs dflags live = + map (lmGlobalRegArg dflags) (filter isPassed allRegs) + where platform = targetPlatform dflags + allRegs = activeStgRegs platform +- paddedLive = map (\(_,r) -> r) $ padLiveArgs live ++ paddedLive = map (\(_,r) -> r) $ padLiveArgs dflags live + isLive r = r `elem` alwaysLive || r `elem` paddedLive +- isPassed r = not (isSSE r) || isLive r +- +- +-isSSE :: GlobalReg -> Bool +-isSSE (FloatReg _) = True +-isSSE (DoubleReg _) = True +-isSSE (XmmReg _) = True +-isSSE (YmmReg _) = True +-isSSE (ZmmReg _) = True +-isSSE _ = False +- +-sseRegNum :: GlobalReg -> Maybe Int +-sseRegNum (FloatReg i) = Just i +-sseRegNum (DoubleReg i) = Just i +-sseRegNum (XmmReg i) = Just i +-sseRegNum (YmmReg i) = Just i +-sseRegNum (ZmmReg i) = Just i +-sseRegNum _ = Nothing +- +--- the bool indicates whether the global reg was added as padding. +--- the returned list is not sorted in any particular order, +--- but does indicate the set of live registers needed, with SSE padding. +-padLiveArgs :: LiveGlobalRegs -> [(Bool, GlobalReg)] +-padLiveArgs live = allRegs ++ isPassed r = not (isFPR r) || isLive r ++ ++ ++isFPR :: GlobalReg -> Bool ++isFPR (FloatReg _) = True ++isFPR (DoubleReg _) = True ++isFPR (XmmReg _) = True ++isFPR (YmmReg _) = True ++isFPR (ZmmReg _) = True ++isFPR _ = False ++ ++sameFPRClass :: GlobalReg -> GlobalReg -> Bool ++sameFPRClass (FloatReg _) (FloatReg _) = True ++sameFPRClass (DoubleReg _) (DoubleReg _) = True ++sameFPRClass (XmmReg _) (XmmReg _) = True ++sameFPRClass (YmmReg _) (YmmReg _) = True ++sameFPRClass (ZmmReg _) (ZmmReg _) = True ++sameFPRClass _ _ = False ++ ++normalizeFPRNum :: GlobalReg -> GlobalReg ++normalizeFPRNum (FloatReg _) = FloatReg 1 ++normalizeFPRNum (DoubleReg _) = DoubleReg 1 ++normalizeFPRNum (XmmReg _) = XmmReg 1 ++normalizeFPRNum (YmmReg _) = YmmReg 1 ++normalizeFPRNum (ZmmReg _) = ZmmReg 1 ++normalizeFPRNum _ = error "normalizeFPRNum expected only FPR regs" ++ ++getFPRCtor :: GlobalReg -> Int -> GlobalReg ++getFPRCtor (FloatReg _) = FloatReg ++getFPRCtor (DoubleReg _) = DoubleReg ++getFPRCtor (XmmReg _) = XmmReg ++getFPRCtor (YmmReg _) = YmmReg ++getFPRCtor (ZmmReg _) = ZmmReg ++getFPRCtor _ = error "getFPRCtor expected only FPR regs" ++ ++fprRegNum :: GlobalReg -> Int ++fprRegNum (FloatReg i) = i ++fprRegNum (DoubleReg i) = i ++fprRegNum (XmmReg i) = i ++fprRegNum (YmmReg i) = i ++fprRegNum (ZmmReg i) = i ++fprRegNum _ = error "fprRegNum expected only FPR regs" ++ ++-- | Input: dynflags, and the list of live registers ++-- ++-- Output: An augmented list of live registers, where padding was ++-- added to the list of registers to ensure the calling convention is ++-- correctly used by LLVM. ++-- ++-- Each global reg in the returned list is tagged with a bool, which ++-- indicates whether the global reg was added as padding, or was an original ++-- live register. ++-- ++-- That is, True => padding, False => a real, live global register. ++-- ++-- Also, the returned list is not sorted in any particular order. ++-- ++padLiveArgs :: DynFlags -> LiveGlobalRegs -> [(Bool, GlobalReg)] ++padLiveArgs dflags live = ++ if platformUnregisterised plat ++ then taggedLive -- not using GHC's register convention for platform. ++ else padding ++ taggedLive ++ where ++ taggedLive = map (\x -> (False, x)) live ++ plat = targetPlatform dflags ++ ++ fprLive = filter isFPR live ++ padding = concatMap calcPad $ groupBy sharesClass fprLive ++ ++ sharesClass :: GlobalReg -> GlobalReg -> Bool ++ sharesClass a b = sameFPRClass a b || overlappingClass ++ where ++ overlappingClass = regsOverlap dflags (norm a) (norm b) ++ norm = CmmGlobal . normalizeFPRNum ++ ++ calcPad :: [GlobalReg] -> [(Bool, GlobalReg)] ++ calcPad rs = getFPRPadding (getFPRCtor $ head rs) rs ++ ++getFPRPadding :: (Int -> GlobalReg) -> LiveGlobalRegs -> [(Bool, GlobalReg)] ++getFPRPadding paddingCtor live = padding + where +- sseRegNums = sort $ mapMaybe sseRegNum live +- (_, padding) = foldl assignSlots (1, []) $ sseRegNums +- allRegs = padding ++ map (\r -> (False, r)) live ++ fprRegNums = sort $ map fprRegNum live ++ (_, padding) = foldl assignSlots (1, []) $ fprRegNums + + assignSlots (i, acc) regNum + | i == regNum = -- don't need padding here +@@ -195,11 +250,7 @@ padLiveArgs live = allRegs + + genPad start n = + take n $ flip map (iterate (+1) start) (\i -> +- (True, FloatReg i)) +- -- NOTE: Picking float should be fine for the following reasons: +- -- (1) Float aliases with all the other SSE register types on +- -- the given platform. +- -- (2) The argument is not live anyways. ++ (True, paddingCtor i)) + + + -- | Llvm standard fun attributes +diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs +index 1873400..21abc65 100644 +--- compiler/llvmGen/LlvmCodeGen/CodeGen.hs ++++ compiler/llvmGen/LlvmCodeGen/CodeGen.hs +@@ -1814,14 +1814,14 @@ funPrologue live cmmBlocks = do + -- STG Liveness optimisation done here. + funEpilogue :: LiveGlobalRegs -> LlvmM ([LlvmVar], LlvmStatements) + funEpilogue live = do ++ dflags <- getDynFlags + + -- the bool indicates whether the register is padding. + let alwaysNeeded = map (\r -> (False, r)) alwaysLive +- livePadded = alwaysNeeded ++ padLiveArgs live ++ livePadded = alwaysNeeded ++ padLiveArgs dflags live + + -- Set to value or "undef" depending on whether the register is + -- actually live +- dflags <- getDynFlags + let loadExpr r = do + (v, _, s) <- getCmmRegVal (CmmGlobal r) + return (Just $ v, s) +@@ -1833,7 +1833,7 @@ funEpilogue live = do + loads <- flip mapM allRegs $ \r -> case () of + _ | (False, r) `elem` livePadded + -> loadExpr r -- if r is not padding, load it +- | not (isSSE r) || (True, r) `elem` livePadded ++ | not (isFPR r) || (True, r) `elem` livePadded + -> loadUndef r + | otherwise -> return (Nothing, nilOL) + +-- +1.9.1 + Index: head/lang/ghc/files/patch-llvm-targets =================================================================== --- head/lang/ghc/files/patch-llvm-targets +++ head/lang/ghc/files/patch-llvm-targets @@ -1,10 +1,12 @@ --- llvm-targets.orig 2018-03-17 14:04:41 UTC +++ llvm-targets -@@ -20,4 +20,7 @@ +@@ -20,4 +20,9 @@ ,("aarch64-apple-ios", ("e-m:o-i64:64-i128:128-n32:64-S128", "generic", "+neon")) ,("i386-apple-ios", ("e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128", "yonah", "")) ,("x86_64-apple-ios", ("e-m:o-i64:64-f80:128-n8:16:32:64-S128", "core2", "")) +,("armv6-unknown-freebsd-gnueabihf", ("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) +,("armv7-unknown-freebsd-gnueabihf", ("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", "generic", "+strict-align")) +,("aarch64-unknown-freebsd", ("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", "generic", "+neon")) ++,("amd64-portbld-freebsd", ("e-m:e-i64:64-f80:128-n8:16:32:64-S128", "x86-64", "")) ++,("i386-portbld-freebsd", ("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", "i486", "")) ] Index: head/lang/ghc/files/patch-rts_posix_OSMem.c =================================================================== --- head/lang/ghc/files/patch-rts_posix_OSMem.c +++ head/lang/ghc/files/patch-rts_posix_OSMem.c @@ -0,0 +1,250 @@ +--- rts/posix/OSMem.c.orig 2017-11-28 16:39:14 UTC ++++ rts/posix/OSMem.c +@@ -36,6 +36,10 @@ + #if defined(HAVE_NUMAIF_H) + #include + #endif ++#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_SYS_TIME_H) ++#include ++#include ++#endif + + #include + +@@ -45,6 +49,29 @@ + #include + #endif + ++#ifndef MAP_FAILED ++# define MAP_FAILED ((void *)-1) ++#endif ++ ++#if defined(hpux_HOST_OS) ++# ifndef MAP_ANON ++# define MAP_ANON MAP_ANONYMOUS ++# endif ++#endif ++ ++#ifndef darwin_HOST_OS ++# undef RESERVE_FLAGS ++# if defined(MAP_GUARD) ++# define RESERVE_FLAGS MAP_GUARD /* FreeBSD */ ++# elif defined(MAP_NORESERVE) ++# define RESERVE_FLAGS MAP_NORESERVE | MAP_ANON | MAP_PRIVATE; ++# else ++# if defined(USE_LARGE_ADDRESS_SPACE) ++# error USE_LARGE_ADDRESS_SPACE needs MAP_NORESERVE or MAP_GUARD ++# endif ++# endif ++#endif ++ + static void *next_request = 0; + + void osMemInit(void) +@@ -98,8 +125,10 @@ + The naming is chosen from the Win32 API (VirtualAlloc) which does the + same thing and has done so forever, while support for this in Unix systems + has only been added recently and is hidden in the posix portability mess. +- It is confusing because to get the reserve behavior we need MAP_NORESERVE +- (which tells the kernel not to allocate backing space), but heh... ++ The Linux manpage suggests that mmap must be passed MAP_NORESERVE in order ++ to get reservation-only behavior. It is confusing because to get the reserve ++ behavior we need MAP_NORESERVE (which tells the kernel not to allocate backing ++ space), but heh... + */ + enum + { +@@ -108,6 +137,44 @@ + MEM_RESERVE_AND_COMMIT = MEM_RESERVE | MEM_COMMIT + }; + ++#if defined(linux_HOST_OS) ++static void * ++linux_retry_mmap(int operation, W_ size, void *ret, void *addr, int prot, int flags) ++{ ++ if (addr != 0 && (operation & MEM_RESERVE)) { ++ // Try again with no hint address. ++ // It's not clear that this can ever actually help, ++ // but since our alternative is to abort, we may as well try. ++ ret = mmap(0, size, prot, flags, -1, 0); ++ } ++ if (ret == MAP_FAILED && errno == EPERM) { ++ // Linux is not willing to give us any mapping, ++ // so treat this as an out-of-memory condition ++ // (really out of virtual address space). ++ errno = ENOMEM; ++ } ++ return ret; ++} ++#endif /* defined(linux_HOST_OS) */ ++ ++static void ++post_mmap_madvise(int operation, W_ size, void *ret) ++{ ++#if defined(MADV_WILLNEED) ++ if (operation & MEM_COMMIT) { ++ madvise(ret, size, MADV_WILLNEED); ++# if defined(MADV_DODUMP) ++ madvise(ret, size, MADV_DODUMP); ++# endif ++ } else { ++ madvise(ret, size, MADV_DONTNEED); ++# if defined(MADV_DONTDUMP) ++ madvise(ret, size, MADV_DONTDUMP); ++# endif ++ } ++#endif ++} ++ + /* Returns NULL on failure; errno set */ + static void * + my_mmap (void *addr, W_ size, int operation) +@@ -149,69 +216,44 @@ + VM_PROT_READ|VM_PROT_WRITE); + } + +-#else ++#else /* defined(darwin_HOST_OS) */ + + int prot, flags; +- if (operation & MEM_COMMIT) ++ if (operation & MEM_COMMIT) { + prot = PROT_READ | PROT_WRITE; +- else ++ } else { + prot = PROT_NONE; +- if (operation == MEM_RESERVE) +-# if defined(MAP_NORESERVE) +- flags = MAP_NORESERVE; ++ } ++ ++ if (operation == MEM_RESERVE) { ++# if defined(RESERVE_FLAGS) ++ flags = RESERVE_FLAGS; + # else +-# if defined(USE_LARGE_ADDRESS_SPACE) +-# error USE_LARGE_ADDRESS_SPACE needs MAP_NORESERVE +-# endif + errorBelch("my_mmap(,,MEM_RESERVE) not supported on this platform"); + # endif +- else if (operation == MEM_COMMIT) +- flags = MAP_FIXED; +- else +- flags = 0; ++ } else if (operation == MEM_COMMIT) { ++ flags = MAP_FIXED | MAP_ANON | MAP_PRIVATE; ++ } else { ++ flags = MAP_ANON | MAP_PRIVATE; ++ } + +-#if defined(hpux_HOST_OS) +- ret = mmap(addr, size, prot, flags | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); +-#elif defined(linux_HOST_OS) +- ret = mmap(addr, size, prot, flags | MAP_ANON | MAP_PRIVATE, -1, 0); +- if (ret == (void *)-1 && errno == EPERM) { ++ ret = mmap(addr, size, prot, flags, -1, 0); ++# if defined(linux_HOST_OS) ++ if (ret == MAP_FAILED && errno == EPERM) { + // Linux may return EPERM if it tried to give us + // a chunk of address space below mmap_min_addr, + // See Trac #7500. +- if (addr != 0 && (operation & MEM_RESERVE)) { +- // Try again with no hint address. +- // It's not clear that this can ever actually help, +- // but since our alternative is to abort, we may as well try. +- ret = mmap(0, size, prot, flags | MAP_ANON | MAP_PRIVATE, -1, 0); +- } +- if (ret == (void *)-1 && errno == EPERM) { +- // Linux is not willing to give us any mapping, +- // so treat this as an out-of-memory condition +- // (really out of virtual address space). +- errno = ENOMEM; +- } ++ ret = linux_retry_mmap(operation, size, ret, addr, prot, flags); + } +- +- if (operation & MEM_COMMIT) { +- madvise(ret, size, MADV_WILLNEED); +-#if defined(MADV_DODUMP) +- madvise(ret, size, MADV_DODUMP); +-#endif +- } else { +- madvise(ret, size, MADV_DONTNEED); +-#if defined(MADV_DONTDUMP) +- madvise(ret, size, MADV_DONTDUMP); +-#endif +- } +- +-#else +- ret = mmap(addr, size, prot, flags | MAP_ANON | MAP_PRIVATE, -1, 0); +-#endif +-#endif +- +- if (ret == (void *)-1) { ++# endif ++ if (ret == MAP_FAILED) { + return NULL; + } ++#endif /* defined(darwin_HOST_OS) */ ++ ++ // Map in committed pages rather than take a fault for each chunk. ++ // Also arrange to include them in core-dump files. ++ post_mmap_madvise(operation, size, ret); + + return ret; + } +@@ -435,6 +477,8 @@ + void *base, *top; + void *start, *end; + ++ ASSERT((len & ~MBLOCK_MASK) == len); ++ + /* We try to allocate len + MBLOCK_SIZE, + because we need memory which is MBLOCK_SIZE aligned, + and then we discard what we don't need */ +@@ -500,8 +544,19 @@ + (void*)startAddress, (void*)minimumAddress); + } + ++#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_SYS_TIME_H) ++ struct rlimit limit; ++ if (!getrlimit(RLIMIT_AS, &limit) ++ && limit.rlim_cur > 0 ++ && *len > limit.rlim_cur) { ++ *len = limit.rlim_cur; ++ } ++#endif ++ + attempt = 0; + while (1) { ++ *len &= ~MBLOCK_MASK; ++ + if (*len < MBLOCK_SIZE) { + // Give up if the system won't even give us 16 blocks worth of heap + barf("osReserveHeapMemory: Failed to allocate heap storage"); +@@ -512,9 +567,14 @@ + if (at == NULL) { + // This means that mmap failed which we take to mean that we asked + // for too much memory. This can happen due to POSIX resource +- // limits. In this case we reduce our allocation request by a factor +- // of two and try again. +- *len /= 2; ++ // limits. In this case we reduce our allocation request by a ++ // fraction of the current size and try again. ++ // ++ // Note that the previously would instead decrease the request size ++ // by a factor of two; however, this meant that significant amounts ++ // of memory will be wasted (e.g. imagine a machine with 512GB of ++ // physical memory but a 511GB ulimit). See #14492. ++ *len -= *len / 8; + } else if ((W_)at >= minimumAddress) { + // Success! We were given a block of memory starting above the 8 GB + // mark, which is what we were looking for. +@@ -536,7 +596,7 @@ + { + void *r = my_mmap(at, size, MEM_COMMIT); + if (r == NULL) { +- barf("Unable to commit %d bytes of memory", size); ++ barf("Unable to commit %" FMT_Word " bytes of memory", size); + } + }