| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // This code should move into the default Windows shim once the win-specific |
| // allocation shim has been removed, and the generic shim has becaome the |
| // default. |
| |
| #include "winheap_stubs_win.h" |
| |
| #include <limits.h> |
| #include <malloc.h> |
| #include <new.h> |
| #include <windows.h> |
| |
| #include "starboard/types.h" |
| |
| namespace base { |
| namespace allocator { |
| |
| bool g_is_win_shim_layer_initialized = false; |
| |
| namespace { |
| |
| const size_t kWindowsPageSize = 4096; |
| const size_t kMaxWindowsAllocation = INT_MAX - kWindowsPageSize; |
| |
| inline HANDLE get_heap_handle() { |
| return reinterpret_cast<HANDLE>(_get_heap_handle()); |
| } |
| |
| } // namespace |
| |
| void* WinHeapMalloc(size_t size) { |
| if (size < kMaxWindowsAllocation) |
| return HeapAlloc(get_heap_handle(), 0, size); |
| return nullptr; |
| } |
| |
| void WinHeapFree(void* ptr) { |
| if (!ptr) |
| return; |
| |
| HeapFree(get_heap_handle(), 0, ptr); |
| } |
| |
| void* WinHeapRealloc(void* ptr, size_t size) { |
| if (!ptr) |
| return WinHeapMalloc(size); |
| if (!size) { |
| WinHeapFree(ptr); |
| return nullptr; |
| } |
| if (size < kMaxWindowsAllocation) |
| return HeapReAlloc(get_heap_handle(), 0, ptr, size); |
| return nullptr; |
| } |
| |
| size_t WinHeapGetSizeEstimate(void* ptr) { |
| if (!ptr) |
| return 0; |
| |
| // Get the user size of the allocation. |
| size_t size = HeapSize(get_heap_handle(), 0, ptr); |
| |
| // Account for the 8-byte HEAP_HEADER preceding the block. |
| size += 8; |
| |
| // Round up to the nearest allocation granularity, which is 8 for |
| // 32 bit machines, and 16 for 64 bit machines. |
| #if defined(ARCH_CPU_64_BITS) |
| const size_t kAllocationGranularity = 16; |
| #else |
| const size_t kAllocationGranularity = 8; |
| #endif |
| |
| return (size + kAllocationGranularity - 1) & ~(kAllocationGranularity - 1); |
| } |
| |
| // Call the new handler, if one has been set. |
| // Returns true on successfully calling the handler, false otherwise. |
| bool WinCallNewHandler(size_t size) { |
| #ifdef _CPPUNWIND |
| #error "Exceptions in allocator shim are not supported!" |
| #endif // _CPPUNWIND |
| // Get the current new handler. |
| _PNH nh = _query_new_handler(); |
| if (!nh) |
| return false; |
| // Since exceptions are disabled, we don't really know if new_handler |
| // failed. Assume it will abort if it fails. |
| return nh(size) ? true : false; |
| } |
| |
| } // namespace allocator |
| } // namespace base |