blob: 9cec5d7cad09a5c81dcd57ff681b53d4b735fd11 [file] [log] [blame]
// 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