diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 6adedacad56..15ebffebd4c 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -911,6 +911,11 @@ struct JSGCLockHashEntry : public JSDHashEntryHdr JSBool js_InitGC(JSRuntime *rt, uint32 maxbytes) { +#if defined(XP_WIN) && defined(_M_X64) + if (!InitNtAllocAPIs()) + return JS_FALSE; +#endif + InitGCArenaLists(rt); if (!rt->gcRootsHash.init(GC_ROOTS_SIZE)) return false; diff --git a/js/src/jsgcchunk.cpp b/js/src/jsgcchunk.cpp index a833dcb84b2..d69fe03c50c 100644 --- a/js/src/jsgcchunk.cpp +++ b/js/src/jsgcchunk.cpp @@ -140,6 +140,47 @@ UnmapPages(void *p, size_t size) # else /* WINCE */ +# ifdef _M_X64 + +typedef long (*ntavm_fun)(HANDLE handle, void **addr, ULONG zbits, + size_t *size, ULONG alloctype, ULONG prot); +typedef long (*ntfvm_fun)(HANDLE handle, void **addr, size_t *size, + ULONG freetype); + +static ntavm_fun NtAllocateVirtualMemory; +static ntfvm_fun NtFreeVirtualMemory; + +bool +js::InitNtAllocAPIs() +{ + HMODULE h = GetModuleHandle("ntdll.dll"); + if (!h) + return false; + NtAllocateVirtualMemory = ntavm_fun(GetProcAddress(h, "NtAllocateVirtualMemory")); + if (!NtAllocateVirtualMemory) + return false; + NtFreeVirtualMemory = ntfvm_fun(GetProcAddress(h, "NtFreeVirtualMemory")); + if (!NtFreeVirtualMemory) + return false; +} + +// Allocate pages with 32-bit addresses (i.e., top 16 bits are all 0). +static void * +MapPages(void *addr, size_t size) +{ + long rc = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &addr, 1, &size, + MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); + return rc ? NULL : addr; +} + +static void +UnmapPages(void *addr, size_t size) +{ + NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &addr, &size, MEM_RELEASE); +} + +# else /* _M_X64 */ + static void * MapPages(void *addr, size_t size) { @@ -154,6 +195,8 @@ UnmapPages(void *addr, size_t size) JS_ALWAYS_TRUE(VirtualFree(addr, 0, MEM_RELEASE)); } +# endif /* _M_X64 */ + # endif /* !WINCE */ #elif defined(XP_MACOSX) || defined(DARWIN) diff --git a/js/src/jsgcchunk.h b/js/src/jsgcchunk.h index bb8622d9b68..3c2d38dc983 100644 --- a/js/src/jsgcchunk.h +++ b/js/src/jsgcchunk.h @@ -55,6 +55,10 @@ const size_t GC_CHUNK_SHIFT = 20; const size_t GC_CHUNK_SIZE = size_t(1) << GC_CHUNK_SHIFT; const size_t GC_CHUNK_MASK = GC_CHUNK_SIZE - 1; +#if defined(XP_WIN) && defined(_M_X64) +bool InitNtAllocAPIs(); +#endif + void * AllocGCChunk();