Title: [213128] releases/WebKitGTK/webkit-2.16/Source
Revision
213128
Author
carlo...@webkit.org
Date
2017-02-28 01:05:24 -0800 (Tue, 28 Feb 2017)

Log Message

Merge r212867 - Remove the demand executable allocator
https://bugs.webkit.org/show_bug.cgi?id=168754

Reviewed by Saam Barati.

Source/_javascript_Core:

We currently only use the demand executable allocator for non-iOS 32-bit platforms.
Benchmark results on a MBP indicate there is no appreciable performance difference
between a the fixed and demand allocators. In a future patch I will go back through
this code and remove more of the abstractions.

* _javascript_Core.xcodeproj/project.pbxproj:
* jit/ExecutableAllocator.cpp:
(JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator):
(JSC::FixedVMPoolExecutableAllocator::initializeSeparatedWXHeaps):
(JSC::FixedVMPoolExecutableAllocator::jitWriteThunkGenerator):
(JSC::FixedVMPoolExecutableAllocator::genericWriteToJITRegion):
(JSC::ExecutableAllocator::initializeAllocator):
(JSC::ExecutableAllocator::ExecutableAllocator):
(JSC::FixedVMPoolExecutableAllocator::~FixedVMPoolExecutableAllocator):
(JSC::ExecutableAllocator::isValid):
(JSC::ExecutableAllocator::underMemoryPressure):
(JSC::ExecutableAllocator::memoryPressureMultiplier):
(JSC::ExecutableAllocator::allocate):
(JSC::ExecutableAllocator::isValidExecutableMemory):
(JSC::ExecutableAllocator::getLock):
(JSC::ExecutableAllocator::committedByteCount):
(JSC::ExecutableAllocator::dumpProfile):
(JSC::DemandExecutableAllocator::DemandExecutableAllocator): Deleted.
(JSC::DemandExecutableAllocator::~DemandExecutableAllocator): Deleted.
(JSC::DemandExecutableAllocator::bytesAllocatedByAllAllocators): Deleted.
(JSC::DemandExecutableAllocator::bytesCommittedByAllocactors): Deleted.
(JSC::DemandExecutableAllocator::dumpProfileFromAllAllocators): Deleted.
(JSC::DemandExecutableAllocator::allocateNewSpace): Deleted.
(JSC::DemandExecutableAllocator::notifyNeedPage): Deleted.
(JSC::DemandExecutableAllocator::notifyPageIsFree): Deleted.
(JSC::DemandExecutableAllocator::allocators): Deleted.
(JSC::DemandExecutableAllocator::allocatorsMutex): Deleted.
* jit/ExecutableAllocator.h:
* jit/ExecutableAllocatorFixedVMPool.cpp: Removed.
* jit/JITStubRoutine.h:
(JSC::JITStubRoutine::canPerformRangeFilter):
(JSC::JITStubRoutine::filteringStartAddress):
(JSC::JITStubRoutine::filteringExtentSize):

Source/WTF:

* wtf/Platform.h:

Modified Paths

Removed Paths

Diff

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/CMakeLists.txt (213127 => 213128)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/CMakeLists.txt	2017-02-28 09:01:09 UTC (rev 213127)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/CMakeLists.txt	2017-02-28 09:05:24 UTC (rev 213128)
@@ -578,7 +578,6 @@
     jit/CallFrameShuffler64.cpp
     jit/ExecutableAllocationFuzz.cpp
     jit/ExecutableAllocator.cpp
-    jit/ExecutableAllocatorFixedVMPool.cpp
     jit/GCAwareJITStubRoutine.cpp
     jit/GPRInfo.cpp
     jit/HostCallReturnValue.cpp

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog (213127 => 213128)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog	2017-02-28 09:01:09 UTC (rev 213127)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog	2017-02-28 09:05:24 UTC (rev 213128)
@@ -1,3 +1,49 @@
+2017-02-22  Keith Miller  <keith_mil...@apple.com>
+
+        Remove the demand executable allocator
+        https://bugs.webkit.org/show_bug.cgi?id=168754
+
+        Reviewed by Saam Barati.
+
+        We currently only use the demand executable allocator for non-iOS 32-bit platforms.
+        Benchmark results on a MBP indicate there is no appreciable performance difference
+        between a the fixed and demand allocators. In a future patch I will go back through
+        this code and remove more of the abstractions.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * jit/ExecutableAllocator.cpp:
+        (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator):
+        (JSC::FixedVMPoolExecutableAllocator::initializeSeparatedWXHeaps):
+        (JSC::FixedVMPoolExecutableAllocator::jitWriteThunkGenerator):
+        (JSC::FixedVMPoolExecutableAllocator::genericWriteToJITRegion):
+        (JSC::ExecutableAllocator::initializeAllocator):
+        (JSC::ExecutableAllocator::ExecutableAllocator):
+        (JSC::FixedVMPoolExecutableAllocator::~FixedVMPoolExecutableAllocator):
+        (JSC::ExecutableAllocator::isValid):
+        (JSC::ExecutableAllocator::underMemoryPressure):
+        (JSC::ExecutableAllocator::memoryPressureMultiplier):
+        (JSC::ExecutableAllocator::allocate):
+        (JSC::ExecutableAllocator::isValidExecutableMemory):
+        (JSC::ExecutableAllocator::getLock):
+        (JSC::ExecutableAllocator::committedByteCount):
+        (JSC::ExecutableAllocator::dumpProfile):
+        (JSC::DemandExecutableAllocator::DemandExecutableAllocator): Deleted.
+        (JSC::DemandExecutableAllocator::~DemandExecutableAllocator): Deleted.
+        (JSC::DemandExecutableAllocator::bytesAllocatedByAllAllocators): Deleted.
+        (JSC::DemandExecutableAllocator::bytesCommittedByAllocactors): Deleted.
+        (JSC::DemandExecutableAllocator::dumpProfileFromAllAllocators): Deleted.
+        (JSC::DemandExecutableAllocator::allocateNewSpace): Deleted.
+        (JSC::DemandExecutableAllocator::notifyNeedPage): Deleted.
+        (JSC::DemandExecutableAllocator::notifyPageIsFree): Deleted.
+        (JSC::DemandExecutableAllocator::allocators): Deleted.
+        (JSC::DemandExecutableAllocator::allocatorsMutex): Deleted.
+        * jit/ExecutableAllocator.h:
+        * jit/ExecutableAllocatorFixedVMPool.cpp: Removed.
+        * jit/JITStubRoutine.h:
+        (JSC::JITStubRoutine::canPerformRangeFilter):
+        (JSC::JITStubRoutine::filteringStartAddress):
+        (JSC::JITStubRoutine::filteringExtentSize):
+
 2017-02-22  Yusuke Suzuki  <utatane....@gmail.com>
 
         JSModuleNamespace object should have IC

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (213127 => 213128)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-02-28 09:01:09 UTC (rev 213127)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-02-28 09:05:24 UTC (rev 213128)
@@ -1551,7 +1551,6 @@
 		86D3B2C510156BDE002865E7 /* AssemblerBufferWithConstantPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		86D3B2C610156BDE002865E7 /* MacroAssemblerARM.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B2C210156BDE002865E7 /* MacroAssemblerARM.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		86D3B3C310159D7F002865E7 /* LinkBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B3C110159D7F002865E7 /* LinkBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */; };
 		86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E116B00FE75AC800B512BC /* CodeLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		86E3C612167BABD7006D760A /* JSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C606167BAB87006D760A /* JSValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		86E3C613167BABD7006D760A /* JSContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C607167BAB87006D760A /* JSContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -4066,7 +4065,6 @@
 		86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblerBufferWithConstantPool.h; sourceTree = "<group>"; };
 		86D3B2C210156BDE002865E7 /* MacroAssemblerARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARM.h; sourceTree = "<group>"; };
 		86D3B3C110159D7F002865E7 /* LinkBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkBuffer.h; sourceTree = "<group>"; };
-		86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorFixedVMPool.cpp; sourceTree = "<group>"; };
 		86E116B00FE75AC800B512BC /* CodeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeLocation.h; sourceTree = "<group>"; };
 		86E3C606167BAB87006D760A /* JSValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValue.h; sourceTree = "<group>"; };
 		86E3C607167BAB87006D760A /* JSContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSContext.h; sourceTree = "<group>"; };
@@ -5654,7 +5652,6 @@
 				0FF054F81AC35B4400E5BE57 /* ExecutableAllocationFuzz.h */,
 				A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */,
 				A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */,
