Bug 589735 - JS engine is completely broken on ia64 - jemalloc part; r=pbiggar
authorJan Horak <jhorak@redhat.com>
Mon, 29 Aug 2011 17:26:22 +0100
changeset 76031 9c15d0fb3e255648d8050634a073033732ca705e
parent 76030 363c40e0666704df081098a50d2c1c01feff7e98
child 76032 7658f61d9e2bfe17529654c2f65ff1234caaa3bf
push id1543
push userbmo@edmorley.co.uk
push dateMon, 29 Aug 2011 16:27:29 +0000
treeherdermozilla-inbound@4fc1f5dd4105 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspbiggar
bugs589735
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 589735 - JS engine is completely broken on ia64 - jemalloc part; r=pbiggar
memory/jemalloc/jemalloc.c
--- a/memory/jemalloc/jemalloc.c
+++ b/memory/jemalloc/jemalloc.c
@@ -2190,16 +2190,36 @@ pages_map_align(size_t size, int pfd, si
 	return (ret);
 }
 #endif
 
 static void *
 pages_map(void *addr, size_t size, int pfd)
 {
 	void *ret;
+#if defined(__ia64__)
+        /*
+         * The JS engine assumes that all allocated pointers have their high 17 bits clear,
+         * which ia64's mmap doesn't support directly. However, we can emulate it by passing
+         * mmap an "addr" parameter with those bits clear. The mmap will return that address,
+         * or the nearest available memory above that address, providing a near-guarantee
+         * that those bits are clear. If they are not, we return NULL below to indicate
+         * out-of-memory.
+         * 
+         * The addr is chosen as 0x0000070000000000, which still allows about 120TB of virtual 
+         * address space.
+         * 
+         * See Bug 589735 for more information.
+         */
+	bool check_placement = true;
+        if (addr == NULL) {
+		addr = (void*)0x0000070000000000;
+		check_placement = false;
+	}
+#endif
 
 	/*
 	 * We don't use MAP_FIXED here, because it can cause the *replacement*
 	 * of existing mappings, and we only want to create new mappings.
 	 */
 #ifdef MALLOC_PAGEFILE
 	if (pfd != -1) {
 		ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
@@ -2209,34 +2229,52 @@ pages_map(void *addr, size_t size, int p
 	       {
 		ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
 		    MAP_ANON, -1, 0);
 	}
 	assert(ret != NULL);
 
 	if (ret == MAP_FAILED)
 		ret = NULL;
+#if defined(__ia64__)
+        /* 
+         * If the allocated memory doesn't have its upper 17 bits clear, consider it 
+         * as out of memory.
+        */
+        else if ((long long)ret & 0xffff800000000000) {
+		munmap(ret, size);
+                ret = NULL;
+        }
+        /* If the caller requested a specific memory location, verify that's what mmap returned. */
+	else if (check_placement && ret != addr) {
+#else
 	else if (addr != NULL && ret != addr) {
+#endif
 		/*
 		 * We succeeded in mapping memory, but not in the right place.
 		 */
 		if (munmap(ret, size) == -1) {
 			char buf[STRERROR_BUF];
 
 			strerror_r(errno, buf, sizeof(buf));
 			_malloc_message(_getprogname(),
 			    ": (malloc) Error in munmap(): ", buf, "\n");
 			if (opt_abort)
 				abort();
 		}
 		ret = NULL;
 	}
 
+#if defined(__ia64__)
+	assert(ret == NULL || (!check_placement && ret != NULL)
+	    || (check_placement && ret == addr));
+#else
 	assert(ret == NULL || (addr == NULL && ret != addr)
 	    || (addr != NULL && ret == addr));
+#endif
 	return (ret);
 }
 
 static void
 pages_unmap(void *addr, size_t size)
 {
 
 	if (munmap(addr, size) == -1) {