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))