/Src/Dependencies/AsmJit/AsmJit/Platform.cpp

http://hadesmem.googlecode.com/ · C++ · 241 lines · 143 code · 51 blank · 47 comment · 8 complexity · e7ca2842534a79ed0b682cc0763c2bdb MD5 · raw file

  1. // AsmJit - Complete JIT Assembler for C++ Language.
  2. // Copyright (c) 2008-2010, Petr Kobalicek <kobalicek.petr@gmail.com>
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. // [Dependencies]
  25. #include <stdio.h>
  26. #include "Platform.h"
  27. // [Api-Begin]
  28. #include "ApiBegin.h"
  29. // helpers
  30. namespace AsmJit {
  31. // ============================================================================
  32. // [AsmJit::Assert]
  33. // ============================================================================
  34. void assertionFailure(const char* file, int line, const char* exp)
  35. {
  36. fprintf(stderr,
  37. "*** ASSERTION FAILURE at %s (line %d)\n"
  38. "*** %s\n", file, line, exp);
  39. exit(1);
  40. }
  41. // ============================================================================
  42. // [AsmJit::Helpers]
  43. // ============================================================================
  44. static bool isAligned(sysuint_t base, sysuint_t alignment)
  45. {
  46. return base % alignment == 0;
  47. }
  48. static sysuint_t roundUp(sysuint_t base, sysuint_t pageSize)
  49. {
  50. sysuint_t over = base % pageSize;
  51. return base + (over > 0 ? pageSize - over : 0);
  52. }
  53. // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
  54. // figure 3-3, page 48, where the function is called clp2.
  55. static sysuint_t roundUpToPowerOf2(sysuint_t base)
  56. {
  57. base -= 1;
  58. base = base | (base >> 1);
  59. base = base | (base >> 2);
  60. base = base | (base >> 4);
  61. base = base | (base >> 8);
  62. base = base | (base >> 16);
  63. // I'm trying to make this portable and MSVC strikes me the warning C4293:
  64. // "Shift count negative or too big, undefined behavior"
  65. // Fixing...
  66. #if _MSC_VER
  67. # pragma warning(disable: 4293)
  68. #endif // _MSC_VER
  69. if (sizeof(sysuint_t) >= 8)
  70. base = base | (base >> 32);
  71. return base + 1;
  72. }
  73. } // AsmJit namespace
  74. // ============================================================================
  75. // [AsmJit::VirtualMemory::Windows]
  76. // ============================================================================
  77. #if defined(ASMJIT_WINDOWS)
  78. #include <windows.h>
  79. namespace AsmJit {
  80. struct ASMJIT_HIDDEN VirtualMemoryLocal
  81. {
  82. VirtualMemoryLocal() ASMJIT_NOTHROW
  83. {
  84. SYSTEM_INFO info;
  85. GetSystemInfo(&info);
  86. alignment = info.dwAllocationGranularity;
  87. pageSize = roundUpToPowerOf2(info.dwPageSize);
  88. }
  89. sysuint_t alignment;
  90. sysuint_t pageSize;
  91. };
  92. static VirtualMemoryLocal& vm() ASMJIT_NOTHROW
  93. {
  94. static VirtualMemoryLocal vm;
  95. return vm;
  96. };
  97. void* VirtualMemory::alloc(sysuint_t length, sysuint_t* allocated, bool canExecute)
  98. ASMJIT_NOTHROW
  99. {
  100. return allocProcessMemory(GetCurrentProcess(), length, allocated, canExecute);
  101. }
  102. void VirtualMemory::free(void* addr, sysuint_t length)
  103. ASMJIT_NOTHROW
  104. {
  105. return freeProcessMemory(GetCurrentProcess(), addr, length);
  106. }
  107. void* VirtualMemory::allocProcessMemory(HANDLE hProcess, sysuint_t length, sysuint_t* allocated, bool canExecute) ASMJIT_NOTHROW
  108. {
  109. // VirtualAlloc rounds allocated size to page size automatically.
  110. sysuint_t msize = roundUp(length, vm().pageSize);
  111. // Windows XP SP2 / Vista allow Data Excution Prevention (DEP).
  112. WORD protect = canExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
  113. LPVOID mbase = VirtualAllocEx(hProcess, NULL, msize, MEM_COMMIT | MEM_RESERVE, protect);
  114. if (mbase == NULL) return NULL;
  115. ASMJIT_ASSERT(isAligned(reinterpret_cast<sysuint_t>(mbase), vm().alignment));
  116. if (allocated) *allocated = msize;
  117. return mbase;
  118. }
  119. void VirtualMemory::freeProcessMemory(HANDLE hProcess, void* addr, sysuint_t /* length */) ASMJIT_NOTHROW
  120. {
  121. VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE);
  122. }
  123. sysuint_t VirtualMemory::getAlignment()
  124. ASMJIT_NOTHROW
  125. {
  126. return vm().alignment;
  127. }
  128. sysuint_t VirtualMemory::getPageSize()
  129. ASMJIT_NOTHROW
  130. {
  131. return vm().pageSize;
  132. }
  133. } // AsmJit
  134. #endif // ASMJIT_WINDOWS
  135. // ============================================================================
  136. // [AsmJit::VirtualMemory::Posix]
  137. // ============================================================================
  138. #if defined(ASMJIT_POSIX)
  139. #include <sys/types.h>
  140. #include <sys/mman.h>
  141. #include <unistd.h>
  142. // MacOS uses MAP_ANON instead of MAP_ANONYMOUS
  143. #ifndef MAP_ANONYMOUS
  144. # define MAP_ANONYMOUS MAP_ANON
  145. #endif
  146. namespace AsmJit {
  147. struct ASMJIT_HIDDEN VirtualMemoryLocal
  148. {
  149. VirtualMemoryLocal() ASMJIT_NOTHROW
  150. {
  151. alignment = pageSize = getpagesize();
  152. }
  153. sysuint_t alignment;
  154. sysuint_t pageSize;
  155. };
  156. static VirtualMemoryLocal& vm()
  157. ASMJIT_NOTHROW
  158. {
  159. static VirtualMemoryLocal vm;
  160. return vm;
  161. }
  162. void* VirtualMemory::alloc(sysuint_t length, sysuint_t* allocated, bool canExecute)
  163. ASMJIT_NOTHROW
  164. {
  165. sysuint_t msize = roundUp(length, vm().pageSize);
  166. int protection = PROT_READ | PROT_WRITE | (canExecute ? PROT_EXEC : 0);
  167. void* mbase = mmap(NULL, msize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  168. if (mbase == MAP_FAILED) return NULL;
  169. if (allocated) *allocated = msize;
  170. return mbase;
  171. }
  172. void VirtualMemory::free(void* addr, sysuint_t length)
  173. ASMJIT_NOTHROW
  174. {
  175. munmap(addr, length);
  176. }
  177. sysuint_t VirtualMemory::getAlignment()
  178. ASMJIT_NOTHROW
  179. {
  180. return vm().alignment;
  181. }
  182. sysuint_t VirtualMemory::getPageSize()
  183. ASMJIT_NOTHROW
  184. {
  185. return vm().pageSize;
  186. }
  187. } // AsmJit
  188. #endif // ASMJIT_POSIX
  189. // [Api-End]
  190. #include "ApiEnd.h"