-				86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */,
 				0F24E53E17EA9F5900ABB217 /* FPRInfo.h */,
 				0F766D2D15A8DCDD008F363E /* GCAwareJITStubRoutine.cpp */,
 				0F766D2E15A8DCDD008F363E /* GCAwareJITStubRoutine.h */,
@@ -10138,7 +10135,6 @@
 				FE6491391D78F3AF00A694D4 /* ExceptionScope.cpp in Sources */,
 				0FF054F91AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp in Sources */,
 				A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */,
-				86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */,
 				147341EA1DC2CF2500AA29BA /* ExecutableBase.cpp in Sources */,
 				0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */,
 				0F0332C018ADFAE1005F979A /* ExitingJITType.cpp in Sources */,

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/ExecutableAllocator.cpp (213127 => 213128)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/ExecutableAllocator.cpp	2017-02-28 09:01:09 UTC (rev 213127)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/ExecutableAllocator.cpp	2017-02-28 09:05:24 UTC (rev 213128)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2009, 2015, 2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -20,151 +20,299 @@
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "config.h"
 #include "ExecutableAllocator.h"
 
+#include "CodeProfiling.h"
+#include "ExecutableAllocationFuzz.h"
 #include "JSCInlines.h"
-
-#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
-#include "CodeProfiling.h"
-#include <wtf/HashSet.h>
-#include <wtf/Lock.h>
 #include <wtf/MetaAllocator.h>
-#include <wtf/NeverDestroyed.h>
 #include <wtf/PageReservation.h>
-#include <wtf/VMTags.h>
+
+#if OS(DARWIN)
+#include <sys/mman.h>
 #endif
 
-// Uncomment to create an artificial executable memory usage limit. This limit
-// is imperfect and is primarily useful for testing the VM's ability to handle
-// out-of-executable-memory situations.
-// #define EXECUTABLE_MEMORY_LIMIT 1000000
+#include "LinkBuffer.h"
+#include "MacroAssembler.h"
 
-#if ENABLE(ASSEMBLER)
+#if PLATFORM(MAC) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000)
+#define HAVE_REMAP_JIT 1
+#endif
 
