aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys/common/erl_mseg.c
diff options
context:
space:
mode:
authorPatrik Nyblom <[email protected]>2009-12-07 15:25:32 +0100
committerBjörn Gustavsson <[email protected]>2010-03-10 14:23:54 +0100
commit5a8e6c4183a30f3b10de22fa5ba80950dfb2adea (patch)
tree1b1830bf144427531d7be5aa968e02bb2e67539e /erts/emulator/sys/common/erl_mseg.c
parent356c33b6063de632f9c98c66260603e6edbc3ee5 (diff)
downloadotp-5a8e6c4183a30f3b10de22fa5ba80950dfb2adea.tar.gz
otp-5a8e6c4183a30f3b10de22fa5ba80950dfb2adea.tar.bz2
otp-5a8e6c4183a30f3b10de22fa5ba80950dfb2adea.zip
Fit all heap data into the 32-bit address range
This is the first step in the implementation of the half-word emulator, a 64-bit emulator where all pointers to heap data will be stored in 32-bit words. Code specific for this emulator variant is conditionally compiled when the HALFWORD_HEAP define has a non-zero value. First force all pointers to heap data to fall into a single 32-bit range, but still store them in 64-bit words. Temporary term data stored on C stack is moved into scheduler specific storage (allocated as heaps) and macros are added to make this happen only in emulators where this is needed. For a vanilla VM the temporary terms are still stored on the C stack.
Diffstat (limited to 'erts/emulator/sys/common/erl_mseg.c')
-rw-r--r--erts/emulator/sys/common/erl_mseg.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index f4e21bc05f..c859b192f7 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -87,11 +87,22 @@ static int is_cache_check_requested;
/* Mmap ... */
#define MMAP_PROT (PROT_READ|PROT_WRITE)
+
+#if HALFWORD_HEAP
+# ifdef MAP_32BIT
+# define RANGE_FLAG (MAP_32BIT)
+# else
+# error "Cannot have halfword heap if unable to restrict mmap areas
+# endif
+#else
+# define RANGE_FLAG (0)
+#endif
+
#ifdef MAP_ANON
-# define MMAP_FLAGS (MAP_ANON|MAP_PRIVATE)
+# define MMAP_FLAGS (MAP_ANON|MAP_PRIVATE|RANGE_FLAG)
# define MMAP_FD (-1)
#else
-# define MMAP_FLAGS (MAP_PRIVATE)
+# define MMAP_FLAGS (MAP_PRIVATE|RANGE_FLAG)
# define MMAP_FD mmap_fd
static int mmap_fd;
#endif
@@ -310,6 +321,12 @@ mseg_create(Uint size)
MMAP_PROT, MMAP_FLAGS, MMAP_FD, 0);
if (seg == (void *) MAP_FAILED)
seg = NULL;
+#if HALFWORD_HEAP
+ if ((unsigned long) seg & CHECK_POINTER_MASK) {
+ erts_fprintf(stderr,"Pointer mask failure (0x%08lx)\n",(unsigned long) seg);
+ return NULL;
+ }
+#endif
#else
#error "Missing mseg_create() implementation"
#endif
@@ -1300,6 +1317,37 @@ erts_mseg_unit_size(void)
{
return page_size;
}
+#if HAVE_MMAP && HALFWORD_HEAP
+#ifdef MAP_NORESERVE
+#define RESERVE_FLAGS (MMAP_FLAGS | MAP_NORESERVE)
+#else
+#define RESERVE_FLAGS (MMAP_FLAGS)
+#endif
+static void halfword_reserve(void)
+{
+#if 0
+ void *ptr, *understack;
+ unsigned long x = 0x80000000;
+ long i = 0;
+
+ understack = mmap(NULL,GET_PAGE_SIZE, PROT_NONE, RESERVE_FLAGS,
+ MMAP_FD, 0);
+ while (x < (unsigned long) understack) {
+ ptr = mmap((void *) x, GET_PAGE_SIZE, PROT_NONE, RESERVE_FLAGS,
+ MMAP_FD, 0);
+ if ((unsigned long) ptr < 0x80000000) {
+ munmap(ptr, GET_PAGE_SIZE);
+ } else {
+ ++i;
+ }
+ x += GET_PAGE_SIZE;
+ }
+ erts_fprintf(stderr,"Reserved %ld pages [%d MB]...\n",i, (i*GET_PAGE_SIZE)/1024/1024);
+#else
+ return;
+#endif
+}
+#endif
void
erts_mseg_init(ErtsMsegInit_t *init)
@@ -1328,6 +1376,10 @@ erts_mseg_init(ErtsMsegInit_t *init)
erl_exit(ERTS_ABORT_EXIT, "erts_mseg: unable to open /dev/zero\n");
#endif
+#if HAVE_MMAP && HALFWORD_HEAP
+ halfword_reserve();
+#endif
+
page_size = GET_PAGE_SIZE;
page_shift = 1;