issue-567: Allows for overriding system allocator on Windows

[alk@tut.by: minor changes to make mingw build work]
Signed-off-by: Aliaksey Kandratsenka <alk@tut.by>
This commit is contained in:
Petr Hosek 2013-08-23 13:53:35 -07:00 committed by Aliaksey Kandratsenka
parent 4ad16873a0
commit 83aed118e0
5 changed files with 196 additions and 63 deletions

View File

@ -214,6 +214,7 @@ WINDOWS_INCLUDES = src/windows/port.h \
noinst_LTLIBRARIES += libwindows.la
libwindows_la_SOURCES = $(WINDOWS_INCLUDES) \
src/windows/port.cc \
src/windows/system-alloc.cc \
src/windows/ia32_modrm_map.cc \
src/windows/ia32_opcode_map.cc \
src/windows/mini_disassembler.cc \

View File

@ -45,7 +45,6 @@
#include "base/logging.h"
#include "base/spinlock.h"
#include "internal_logging.h"
#include "system-alloc.h"
// -----------------------------------------------------------------------
// Basic libraries
@ -216,68 +215,6 @@ extern "C" int perftools_pthread_once(pthread_once_t *once_control,
}
// -----------------------------------------------------------------------
// These functions replace system-alloc.cc
// The current system allocator declaration (unused here)
SysAllocator* sys_alloc = NULL;
// Number of bytes taken from system.
size_t TCMalloc_SystemTaken = 0;
// This is mostly like MmapSysAllocator::Alloc, except it does these weird
// munmap's in the middle of the page, which is forbidden in windows.
extern PERFTOOLS_DLL_DECL
void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
size_t alignment) {
// Align on the pagesize boundary
const int pagesize = getpagesize();
if (alignment < pagesize) alignment = pagesize;
size = ((size + alignment - 1) / alignment) * alignment;
// Safest is to make actual_size same as input-size.
if (actual_size) {
*actual_size = size;
}
// Ask for extra memory if alignment > pagesize
size_t extra = 0;
if (alignment > pagesize) {
extra = alignment - pagesize;
}
void* result = VirtualAlloc(0, size + extra,
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
if (result == NULL)
return NULL;
TCMalloc_SystemTaken += size + extra;
// Adjust the return memory so it is aligned
uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
size_t adjust = 0;
if ((ptr & (alignment - 1)) != 0) {
adjust = alignment - (ptr & (alignment - 1));
}
ptr += adjust;
return reinterpret_cast<void*>(ptr);
}
extern PERFTOOLS_DLL_DECL
bool TCMalloc_SystemRelease(void* start, size_t length) {
// TODO(csilvers): should I be calling VirtualFree here?
return false;
}
bool RegisterSystemAllocator(SysAllocator *allocator, int priority) {
return false; // we don't allow registration on windows, right now
}
void DumpSystemAllocatorStats(TCMalloc_Printer* printer) {
// We don't dump stats on windows, right now
}
// -----------------------------------------------------------------------
// These functions rework existing functions of the same name in the
// Google codebase.

159
src/windows/system-alloc.cc Normal file
View File

@ -0,0 +1,159 @@
// Copyright (c) 2013, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
// Author: Petr Hosek
#ifndef _WIN32
# error You should only be including windows/system-alloc.cc in a windows environment!
#endif
#include <config.h>
#include <windows.h>
#include <gperftools/malloc_extension.h>
#include "base/logging.h"
#include "base/spinlock.h"
#include "internal_logging.h"
#include "system-alloc.h"
static SpinLock spinlock(SpinLock::LINKER_INITIALIZED);
// The current system allocator declaration
SysAllocator* sys_alloc = NULL;
// Number of bytes taken from system.
size_t TCMalloc_SystemTaken = 0;
class VirtualSysAllocator : public SysAllocator {
public:
VirtualSysAllocator() : SysAllocator() {
}
void* Alloc(size_t size, size_t *actual_size, size_t alignment);
};
static char virtual_space[sizeof(VirtualSysAllocator)];
// This is mostly like MmapSysAllocator::Alloc, except it does these weird
// munmap's in the middle of the page, which is forbidden in windows.
void* VirtualSysAllocator::Alloc(size_t size, size_t *actual_size,
size_t alignment) {
// Align on the pagesize boundary
const int pagesize = getpagesize();
if (alignment < pagesize) alignment = pagesize;
size = ((size + alignment - 1) / alignment) * alignment;
// Safest is to make actual_size same as input-size.
if (actual_size) {
*actual_size = size;
}
// Ask for extra memory if alignment > pagesize
size_t extra = 0;
if (alignment > pagesize) {
extra = alignment - pagesize;
}
void* result = VirtualAlloc(0, size + extra,
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
if (result == NULL)
return NULL;
// Adjust the return memory so it is aligned
uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
size_t adjust = 0;
if ((ptr & (alignment - 1)) != 0) {
adjust = alignment - (ptr & (alignment - 1));
}
ptr += adjust;
return reinterpret_cast<void*>(ptr);
}
#ifdef _MSC_VER
extern "C" SysAllocator* tc_get_sysalloc_override(SysAllocator *def);
extern "C" SysAllocator* tc_get_sysalloc_default(SysAllocator *def)
{
return def;
}
#if defined(_M_IX86)
#pragma comment(linker, "/alternatename:_tc_get_sysalloc_override=_tc_get_sysalloc_default")
#elif defined(_M_X64)
#pragma comment(linker, "/alternatename:tc_get_sysalloc_override=tc_get_sysalloc_default")
#endif
#else // !_MSC_VER
extern "C" ATTRIBUTE_NOINLINE
SysAllocator* tc_get_sysalloc_override(SysAllocator *def)
{
return def;
}
#endif
static bool system_alloc_inited = false;
void InitSystemAllocators(void) {
VirtualSysAllocator *alloc = new (virtual_space) VirtualSysAllocator();
sys_alloc = tc_get_sysalloc_override(alloc);
}
extern PERFTOOLS_DLL_DECL
void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
size_t alignment) {
SpinLockHolder lock_holder(&spinlock);
if (!system_alloc_inited) {
InitSystemAllocators();
system_alloc_inited = true;
}
void* result = sys_alloc->Alloc(size, actual_size, alignment);
if (result != NULL) {
if (actual_size) {
TCMalloc_SystemTaken += *actual_size;
} else {
TCMalloc_SystemTaken += size;
}
}
return result;
}
extern PERFTOOLS_DLL_DECL
bool TCMalloc_SystemRelease(void* start, size_t length) {
// TODO(csilvers): should I be calling VirtualFree here?
return false;
}
bool RegisterSystemAllocator(SysAllocator *allocator, int priority) {
return false; // we don't allow registration on windows, right now
}
void DumpSystemAllocatorStats(TCMalloc_Printer* printer) {
// We don't dump stats on windows, right now
}

View File

@ -452,6 +452,23 @@
RuntimeLibrary="2"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\windows\system-alloc.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
RuntimeLibrary="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
RuntimeLibrary="2"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\raw_printer.cc">
<FileConfiguration

View File

@ -488,6 +488,25 @@
RuntimeLibrary="2"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\windows\system-alloc.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D PERFTOOLS_DLL_DECL="
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
RuntimeLibrary="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D PERFTOOLS_DLL_DECL="
AdditionalIncludeDirectories="..\..\src\windows; ..\..\src"
RuntimeLibrary="2"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\raw_printer.cc">
<FileConfiguration