libcopp  1.1.0
stack_allocator_windows.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include <assert.h>
3 #include <cstring>
4 #include <limits>
5 #include <numeric>
6 
7 extern "C" {
8 #include <windows.h>
9 }
10 
14 
15 #if defined(COPP_MACRO_COMPILER_MSVC)
16 #pragma warning(push)
17 #pragma warning(disable : 4244 4267)
18 #endif
19 
20 #ifdef COPP_HAS_ABI_HEADERS
21 #include COPP_ABI_PREFIX
22 #endif
23 
24 namespace copp {
25  namespace allocator {
26 
28 
30 
31  void stack_allocator_windows::allocate(stack_context &ctx, std::size_t size) UTIL_CONFIG_NOEXCEPT {
32  size = (std::max)(size, stack_traits::minimum_size());
33  size = stack_traits::is_unbounded() ? size : (std::min)(size, stack_traits::maximum_size());
34 
35  std::size_t size_ = stack_traits::round_to_page_size(size) + stack_traits::page_size();
36  assert(size > 0 && size_ > 0);
37 
38  void *start_ptr = ::VirtualAlloc(0, size_, MEM_COMMIT, PAGE_READWRITE);
39  if (!start_ptr) {
40  ctx.sp = NULL;
41  return;
42  }
43 
44  // memset(start_ptr, 0, size_);
45  DWORD old_options;
46  ::VirtualProtect(start_ptr, stack_traits::page_size(), PAGE_READWRITE | PAGE_GUARD, &old_options);
47 
48  ctx.size = size_;
49  ctx.sp = static_cast<char *>(start_ptr) + ctx.size; // stack down
50  }
51 
52  void stack_allocator_windows::deallocate(stack_context &ctx) UTIL_CONFIG_NOEXCEPT {
53  assert(ctx.sp);
54  assert(stack_traits::minimum_size() <= ctx.size);
55  assert(stack_traits::is_unbounded() || (stack_traits::maximum_size() >= ctx.size));
56 
57  void *start_ptr = static_cast<char *>(ctx.sp) - ctx.size;
58  ::VirtualFree(start_ptr, 0, MEM_RELEASE);
59  }
60  }
61 }
62 
63 #ifdef COPP_HAS_ABI_HEADERS
64 #include COPP_ABI_SUFFIX
65 #endif
void allocate(stack_context &, std::size_t) UTIL_CONFIG_NOEXCEPT
static std::size_t page_size() COPP_MACRO_NOEXCEPT
static bool is_unbounded() COPP_MACRO_NOEXCEPT
static std::size_t maximum_size() COPP_MACRO_NOEXCEPT
static std::size_t minimum_size() COPP_MACRO_NOEXCEPT
void deallocate(stack_context &) UTIL_CONFIG_NOEXCEPT
static std::size_t round_to_page_size(std::size_t stacksize) COPP_MACRO_NOEXCEPT