diff options
author | Petr Hosek <phosek@chromium.org> | 2013-08-23 13:53:35 -0700 |
---|---|---|
committer | Aliaksey Kandratsenka <alk@tut.by> | 2013-09-21 09:00:29 -0700 |
commit | 83aed118e009b92ea88645ef1f7b842a921612c5 (patch) | |
tree | 1a370bf56bba88302d0d1996290f177be565d68f | |
parent | 4ad16873a0a2d8861a0bfe8234d45e31cc70ee90 (diff) | |
download | gperftools-83aed118e009b92ea88645ef1f7b842a921612c5.tar.gz |
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>
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/windows/port.cc | 63 | ||||
-rw-r--r-- | src/windows/system-alloc.cc | 159 | ||||
-rwxr-xr-x | vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj | 17 | ||||
-rwxr-xr-x | vsprojects/tmu-static/tmu-static.vcproj | 19 |
5 files changed, 196 insertions, 63 deletions
diff --git a/Makefile.am b/Makefile.am index ed0fb66..d269ed0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/src/windows/port.cc b/src/windows/port.cc index 249a2aa..4aaa6c1 100644 --- a/src/windows/port.cc +++ b/src/windows/port.cc @@ -45,7 +45,6 @@ #include "base/logging.h" #include "base/spinlock.h" #include "internal_logging.h" -#include "system-alloc.h" // ----------------------------------------------------------------------- // Basic libraries @@ -217,68 +216,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. diff --git a/src/windows/system-alloc.cc b/src/windows/system-alloc.cc new file mode 100644 index 0000000..91bc3e8 --- /dev/null +++ b/src/windows/system-alloc.cc @@ -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 +} diff --git a/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj b/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj index f71a689..de5be53 100755 --- a/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj +++ b/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj @@ -453,6 +453,23 @@ </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
Name="Debug|Win32">
diff --git a/vsprojects/tmu-static/tmu-static.vcproj b/vsprojects/tmu-static/tmu-static.vcproj index 3b1db32..abb73b5 100755 --- a/vsprojects/tmu-static/tmu-static.vcproj +++ b/vsprojects/tmu-static/tmu-static.vcproj @@ -489,6 +489,25 @@ </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
Name="Debug|Win32">
|