+#if HAVE(REMAP_JIT)
+#if CPU(ARM64) && PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000
+#define USE_EXECUTE_ONLY_JIT_WRITE_FUNCTION 1
+#endif
+#endif
+
+#if OS(DARWIN)
+#include <mach/mach.h>
+extern "C" {
+    /* Routine mach_vm_remap */
+#ifdef mig_external
+    mig_external
+#else
+    extern
+#endif /* mig_external */
+    kern_return_t mach_vm_remap
+    (
+     vm_map_t target_task,
+     mach_vm_address_t *target_address,
+     mach_vm_size_t size,
+     mach_vm_offset_t mask,
+     int flags,
+     vm_map_t src_task,
+     mach_vm_address_t src_address,
+     boolean_t copy,
+     vm_prot_t *cur_protection,
+     vm_prot_t *max_protection,
+     vm_inherit_t inheritance
+     );
+}
+
+#endif
+
 using namespace WTF;
 
 namespace JSC {
 
-#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
+JS_EXPORTDATA uintptr_t startOfFixedExecutableMemoryPool;
+JS_EXPORTDATA uintptr_t endOfFixedExecutableMemoryPool;
 
-class DemandExecutableAllocator : public MetaAllocator {
+JS_EXPORTDATA JITWriteFunction jitWriteFunction;
+
+#if !USE(EXECUTE_ONLY_JIT_WRITE_FUNCTION) && HAVE(REMAP_JIT)
+static uintptr_t startOfFixedWritableMemoryPool;
+#endif
+
+class FixedVMPoolExecutableAllocator : public MetaAllocator {
+    WTF_MAKE_FAST_ALLOCATED;
 public:
-    DemandExecutableAllocator()
-        : MetaAllocator(jitAllocationGranule)
+    FixedVMPoolExecutableAllocator()
+        : MetaAllocator(jitAllocationGranule) // round up all allocations to 32 bytes
     {
-        std::lock_guard<StaticLock> lock(allocatorsMutex());
-        allocators().add(this);
-        // Don't preallocate any memory here.
-    }
-    
-    virtual ~DemandExecutableAllocator()
-    {
-        {
-            std::lock_guard<StaticLock> lock(allocatorsMutex());
-            allocators().remove(this);
+        size_t reservationSize;
+        if (Options::jitMemoryReservationSize())
+            reservationSize = Options::jitMemoryReservationSize();
+        else
+            reservationSize = fixedExecutableMemoryPoolSize;
+        reservationSize = roundUpToMultipleOf(pageSize(), reservationSize);
+        m_reservation = PageReservation::reserveWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
+        if (m_reservation) {
+            ASSERT(m_reservation.size() == reservationSize);
+            void* reservationBase = m_reservation.base();
+
+            if (Options::useSeparatedWXHeap()) {
+                // First page of our JIT allocation is reserved.
+                ASSERT(reservationSize >= pageSize() * 2);
+                reservationBase = (void*)((uintptr_t)reservationBase + pageSize());
+                reservationSize -= pageSize();
+                initializeSeparatedWXHeaps(m_reservation.base(), pageSize(), reservationBase, reservationSize);
+            }
+
+            addFreshFreeSpace(reservationBase, reservationSize);
+
+            startOfFixedExecutableMemoryPool = reinterpret_cast<uintptr_t>(reservationBase);
+            endOfFixedExecutableMemoryPool = startOfFixedExecutableMemoryPool + reservationSize;
         }
-        for (unsigned i = 0; i < reservations.size(); ++i)
-            reservations.at(i).deallocate();
     }
 
-    static size_t bytesAllocatedByAllAllocators()
+    virtual ~FixedVMPoolExecutableAllocator();
+
+protected:
+    void* allocateNewSpace(size_t&) override
     {
-        size_t total = 0;
-        std::lock_guard<StaticLock> lock(allocatorsMutex());
-        for (HashSet<DemandExecutableAllocator*>::const_iterator allocator = allocators().begin(); allocator != allocators().end(); ++allocator)
-            total += (*allocator)->bytesAllocated();
-        return total;
+        // We're operating in a fixed pool, so new allocation is always prohibited.
+        return 0;
     }
 
-    static size_t bytesCommittedByAllocactors()
+    void notifyNeedPage(void* page) override
     {
-        size_t total = 0;
-        std::lock_guard<StaticLock> lock(allocatorsMutex());
-        for (HashSet<DemandExecutableAllocator*>::const_iterator allocator = allocators().begin(); allocator != allocators().end(); ++allocator)
-            total += (*allocator)->bytesCommitted();
-        return total;
+#if USE(MADV_FREE_FOR_JIT_MEMORY)
+        UNUSED_PARAM(page);
+#else
+        m_reservation.commit(page, pageSize());
+#endif
     }
 
-#if ENABLE(META_ALLOCATOR_PROFILE)
-    static void dumpProfileFromAllAllocators()
+    void notifyPageIsFree(void* page) override
     {
-        std::lock_guard<StaticLock> lock(allocatorsMutex());
-        for (HashSet<DemandExecutableAllocator*>::const_iterator allocator = allocators().begin(); allocator != allocators().end(); ++allocator)
-            (*allocator)->dumpProfile();
+#if USE(MADV_FREE_FOR_JIT_MEMORY)
+        for (;;) {
+            int result = madvise(page, pageSize(), MADV_FREE);
+            if (!result)
+                return;
+            ASSERT(result == -1);
+            if (errno != EAGAIN) {
+                RELEASE_ASSERT_NOT_REACHED(); // In debug mode, this should be a hard failure.
+                break; // In release mode, we should just ignore the error - not returning memory to the OS is better than crashing, especially since we _will_ be able to reuse the memory internally anyway.
+            }
+        }
+#else
+        m_reservation.decommit(page, pageSize());
+#endif
     }
-#endif
 
-protected:
-    virtual void* allocateNewSpace(size_t& numPages)
+private:
+#if OS(DARWIN) && HAVE(REMAP_JIT)
+    void initializeSeparatedWXHeaps(void* stubBase, size_t stubSize, void* jitBase, size_t jitSize)
     {
-        size_t newNumPages = (((numPages * pageSize() + JIT_ALLOCATOR_LARGE_ALLOC_SIZE - 1) / JIT_ALLOCATOR_LARGE_ALLOC_SIZE * JIT_ALLOCATOR_LARGE_ALLOC_SIZE) + pageSize() - 1) / pageSize();
-        
-        ASSERT(newNumPages >= numPages);
-        
-        numPages = newNumPages;
-        
-#ifdef EXECUTABLE_MEMORY_LIMIT
-        if (bytesAllocatedByAllAllocators() >= EXECUTABLE_MEMORY_LIMIT)
-            return 0;
+        mach_vm_address_t writableAddr = 0;
+
+        // Create a second mapping of the JIT region at a random address.
+        vm_prot_t cur, max;
+        int remapFlags = VM_FLAGS_ANYWHERE;
+#if defined(VM_FLAGS_RANDOM_ADDR)
+        remapFlags |= VM_FLAGS_RANDOM_ADDR;
 #endif
-        
-        PageReservation reservation = PageReservation::reserve(numPages * pageSize(), OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
-        RELEASE_ASSERT(reservation);
-        
-        reservations.append(reservation);
-        
-        return reservation.base();
+        kern_return_t ret = mach_vm_remap(mach_task_self(), &writableAddr, jitSize, 0,
+            remapFlags,
+            mach_task_self(), (mach_vm_address_t)jitBase, FALSE,
+            &cur, &max, VM_INHERIT_DEFAULT);
+
+        bool remapSucceeded = (ret == KERN_SUCCESS);
+        if (!remapSucceeded)
+            return;
+
+        // Assemble a thunk that will serve as the means for writing into the JIT region.
+        MacroAssemblerCodeRef writeThunk = jitWriteThunkGenerator(reinterpret_cast<void*>(writableAddr), stubBase, stubSize);
+
+        int result = 0;
+
+#if USE(EXECUTE_ONLY_JIT_WRITE_FUNCTION)
+        // Prevent reading the write thunk code.
+        result = mprotect(stubBase, stubSize, VM_PROT_EXECUTE_ONLY);
+        RELEASE_ASSERT(!result);
+#endif
+
+        // Prevent writing into the executable JIT mapping.
+        result = mprotect(jitBase, jitSize, VM_PROT_READ | VM_PROT_EXECUTE);
+        RELEASE_ASSERT(!result);
+
+        // Prevent execution in the writable JIT mapping.
+        result = mprotect((void*)writableAddr, jitSize, VM_PROT_READ | VM_PROT_WRITE);
+        RELEASE_ASSERT(!result);
+
+        // Zero out writableAddr to avoid leaking the address of the writable mapping.
+        memset_s(&writableAddr, sizeof(writableAddr), 0, sizeof(writableAddr));
+
+        jitWriteFunction = reinterpret_cast<JITWriteFunction>(writeThunk.code().executableAddress());
     }
-    
-    virtual void notifyNeedPage(void* page)
+
+#if CPU(ARM64) && USE(EXECUTE_ONLY_JIT_WRITE_FUNCTION)
+    MacroAssemblerCodeRef jitWriteThunkGenerator(void* writableAddr, void* stubBase, size_t stubSize)
     {
-        OSAllocator::commit(page, pageSize(), EXECUTABLE_POOL_WRITABLE, true);
+        using namespace ARM64Registers;
+        using TrustedImm32 = MacroAssembler::TrustedImm32;
+
+        MacroAssembler jit;
+
+        jit.move(MacroAssembler::TrustedImmPtr(writableAddr), x7);
+        jit.addPtr(x7, x0);
+
+        jit.move(x0, x3);
+        MacroAssembler::Jump smallCopy = jit.branch64(MacroAssembler::Below, x2, MacroAssembler::TrustedImm64(64));
+
+        jit.add64(TrustedImm32(32), x3);
+        jit.and64(TrustedImm32(-32), x3);
+        jit.loadPair64(x1, x12, x13);
+        jit.loadPair64(x1, TrustedImm32(16), x14, x15);
+        jit.sub64(x3, x0, x5);
+        jit.addPtr(x5, x1);
+
+        jit.loadPair64(x1, x8, x9);
+        jit.loadPair64(x1, TrustedImm32(16), x10, x11);
+        jit.add64(TrustedImm32(32), x1);
+        jit.sub64(x5, x2);
+        jit.storePair64(x12, x13, x0);
+        jit.storePair64(x14, x15, x0, TrustedImm32(16));
+        MacroAssembler::Jump cleanup = jit.branchSub64(MacroAssembler::BelowOrEqual, TrustedImm32(64), x2);
+
+        MacroAssembler::Label copyLoop = jit.label();
+        jit.storePair64WithNonTemporalAccess(x8, x9, x3);
+        jit.storePair64WithNonTemporalAccess(x10, x11, x3, TrustedImm32(16));
+        jit.add64(TrustedImm32(32), x3);
+        jit.loadPair64WithNonTemporalAccess(x1, x8, x9);
+        jit.loadPair64WithNonTemporalAccess(x1, TrustedImm32(16), x10, x11);
+        jit.add64(TrustedImm32(32), x1);
+        jit.branchSub64(MacroAssembler::Above, TrustedImm32(32), x2).linkTo(copyLoop, &jit);
+
+        cleanup.link(&jit);
+        jit.add64(x2, x1);
+        jit.loadPair64(x1, x12, x13);
+        jit.loadPair64(x1, TrustedImm32(16), x14, x15);
+        jit.storePair64(x8, x9, x3);
+        jit.storePair64(x10, x11, x3, TrustedImm32(16));
+        jit.addPtr(x2, x3);
+        jit.storePair64(x12, x13, x3, TrustedImm32(32));
+        jit.storePair64(x14, x15, x3, TrustedImm32(48));
+        jit.ret();
+
+        MacroAssembler::Label local0 = jit.label();
+        jit.load64(x1, PostIndex(8), x6);
+        jit.store64(x6, x3, PostIndex(8));
+        smallCopy.link(&jit);
+        jit.branchSub64(MacroAssembler::AboveOrEqual, TrustedImm32(8), x2).linkTo(local0, &jit);
+        MacroAssembler::Jump local2 = jit.branchAdd64(MacroAssembler::Equal, TrustedImm32(8), x2);
+        MacroAssembler::Label local1 = jit.label();
+        jit.load8(x1, PostIndex(1), x6);
+        jit.store8(x6, x3, PostIndex(1));
+        jit.branchSub64(MacroAssembler::NotEqual, TrustedImm32(1), x2).linkTo(local1, &jit);
+        local2.link(&jit);
+        jit.ret();
+
+        LinkBuffer linkBuffer(jit, stubBase, stubSize);
+        // We don't use FINALIZE_CODE() for two reasons.
+        // The first is that we don't want the writeable address, as disassembled instructions,
+        // to appear in the console or anywhere in memory, via the PrintStream buffer.
+        // The second is we can't guarantee that the code is readable when using the
+        // asyncDisassembly option as our caller will set our pages execute only.
+        return linkBuffer.finalizeCodeWithoutDisassembly();
     }
-    
-    virtual void notifyPageIsFree(void* page)
+#else // CPU(ARM64) && USE(EXECUTE_ONLY_JIT_WRITE_FUNCTION)
+    static void genericWriteToJITRegion(off_t offset, const void* data, size_t dataSize)
     {
-        OSAllocator::decommit(page, pageSize());
+        memcpy((void*)(startOfFixedWritableMemoryPool + offset), data, dataSize);
     }
 
-private:
-    Vector<PageReservation, 16> reservations;
-    static HashSet<DemandExecutableAllocator*>& allocators()
+    MacroAssemblerCodeRef jitWriteThunkGenerator(void* address, void*, size_t)
     {
-        static NeverDestroyed<HashSet<DemandExecutableAllocator*>> set;
-        return set;
+        startOfFixedWritableMemoryPool = reinterpret_cast<uintptr_t>(address);
+        uintptr_t function = (uintptr_t)((void*)&genericWriteToJITRegion);
+#if CPU(ARM_THUMB2)
+        // Handle thumb offset
+        function -= 1;
+#endif
+        return MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr((void*)function));
     }
+#endif
 
-    static StaticLock& allocatorsMutex()
+#else // OS(DARWIN) && HAVE(REMAP_JIT)
+    void initializeSeparatedWXHeaps(void*, size_t, void*, size_t)
     {
-        static StaticLock mutex;
+    }
+#endif
 
-        return mutex;
-    }
+private:
+    PageReservation m_reservation;
 };
 
-static DemandExecutableAllocator* gAllocator;
+static FixedVMPoolExecutableAllocator* allocator;
 
-namespace {
-static inline DemandExecutableAllocator* allocator()
-{
-    return gAllocator;
-}
-}
-
 void ExecutableAllocator::initializeAllocator()
 {
-    ASSERT(!gAllocator);
-    gAllocator = new DemandExecutableAllocator();
-    CodeProfiling::notifyAllocator(gAllocator);
+    ASSERT(!allocator);
+    allocator = new FixedVMPoolExecutableAllocator();
+    CodeProfiling::notifyAllocator(allocator);
 }
 
 ExecutableAllocator::ExecutableAllocator(VM&)
 {
-    ASSERT(allocator());
+    ASSERT(allocator);
 }
 
 ExecutableAllocator::~ExecutableAllocator()
@@ -171,70 +319,97 @@
 {
 }
 
+FixedVMPoolExecutableAllocator::~FixedVMPoolExecutableAllocator()
+{
+    m_reservation.deallocate();
+}
+
 bool ExecutableAllocator::isValid() const
 {
-    return true;
+    return !!allocator->bytesReserved();
 }
 
 bool ExecutableAllocator::underMemoryPressure()
 {
-#ifdef EXECUTABLE_MEMORY_LIMIT
-    return DemandExecutableAllocator::bytesAllocatedByAllAllocators() > EXECUTABLE_MEMORY_LIMIT / 2;
-#else
-    return false;
-#endif
+    MetaAllocator::Statistics statistics = allocator->currentStatistics();
+    return statistics.bytesAllocated > statistics.bytesReserved / 2;
 }
 
 double ExecutableAllocator::memoryPressureMultiplier(size_t addedMemoryUsage)
 {
-    double result;
-#ifdef EXECUTABLE_MEMORY_LIMIT
-    size_t bytesAllocated = DemandExecutableAllocator::bytesAllocatedByAllAllocators() + addedMemoryUsage;
-    if (bytesAllocated >= EXECUTABLE_MEMORY_LIMIT)
-        bytesAllocated = EXECUTABLE_MEMORY_LIMIT;
-    result = static_cast<double>(EXECUTABLE_MEMORY_LIMIT) /
-        (EXECUTABLE_MEMORY_LIMIT - bytesAllocated);
-#else
-    UNUSED_PARAM(addedMemoryUsage);
-    result = 1.0;
-#endif
+    MetaAllocator::Statistics statistics = allocator->currentStatistics();
+    ASSERT(statistics.bytesAllocated <= statistics.bytesReserved);
+    size_t bytesAllocated = statistics.bytesAllocated + addedMemoryUsage;
+    size_t bytesAvailable = static_cast<size_t>(
+        statistics.bytesReserved * (1 - executablePoolReservationFraction));
+    if (bytesAllocated >= bytesAvailable)
+        bytesAllocated = bytesAvailable;
+    double result = 1.0;
+    size_t divisor = bytesAvailable - bytesAllocated;
+    if (divisor)
+        result = static_cast<double>(bytesAvailable) / divisor;
     if (result < 1.0)
         result = 1.0;
     return result;
-
 }
 
 RefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
 {
-    RefPtr<ExecutableMemoryHandle> result = allocator()->allocate(sizeInBytes, ownerUID);
-    RELEASE_ASSERT(result || effort != JITCompilationMustSucceed);
+    if (Options::logExecutableAllocation()) {
+        MetaAllocator::Statistics stats = allocator->currentStatistics();
+        dataLog("Allocating ", sizeInBytes, " bytes of executable memory with ", stats.bytesAllocated, " bytes allocated, ", stats.bytesReserved, " bytes reserved, and ", stats.bytesCommitted, " committed.\n");
+    }
+    
+    if (effort != JITCompilationCanFail && Options::reportMustSucceedExecutableAllocations()) {
+        dataLog("Allocating ", sizeInBytes, " bytes of executable memory with JITCompilationMustSucceed.\n");
+        WTFReportBacktrace();
+    }
+    
+    if (effort == JITCompilationCanFail
+        && doExecutableAllocationFuzzingIfEnabled() == PretendToFailExecutableAllocation)
+        return nullptr;
+    
+    if (effort == JITCompilationCanFail) {
+        // Don't allow allocations if we are down to reserve.
+        MetaAllocator::Statistics statistics = allocator->currentStatistics();
+        size_t bytesAllocated = statistics.bytesAllocated + sizeInBytes;
+        size_t bytesAvailable = static_cast<size_t>(
+            statistics.bytesReserved * (1 - executablePoolReservationFraction));
+        if (bytesAllocated > bytesAvailable)
+            return nullptr;
+    }
+    
+    RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID);
+    if (!result) {
+        if (effort != JITCompilationCanFail) {
+            dataLog("Ran out of executable memory while allocating ", sizeInBytes, " bytes.\n");
+            CRASH();
+        }
+        return nullptr;
+    }
     return result;
 }
 
-size_t ExecutableAllocator::committedByteCount()
+bool ExecutableAllocator::isValidExecutableMemory(const LockHolder& locker, void* address)
 {
-    return DemandExecutableAllocator::bytesCommittedByAllocactors();
+    return allocator->isInAllocatedMemory(locker, address);
 }
 
-#if ENABLE(META_ALLOCATOR_PROFILE)
-void ExecutableAllocator::dumpProfile()
+Lock& ExecutableAllocator::getLock() const
 {
-    DemandExecutableAllocator::dumpProfileFromAllAllocators();
+    return allocator->getLock();
 }
-#endif
 
-Lock& ExecutableAllocator::getLock() const
+size_t ExecutableAllocator::committedByteCount()
 {
-    return gAllocator->getLock();
+    return allocator->bytesCommitted();
 }
 
-bool ExecutableAllocator::isValidExecutableMemory(const LockHolder& locker, void* address)
+#if ENABLE(META_ALLOCATOR_PROFILE)
+void ExecutableAllocator::dumpProfile()
 {
-    return gAllocator->isInAllocatedMemory(locker, address);
+    allocator->dumpProfile();
 }
-
-#endif // ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
-
+#endif
+    
 }
