ExecutableAllocator.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright (C) 2008 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef ExecutableAllocator_h
  26. #define ExecutableAllocator_h
  27. #include "JITCompilationEffort.h"
  28. #include <stddef.h> // for ptrdiff_t
  29. #include <limits>
  30. #include <wtf/Assertions.h>
  31. #include <wtf/MetaAllocatorHandle.h>
  32. #include <wtf/MetaAllocator.h>
  33. #include <wtf/PageAllocation.h>
  34. #include <wtf/PassRefPtr.h>
  35. #include <wtf/RefCounted.h>
  36. #include <wtf/Vector.h>
  37. #if OS(IOS)
  38. #include <libkern/OSCacheControl.h>
  39. #endif
  40. #if OS(IOS) || OS(QNX)
  41. #include <sys/mman.h>
  42. #endif
  43. #if CPU(MIPS) && OS(LINUX)
  44. #include <sys/cachectl.h>
  45. #endif
  46. #if CPU(SH4) && OS(LINUX)
  47. #include <asm/cachectl.h>
  48. #include <asm/unistd.h>
  49. #include <sys/syscall.h>
  50. #include <unistd.h>
  51. #endif
  52. #if OS(WINCE)
  53. // From pkfuncs.h (private header file from the Platform Builder)
  54. #define CACHE_SYNC_ALL 0x07F
  55. extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags);
  56. #endif
  57. #define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (pageSize() * 4)
  58. #if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
  59. #define PROTECTION_FLAGS_RW (PROT_READ | PROT_WRITE)
  60. #define PROTECTION_FLAGS_RX (PROT_READ | PROT_EXEC)
  61. #define EXECUTABLE_POOL_WRITABLE false
  62. #else
  63. #define EXECUTABLE_POOL_WRITABLE true
  64. #endif
  65. namespace JSC {
  66. class VM;
  67. void releaseExecutableMemory(VM&);
  68. static const unsigned jitAllocationGranule = 32;
  69. inline size_t roundUpAllocationSize(size_t request, size_t granularity)
  70. {
  71. RELEASE_ASSERT((std::numeric_limits<size_t>::max() - granularity) > request);
  72. // Round up to next page boundary
  73. size_t size = request + (granularity - 1);
  74. size = size & ~(granularity - 1);
  75. ASSERT(size >= request);
  76. return size;
  77. }
  78. }
  79. namespace JSC {
  80. typedef WTF::MetaAllocatorHandle ExecutableMemoryHandle;
  81. #if ENABLE(ASSEMBLER)
  82. #if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
  83. class DemandExecutableAllocator;
  84. #endif
  85. #if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
  86. #if OS(PSP2)
  87. static size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024; // non-const because we need to adjust this post ASLR...
  88. #elif CPU(ARM)
  89. static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024;
  90. #elif CPU(X86_64)
  91. static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024;
  92. #else
  93. static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
  94. #endif
  95. extern uintptr_t startOfFixedExecutableMemoryPool;
  96. #endif
  97. class ExecutableAllocator {
  98. enum ProtectionSetting { Writable, Executable };
  99. public:
  100. ExecutableAllocator(VM&);
  101. ~ExecutableAllocator();
  102. static void initializeAllocator();
  103. #if ENABLE(DETACHED_JIT)
  104. static void setMetaAllocator(WTF::MetaAllocator*);
  105. static WTF::MetaAllocator* metaAllocator();
  106. #endif
  107. bool isValid() const;
  108. static bool underMemoryPressure();
  109. static double memoryPressureMultiplier(size_t addedMemoryUsage);
  110. #if ENABLE(META_ALLOCATOR_PROFILE)
  111. static void dumpProfile();
  112. #else
  113. static void dumpProfile() { }
  114. #endif
  115. PassRefPtr<ExecutableMemoryHandle> allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort);
  116. #if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
  117. static void makeWritable(void* start, size_t size)
  118. {
  119. reprotectRegion(start, size, Writable);
  120. }
  121. static void makeExecutable(void* start, size_t size)
  122. {
  123. reprotectRegion(start, size, Executable);
  124. }
  125. #else
  126. static void makeWritable(void*, size_t) {}
  127. static void makeExecutable(void*, size_t) {}
  128. #endif
  129. static size_t committedByteCount();
  130. private:
  131. #if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
  132. static void reprotectRegion(void*, size_t, ProtectionSetting);
  133. #if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
  134. // We create a MetaAllocator for each JS global object.
  135. OwnPtr<DemandExecutableAllocator> m_allocator;
  136. DemandExecutableAllocator* allocator() { return m_allocator.get(); }
  137. #endif
  138. #endif
  139. };
  140. #endif // ENABLE(JIT) && ENABLE(ASSEMBLER)
  141. } // namespace JSC
  142. #endif // !defined(ExecutableAllocator)