| From: Stephan Schreiber <info@fs-driver.org> |
| Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=659186 |
| Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=589735 |
| Description: Fix MapPages() on ia64 |
| |
| --- a/js/src/jsgcchunk.cpp |
| +++ b/js/src/jsgcchunk.cpp |
| @@ -318,15 +318,48 @@ MapAlignedPages(size_t size, size_t alig |
| static void * |
| MapPages(void *addr, size_t size) |
| { |
| +#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. |
| + */ |
| +#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. |
| */ |
| +#if defined(__ia64__) |
| + void *p = mmap(addr ? addr : (void*)0x0000070000000000, |
| + size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, |
| + -1, 0); |
| +#else |
| void *p = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, |
| -1, 0); |
| +#endif |
| if (p == MAP_FAILED) |
| return NULL; |
| +#if defined(__ia64__) |
| + /* |
| + * If the caller requested a specific memory location, verify that's what mmap returned. |
| + * Otherwise: If the allocated memory doesn't have its upper 17 bits clear, consider it |
| + * as out of memory. |
| + */ |
| + if (addr && p != addr |
| + || !addr && ((long long)p & 0xffff800000000000)) { |
| +#else |
| + /* If the caller requested a specific memory location, verify that's what mmap returned. */ |
| if (addr && p != addr) { |
| +#endif |
| /* We succeeded in mapping memory, but not in the right place. */ |
| JS_ALWAYS_TRUE(munmap(p, size) == 0); |
| return NULL; |