-
-#endif // HAVE(ASSEMBLER)

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/ExecutableAllocator.h (213127 => 213128)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/ExecutableAllocator.h	2017-02-28 09:01:09 UTC (rev 213127)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/ExecutableAllocator.h	2017-02-28 09:05:24 UTC (rev 213128)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -60,11 +60,6 @@
 
 #if ENABLE(ASSEMBLER)
 
-#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
-class DemandExecutableAllocator;
-#endif
-
-#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
 #if defined(FIXED_EXECUTABLE_MEMORY_POOL_SIZE_IN_MB) && FIXED_EXECUTABLE_MEMORY_POOL_SIZE_IN_MB > 0
 static const size_t fixedExecutableMemoryPoolSize = FIXED_EXECUTABLE_MEMORY_POOL_SIZE_IN_MB * 1024 * 1024;
 #elif CPU(ARM)
@@ -102,13 +97,6 @@
     return memcpy(dst, src, n);
 }
 
-#else // ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
-static inline void* performJITMemcpy(void *dst, const void *src, size_t n)
-{
-    return memcpy(dst, src, n);
-}
-#endif
-
 class ExecutableAllocator {
     enum ProtectionSetting { Writable, Executable };
 

Deleted: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/ExecutableAllocatorFixedVMPool.cpp (213127 => 213128)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/ExecutableAllocatorFixedVMPool.cpp	2017-02-28 09:01:09 UTC (rev 213127)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/ExecutableAllocatorFixedVMPool.cpp	2017-02-28 09:05:24 UTC (rev 213128)
@@ -1,421 +0,0 @@
-/*
- * Copyright (C) 2009, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "ExecutableAllocator.h"
-
-#include "JSCInlines.h"
-
-#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
-
-#include "CodeProfiling.h"
-#include "ExecutableAllocationFuzz.h"
-#include <wtf/MetaAllocator.h>
-#include <wtf/PageReservation.h>
-
-#if OS(DARWIN)
-#include <sys/mman.h>
-#endif
-
-#include "LinkBuffer.h"
-#include "MacroAssembler.h"
-
-#if PLATFORM(MAC) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000)
-#define HAVE_REMAP_JIT 1
-#endif
-
-#if HAVE(REMAP_JIT)
-#if CPU(ARM64) && PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000
-#define USE_EXECUTE_ONLY_JIT_WRITE_FUNCTION 1
-#endif
-#endif
-
-#if OS(DARWIN)
-#include <mach/mach.h>
-extern "C" {
-    /* Routine mach_vm_remap */
-#ifdef mig_external
-    mig_external
-#else
-    extern
-#endif /* mig_external */
-    kern_return_t mach_vm_remap
-    (
-     vm_map_t target_task,
-     mach_vm_address_t *target_address,
-     mach_vm_size_t size,
-     mach_vm_offset_t mask,
-     int flags,
-     vm_map_t src_task,
-     mach_vm_address_t src_address,
-     boolean_t copy,
-     vm_prot_t *cur_protection,
-     vm_prot_t *max_protection,
-     vm_inherit_t inheritance
-     );
-}
-
-#endif
-
-using namespace WTF;
-
-namespace JSC {
-
-JS_EXPORTDATA uintptr_t startOfFixedExecutableMemoryPool;
-JS_EXPORTDATA uintptr_t endOfFixedExecutableMemoryPool;
-
-JS_EXPORTDATA JITWriteFunction jitWriteFunction;
-
-#if !USE(EXECUTE_ONLY_JIT_WRITE_FUNCTION) && HAVE(REMAP_JIT)
-static uintptr_t startOfFixedWritableMemoryPool;
-#endif
-
-class FixedVMPoolExecutableAllocator : public MetaAllocator {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    FixedVMPoolExecutableAllocator()
-        : MetaAllocator(jitAllocationGranule) // round up all allocations to 32 bytes
-    {
-        size_t reservationSize;
-        if (Options::jitMemoryReservationSize())
-            reservationSize = Options::jitMemoryReservationSize();
-        else
-            reservationSize = fixedExecutableMemoryPoolSize;
-        reservationSize = roundUpToMultipleOf(pageSize(), reservationSize);
-        m_reservation = PageReservation::reserveWithGuardPages(reservationSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
-        if (m_reservation) {
-            ASSERT(m_reservation.size() == reservationSize);
-            void* reservationBase = m_reservation.base();
-
-            if (Options::useSeparatedWXHeap()) {
-                // First page of our JIT allocation is reserved.
-                ASSERT(reservationSize >= pageSize() * 2);
-                reservationBase = (void*)((uintptr_t)reservationBase + pageSize());
-                reservationSize -= pageSize();
-                initializeSeparatedWXHeaps(m_reservation.base(), pageSize(), reservationBase, reservationSize);
-            }
-
-            addFreshFreeSpace(reservationBase, reservationSize);
-
-            startOfFixedExecutableMemoryPool = reinterpret_cast<uintptr_t>(reservationBase);
-            endOfFixedExecutableMemoryPool = startOfFixedExecutableMemoryPool + reservationSize;
-        }
-    }
-
-    virtual ~FixedVMPoolExecutableAllocator();
-    
-protected:
-    void* allocateNewSpace(size_t&) override
-    {
-        // We're operating in a fixed pool, so new allocation is always prohibited.
-        return 0;
-    }
-    
-    void notifyNeedPage(void* page) override
-    {
-#if USE(MADV_FREE_FOR_JIT_MEMORY)
-        UNUSED_PARAM(page);
-#else
-        m_reservation.commit(page, pageSize());
-#endif
-    }
-    
-    void notifyPageIsFree(void* page) override
-    {
-#if USE(MADV_FREE_FOR_JIT_MEMORY)
-        for (;;) {
-            int result = madvise(page, pageSize(), MADV_FREE);
-            if (!result)
-                return;
-            ASSERT(result == -1);
-            if (errno != EAGAIN) {
-                RELEASE_ASSERT_NOT_REACHED(); // In debug mode, this should be a hard failure.
-                break; // In release mode, we should just ignore the error - not returning memory to the OS is better than crashing, especially since we _will_ be able to reuse the memory internally anyway.
-            }
-        }
-#else
-        m_reservation.decommit(page, pageSize());
-#endif
-    }
-
-private:
-#if OS(DARWIN) && HAVE(REMAP_JIT)
-    void initializeSeparatedWXHeaps(void* stubBase, size_t stubSize, void* jitBase, size_t jitSize)
-    {
-        mach_vm_address_t writableAddr = 0;
-
-        // Create a second mapping of the JIT region at a random address.
-        vm_prot_t cur, max;
-        int remapFlags = VM_FLAGS_ANYWHERE;
-#if defined(VM_FLAGS_RANDOM_ADDR)
-        remapFlags |= VM_FLAGS_RANDOM_ADDR;
-#endif
-        kern_return_t ret = mach_vm_remap(mach_task_self(), &writableAddr, jitSize, 0,
-            remapFlags,
-            mach_task_self(), (mach_vm_address_t)jitBase, FALSE,
-            &cur, &max, VM_INHERIT_DEFAULT);
-
-        bool remapSucceeded = (ret == KERN_SUCCESS);
-        if (!remapSucceeded)
-            return;
-
-        // Assemble a thunk that will serve as the means for writing into the JIT region.
-        MacroAssemblerCodeRef writeThunk = jitWriteThunkGenerator(reinterpret_cast<void*>(writableAddr), stubBase, stubSize);
-
-        int result = 0;
-
-#if USE(EXECUTE_ONLY_JIT_WRITE_FUNCTION)
-        // Prevent reading the write thunk code.
-        result = mprotect(stubBase, stubSize, VM_PROT_EXECUTE_ONLY);
-        RELEASE_ASSERT(!result);
-#endif
-
-        // Prevent writing into the executable JIT mapping.
-        result = mprotect(jitBase, jitSize, VM_PROT_READ | VM_PROT_EXECUTE);
-        RELEASE_ASSERT(!result);
-
-        // Prevent execution in the writable JIT mapping.
-        result = mprotect((void*)writableAddr, jitSize, VM_PROT_READ | VM_PROT_WRITE);
-        RELEASE_ASSERT(!result);
-
-        // Zero out writableAddr to avoid leaking the address of the writable mapping.
-        memset_s(&writableAddr, sizeof(writableAddr), 0, sizeof(writableAddr));
-
-        jitWriteFunction = reinterpret_cast<JITWriteFunction>(writeThunk.code().executableAddress());
-    }
-
-#if CPU(ARM64) && USE(EXECUTE_ONLY_JIT_WRITE_FUNCTION)
-    MacroAssemblerCodeRef jitWriteThunkGenerator(void* writableAddr, void* stubBase, size_t stubSize)
-    {
-        using namespace ARM64Registers;
-        using TrustedImm32 = MacroAssembler::TrustedImm32;
-
-        MacroAssembler jit;
-
-        jit.move(MacroAssembler::TrustedImmPtr(writableAddr), x7);
-        jit.addPtr(x7, x0);
-
-        jit.move(x0, x3);
-        MacroAssembler::Jump smallCopy = jit.branch64(MacroAssembler::Below, x2, MacroAssembler::TrustedImm64(64));
-
-        jit.add64(TrustedImm32(32), x3);
-        jit.and64(TrustedImm32(-32), x3);
-        jit.loadPair64(x1, x12, x13);
-        jit.loadPair64(x1, TrustedImm32(16), x14, x15);
-        jit.sub64(x3, x0, x5);
-        jit.addPtr(x5, x1);
-
-        jit.loadPair64(x1, x8, x9);
-        jit.loadPair64(x1, TrustedImm32(16), x10, x11);
-        jit.add64(TrustedImm32(32), x1);
-        jit.sub64(x5, x2);
-        jit.storePair64(x12, x13, x0);
-        jit.storePair64(x14, x15, x0, TrustedImm32(16));
-        MacroAssembler::Jump cleanup = jit.branchSub64(MacroAssembler::BelowOrEqual, TrustedImm32(64), x2);
-
-        MacroAssembler::Label copyLoop = jit.label();
-        jit.storePair64WithNonTemporalAccess(x8, x9, x3);
-        jit.storePair64WithNonTemporalAccess(x10, x11, x3, TrustedImm32(16));
-        jit.add64(TrustedImm32(32), x3);
-        jit.loadPair64WithNonTemporalAccess(x1, x8, x9);
-        jit.loadPair64WithNonTemporalAccess(x1, TrustedImm32(16), x10, x11);
-        jit.add64(TrustedImm32(32), x1);
-        jit.branchSub64(MacroAssembler::Above, TrustedImm32(32), x2).linkTo(copyLoop, &jit);
-
-        cleanup.link(&jit);
-        jit.add64(x2, x1);
-        jit.loadPair64(x1, x12, x13);
-        jit.loadPair64(x1, TrustedImm32(16), x14, x15);
-        jit.storePair64(x8, x9, x3);
-        jit.storePair64(x10, x11, x3, TrustedImm32(16));
-        jit.addPtr(x2, x3);
-        jit.storePair64(x12, x13, x3, TrustedImm32(32));
-        jit.storePair64(x14, x15, x3, TrustedImm32(48));
-        jit.ret();
-
-        MacroAssembler::Label local0 = jit.label();
-        jit.load64(x1, PostIndex(8), x6);
-        jit.store64(x6, x3, PostIndex(8));
-        smallCopy.link(&jit);
-        jit.branchSub64(MacroAssembler::AboveOrEqual, TrustedImm32(8), x2).linkTo(local0, &jit);
-        MacroAssembler::Jump local2 = jit.branchAdd64(MacroAssembler::Equal, TrustedImm32(8), x2);
-        MacroAssembler::Label local1 = jit.label();
-        jit.load8(x1, PostIndex(1), x6);
-        jit.store8(x6, x3, PostIndex(1));
-        jit.branchSub64(MacroAssembler::NotEqual, TrustedImm32(1), x2).linkTo(local1, &jit);
-        local2.link(&jit);
-        jit.ret();
-
-        LinkBuffer linkBuffer(jit, stubBase, stubSize);
-        // We don't use FINALIZE_CODE() for two reasons.
-        // The first is that we don't want the writeable address, as disassembled instructions,
-        // to appear in the console or anywhere in memory, via the PrintStream buffer.
-        // The second is we can't guarantee that the code is readable when using the
-        // asyncDisassembly option as our caller will set our pages execute only.
-        return linkBuffer.finalizeCodeWithoutDisassembly();
-    }
-#else // CPU(ARM64) && USE(EXECUTE_ONLY_JIT_WRITE_FUNCTION)
-    static void genericWriteToJITRegion(off_t offset, const void* data, size_t dataSize)
-    {
-        memcpy((void*)(startOfFixedWritableMemoryPool + offset), data, dataSize);
-    }
-
-    MacroAssemblerCodeRef jitWriteThunkGenerator(void* address, void*, size_t)
-    {
-        startOfFixedWritableMemoryPool = reinterpret_cast<uintptr_t>(address);
-        uintptr_t function = (uintptr_t)((void*)&genericWriteToJITRegion);
-#if CPU(ARM_THUMB2)
-        // Handle thumb offset
-        function -= 1;
-#endif
-        return MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr((void*)function));
-    }
-#endif
-
-#else // OS(DARWIN) && HAVE(REMAP_JIT)
-    void initializeSeparatedWXHeaps(void*, size_t, void*, size_t)
-    {
-    }
-#endif
-
-private:
-    PageReservation m_reservation;
-};
-
-static FixedVMPoolExecutableAllocator* allocator;
-
-void ExecutableAllocator::initializeAllocator()
-{
-    ASSERT(!allocator);
-    allocator = new FixedVMPoolExecutableAllocator();
-    CodeProfiling::notifyAllocator(allocator);
-}
-
-ExecutableAllocator::ExecutableAllocator(VM&)
-{
-    ASSERT(allocator);
-}
-
-ExecutableAllocator::~ExecutableAllocator()
-{
-}
-
-FixedVMPoolExecutableAllocator::~FixedVMPoolExecutableAllocator()
-{
-    m_reservation.deallocate();
-}
-
-bool ExecutableAllocator::isValid() const
-{
-    return !!allocator->bytesReserved();
-}
-
-bool ExecutableAllocator::underMemoryPressure()
-{
-    MetaAllocator::Statistics statistics = allocator->currentStatistics();
-    return statistics.bytesAllocated > statistics.bytesReserved / 2;
-}
-
-double ExecutableAllocator::memoryPressureMultiplier(size_t addedMemoryUsage)
-{
-    MetaAllocator::Statistics statistics = allocator->currentStatistics();
-    ASSERT(statistics.bytesAllocated <= statistics.bytesReserved);
-    size_t bytesAllocated = statistics.bytesAllocated + addedMemoryUsage;
-    size_t bytesAvailable = static_cast<size_t>(
-        statistics.bytesReserved * (1 - executablePoolReservationFraction));
-    if (bytesAllocated >= bytesAvailable)
-        bytesAllocated = bytesAvailable;
-    double result = 1.0;
-    size_t divisor = bytesAvailable - bytesAllocated;
-    if (divisor)
-        result = static_cast<double>(bytesAvailable) / divisor;
-    if (result < 1.0)
-        result = 1.0;
-    return result;
-}
-
-RefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
-{
-    if (Options::logExecutableAllocation()) {
-        MetaAllocator::Statistics stats = allocator->currentStatistics();
-        dataLog("Allocating ", sizeInBytes, " bytes of executable memory with ", stats.bytesAllocated, " bytes allocated, ", stats.bytesReserved, " bytes reserved, and ", stats.bytesCommitted, " committed.\n");
-    }
-    
-    if (effort != JITCompilationCanFail && Options::reportMustSucceedExecutableAllocations()) {
-        dataLog("Allocating ", sizeInBytes, " bytes of executable memory with JITCompilationMustSucceed.\n");
-        WTFReportBacktrace();
-    }
-    
-    if (effort == JITCompilationCanFail
-        && doExecutableAllocationFuzzingIfEnabled() == PretendToFailExecutableAllocation)
-        return nullptr;
-    
-    if (effort == JITCompilationCanFail) {
-        // Don't allow allocations if we are down to reserve.
-        MetaAllocator::Statistics statistics = allocator->currentStatistics();
-        size_t bytesAllocated = statistics.bytesAllocated + sizeInBytes;
-        size_t bytesAvailable = static_cast<size_t>(
-            statistics.bytesReserved * (1 - executablePoolReservationFraction));
-        if (bytesAllocated > bytesAvailable)
-            return nullptr;
-    }
-    
-    RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID);
-    if (!result) {
-        if (effort != JITCompilationCanFail) {
-            dataLog("Ran out of executable memory while allocating ", sizeInBytes, " bytes.\n");
-            CRASH();
-        }
-        return nullptr;
-    }
-    return result;
-}
-
-bool ExecutableAllocator::isValidExecutableMemory(const LockHolder& locker, void* address)
-{
-    return allocator->isInAllocatedMemory(locker, address);
-}
-
-Lock& ExecutableAllocator::getLock() const
-{
-    return allocator->getLock();
-}
-
-size_t ExecutableAllocator::committedByteCount()
-{
-    return allocator->bytesCommitted();
-}
-
-#if ENABLE(META_ALLOCATOR_PROFILE)
-void ExecutableAllocator::dumpProfile()
-{
-    allocator->dumpProfile();
-}
-#endif
-
-}
-
-
-#endif // ENABLE(EXECUTABLE_ALLOCATOR_FIXED)

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/JITStubRoutine.h (213127 => 213128)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/JITStubRoutine.h	2017-02-28 09:01:09 UTC (rev 213127)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/JITStubRoutine.h	2017-02-28 09:05:24 UTC (rev 213128)
@@ -97,29 +97,15 @@
     
     static bool canPerformRangeFilter()
     {
-#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
         return true;
-#else
-        return false;
-#endif
     }
     static uintptr_t filteringStartAddress()
     {
-#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
         return startOfFixedExecutableMemoryPool;
-#else
-        UNREACHABLE_FOR_PLATFORM();
-        return 0;
-#endif
     }
     static size_t filteringExtentSize()
     {
-#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
         return fixedExecutableMemoryPoolSize;
-#else
-        UNREACHABLE_FOR_PLATFORM();
-        return 0;
-#endif
     }
     static bool passesFilter(uintptr_t address)
     {

Modified: releases/WebKitGTK/webkit-2.16/Source/WTF/ChangeLog (213127 => 213128)


--- releases/WebKitGTK/webkit-2.16/Source/WTF/ChangeLog	2017-02-28 09:01:09 UTC (rev 213127)
+++ releases/WebKitGTK/webkit-2.16/Source/WTF/ChangeLog	2017-02-28 09:05:24 UTC (rev 213128)
@@ -1,3 +1,12 @@
+2017-02-22  Keith Miller  <keith_mil...@apple.com>
+
+        Remove the demand executable allocator
+        https://bugs.webkit.org/show_bug.cgi?id=168754
+
+        Reviewed by Saam Barati.
+
+        * wtf/Platform.h:
+
 2017-02-22  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [GTK] Test fast/events/message-port-postMessage-recursive.html times out

Modified: releases/WebKitGTK/webkit-2.16/Source/WTF/wtf/Platform.h (213127 => 213128)


--- releases/WebKitGTK/webkit-2.16/Source/WTF/wtf/Platform.h	2017-02-28 09:01:09 UTC (rev 213127)
+++ releases/WebKitGTK/webkit-2.16/Source/WTF/wtf/Platform.h	2017-02-28 09:05:24 UTC (rev 213128)
@@ -909,16 +909,6 @@
 #endif
 #endif
 
-/* Pick which allocator to use; we only need an executable allocator if the assembler is compiled in.
-   On non-Windows x86-64, iOS, and ARM64 we use a single fixed mmap, on other platforms we mmap on demand. */
-#if ENABLE(ASSEMBLER)
-#if CPU(X86_64) || PLATFORM(IOS) || CPU(ARM64)
-#define ENABLE_EXECUTABLE_ALLOCATOR_FIXED 1
-#else
-#define ENABLE_EXECUTABLE_ALLOCATOR_DEMAND 1
-#endif
-#endif
-
 /* CSS Selector JIT Compiler */
 #if !defined(ENABLE_CSS_SELECTOR_JIT)
 #if (CPU(X86_64) || CPU(ARM64) || (CPU(ARM_THUMB2) && PLATFORM(IOS))) && ENABLE(JIT) && (OS(DARWIN) || PLATFORM(GTK))
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to