js/src/assembler/jit/ExecutableAllocatorWin.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

michael@0 1 /*
michael@0 2 * Copyright (C) 2008 Apple Inc. All rights reserved.
michael@0 3 *
michael@0 4 * Redistribution and use in source and binary forms, with or without
michael@0 5 * modification, are permitted provided that the following conditions
michael@0 6 * are met:
michael@0 7 * 1. Redistributions of source code must retain the above copyright
michael@0 8 * notice, this list of conditions and the following disclaimer.
michael@0 9 * 2. Redistributions in binary form must reproduce the above copyright
michael@0 10 * notice, this list of conditions and the following disclaimer in the
michael@0 11 * documentation and/or other materials provided with the distribution.
michael@0 12 *
michael@0 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
michael@0 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
michael@0 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
michael@0 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
michael@0 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
michael@0 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
michael@0 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
michael@0 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
michael@0 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 24 */
michael@0 25
michael@0 26 #include "assembler/jit/ExecutableAllocator.h"
michael@0 27
michael@0 28 #if ENABLE_ASSEMBLER && WTF_OS_WINDOWS
michael@0 29
michael@0 30 #include "jswin.h"
michael@0 31 #include "mozilla/WindowsVersion.h"
michael@0 32
michael@0 33 extern uint64_t random_next(uint64_t *, int);
michael@0 34
michael@0 35 namespace JSC {
michael@0 36
michael@0 37 uint64_t ExecutableAllocator::rngSeed;
michael@0 38
michael@0 39 size_t ExecutableAllocator::determinePageSize()
michael@0 40 {
michael@0 41 SYSTEM_INFO system_info;
michael@0 42 GetSystemInfo(&system_info);
michael@0 43 return system_info.dwPageSize;
michael@0 44 }
michael@0 45
michael@0 46 void *ExecutableAllocator::computeRandomAllocationAddress()
michael@0 47 {
michael@0 48 /*
michael@0 49 * Inspiration is V8's OS::Allocate in platform-win32.cc.
michael@0 50 *
michael@0 51 * VirtualAlloc takes 64K chunks out of the virtual address space, so we
michael@0 52 * keep 16b alignment.
michael@0 53 *
michael@0 54 * x86: V8 comments say that keeping addresses in the [64MiB, 1GiB) range
michael@0 55 * tries to avoid system default DLL mapping space. In the end, we get 13
michael@0 56 * bits of randomness in our selection.
michael@0 57 * x64: [2GiB, 4TiB), with 25 bits of randomness.
michael@0 58 */
michael@0 59 static const unsigned chunkBits = 16;
michael@0 60 #if WTF_CPU_X86_64
michael@0 61 static const uintptr_t base = 0x0000000080000000;
michael@0 62 static const uintptr_t mask = 0x000003ffffff0000;
michael@0 63 #elif WTF_CPU_X86
michael@0 64 static const uintptr_t base = 0x04000000;
michael@0 65 static const uintptr_t mask = 0x3fff0000;
michael@0 66 #else
michael@0 67 # error "Unsupported architecture"
michael@0 68 #endif
michael@0 69 uint64_t rand = random_next(&rngSeed, 32) << chunkBits;
michael@0 70 return (void *) (base | rand & mask);
michael@0 71 }
michael@0 72
michael@0 73 static bool
michael@0 74 RandomizeIsBrokenImpl()
michael@0 75 {
michael@0 76 // We disable everything before Vista, for now.
michael@0 77 return !mozilla::IsVistaOrLater();
michael@0 78 }
michael@0 79
michael@0 80 static bool
michael@0 81 RandomizeIsBroken()
michael@0 82 {
michael@0 83 // Use the compiler's intrinsic guards for |static type value = expr| to avoid some potential
michael@0 84 // races if runtimes are created from multiple threads.
michael@0 85 static int result = RandomizeIsBrokenImpl();
michael@0 86 return !!result;
michael@0 87 }
michael@0 88
michael@0 89 ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n)
michael@0 90 {
michael@0 91 void *allocation = NULL;
michael@0 92 // Randomization disabled to avoid a performance fault on x64 builds.
michael@0 93 // See bug 728623.
michael@0 94 #ifndef JS_CPU_X64
michael@0 95 if (!RandomizeIsBroken()) {
michael@0 96 void *randomAddress = computeRandomAllocationAddress();
michael@0 97 allocation = VirtualAlloc(randomAddress, n, MEM_COMMIT | MEM_RESERVE,
michael@0 98 PAGE_EXECUTE_READWRITE);
michael@0 99 }
michael@0 100 #endif
michael@0 101 if (!allocation)
michael@0 102 allocation = VirtualAlloc(0, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
michael@0 103 ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(allocation), n };
michael@0 104 return alloc;
michael@0 105 }
michael@0 106
michael@0 107 void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc)
michael@0 108 {
michael@0 109 VirtualFree(alloc.pages, 0, MEM_RELEASE);
michael@0 110 }
michael@0 111
michael@0 112 void
michael@0 113 ExecutablePool::toggleAllCodeAsAccessible(bool accessible)
michael@0 114 {
michael@0 115 char* begin = m_allocation.pages;
michael@0 116 size_t size = m_freePtr - begin;
michael@0 117
michael@0 118 if (size) {
michael@0 119 // N.B. DEP is not on automatically in Windows XP, so be sure to use
michael@0 120 // PAGE_NOACCESS instead of PAGE_READWRITE when making inaccessible.
michael@0 121 DWORD oldProtect;
michael@0 122 int flags = accessible ? PAGE_EXECUTE_READWRITE : PAGE_NOACCESS;
michael@0 123 if (!VirtualProtect(begin, size, flags, &oldProtect))
michael@0 124 MOZ_CRASH();
michael@0 125 }
michael@0 126 }
michael@0 127
michael@0 128 #if ENABLE_ASSEMBLER_WX_EXCLUSIVE
michael@0 129 #error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform."
michael@0 130 #endif
michael@0 131
michael@0 132 }
michael@0 133
michael@0 134 #endif // HAVE(ASSEMBLER)

mercurial