summaryrefslogtreecommitdiffstats
path: root/third_party/tcmalloc/chromium/src/windows
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/tcmalloc/chromium/src/windows')
-rw-r--r--third_party/tcmalloc/chromium/src/windows/config.h18
-rw-r--r--third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h18
-rw-r--r--third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h.in116
-rw-r--r--third_party/tcmalloc/chromium/src/windows/mingw.h13
-rw-r--r--third_party/tcmalloc/chromium/src/windows/patch_functions.cc51
-rw-r--r--third_party/tcmalloc/chromium/src/windows/port.cc69
-rw-r--r--third_party/tcmalloc/chromium/src/windows/port.h351
7 files changed, 466 insertions, 170 deletions
diff --git a/third_party/tcmalloc/chromium/src/windows/config.h b/third_party/tcmalloc/chromium/src/windows/config.h
index b5d9bb6..1d93c4f 100644
--- a/third_party/tcmalloc/chromium/src/windows/config.h
+++ b/third_party/tcmalloc/chromium/src/windows/config.h
@@ -92,7 +92,7 @@
#undef HAVE_LINUX_PTRACE_H
/* Define to 1 if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
+#define HAVE_MALLOC_H 1
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@@ -136,6 +136,9 @@
/* Define to 1 if the system has the type `struct mallinfo'. */
#undef HAVE_STRUCT_MALLINFO
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
/* Define to 1 if you have the <sys/prctl.h> header file. */
#undef HAVE_SYS_PRCTL_H
@@ -154,7 +157,7 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
-/* Define to 1 if you have the <sys/ucontext.h> header file. */
+/* <sys/ucontext.h> is broken on redhat 7 */
#undef HAVE_SYS_UCONTEXT_H
/* Define to 1 if you have the <sys/wait.h> header file. */
@@ -172,6 +175,9 @@
/* Define to 1 if you have the <unwind.h> header file. */
#undef HAVE_UNWIND_H
+/* Define to 1 if you have the <valgrind.h> header file. */
+#undef HAVE_VALGRIND_H
+
/* define if your compiler has __attribute__ */
#undef HAVE___ATTRIBUTE__
@@ -187,6 +193,10 @@
/* Define to 1 if int32_t is equivalent to intptr_t */
#undef INT32_EQUALS_INTPTR
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
@@ -200,7 +210,7 @@
#define PACKAGE_NAME "google-perftools"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "google-perftools 1.4"
+#define PACKAGE_STRING "google-perftools 1.7"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "google-perftools"
@@ -209,7 +219,7 @@
#undef PACKAGE_URL
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.4"
+#define PACKAGE_VERSION "1.7"
/* How to access the PC from a struct ucontext */
#undef PC_FROM_UCONTEXT
diff --git a/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h b/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h
index 663b7f9..f6c17f5 100644
--- a/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h
+++ b/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h
@@ -35,12 +35,6 @@
#ifndef TCMALLOC_TCMALLOC_H_
#define TCMALLOC_TCMALLOC_H_
-// Define the version number so folks can check against it
-#define TC_VERSION_MAJOR 1
-#define TC_VERSION_MINOR 4
-#define TC_VERSION_PATCH ""
-#define TC_VERSION_STRING "google-perftools 1.4"
-
// __THROW is defined in glibc systems. It means, counter-intuitively,
// "This function will never throw an exception." It's an optional
// optimization tool, but we may need to use it to match glibc prototypes.
@@ -48,6 +42,11 @@
# define __THROW /* __THROW is just an optimization, so ok to make it "" */
#endif
+// Define the version number so folks can check against it
+#define TC_VERSION_MAJOR 1
+#define TC_VERSION_MINOR 7
+#define TC_VERSION_PATCH ""
+#define TC_VERSION_STRING "google-perftools 1.7"
#include <stdlib.h> // for struct mallinfo, if it's defined
@@ -90,6 +89,13 @@ extern "C" {
PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW;
#endif
+ // This is an alias for MallocExtension::instance()->GetAllocatedSize().
+ // It is equivalent to
+ // OS X: malloc_size()
+ // glibc: malloc_usable_size()
+ // Windows: _msize()
+ PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW;
+
#ifdef __cplusplus
PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) __THROW;
PERFTOOLS_DLL_DECL void* tc_new(size_t size);
diff --git a/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h.in b/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h.in
new file mode 100644
index 0000000..a031b35
--- /dev/null
+++ b/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h.in
@@ -0,0 +1,116 @@
+/* Copyright (c) 2003, 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: Sanjay Ghemawat <opensource@google.com>
+ * .h.in file by Craig Silverstein <opensource@google.com>
+ */
+
+#ifndef TCMALLOC_TCMALLOC_H_
+#define TCMALLOC_TCMALLOC_H_
+
+// __THROW is defined in glibc systems. It means, counter-intuitively,
+// "This function will never throw an exception." It's an optional
+// optimization tool, but we may need to use it to match glibc prototypes.
+#ifndef __THROW /* I guess we're not on a glibc system */
+# define __THROW /* __THROW is just an optimization, so ok to make it "" */
+#endif
+
+// Define the version number so folks can check against it
+#define TC_VERSION_MAJOR @TC_VERSION_MAJOR@
+#define TC_VERSION_MINOR @TC_VERSION_MINOR@
+#define TC_VERSION_PATCH "@TC_VERSION_PATCH@"
+#define TC_VERSION_STRING "google-perftools @TC_VERSION_MAJOR@.@TC_VERSION_MINOR@@TC_VERSION_PATCH@"
+
+#include <stdlib.h> // for struct mallinfo, if it's defined
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef PERFTOOLS_DLL_DECL
+# ifdef _WIN32
+# define PERFTOOLS_DLL_DECL __declspec(dllimport)
+# else
+# define PERFTOOLS_DLL_DECL
+# endif
+#endif
+
+#ifdef __cplusplus
+#include <new> // for std::nothrow_t
+
+extern "C" {
+#endif
+ // Returns a human-readable version string. If major, minor,
+ // and/or patch are not NULL, they are set to the major version,
+ // minor version, and patch-code (a string, usually "").
+ PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,
+ const char** patch) __THROW;
+
+ PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW;
+ PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW;
+ PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) __THROW;
+ PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) __THROW;
+ PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) __THROW;
+
+ PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,
+ size_t __size) __THROW;
+ PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,
+ size_t align, size_t size) __THROW;
+ PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) __THROW;
+ PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) __THROW;
+
+ PERFTOOLS_DLL_DECL void tc_malloc_stats(void) __THROW;
+ PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW;
+#if 0
+ PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW;
+#endif
+
+ // This is an alias for MallocExtension::instance()->GetAllocatedSize().
+ // It is equivalent to
+ // OS X: malloc_size()
+ // glibc: malloc_usable_size()
+ // Windows: _msize()
+ PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW;
+
+#ifdef __cplusplus
+ PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) __THROW;
+ PERFTOOLS_DLL_DECL void* tc_new(size_t size);
+ PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
+ const std::nothrow_t&) __THROW;
+ PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW;
+ PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
+ const std::nothrow_t&) __THROW;
+ PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
+ PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
+ const std::nothrow_t&) __THROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
+ const std::nothrow_t&) __THROW;
+}
+#endif
+
+#endif // #ifndef TCMALLOC_TCMALLOC_H_
diff --git a/third_party/tcmalloc/chromium/src/windows/mingw.h b/third_party/tcmalloc/chromium/src/windows/mingw.h
index e69b5da..747b285 100644
--- a/third_party/tcmalloc/chromium/src/windows/mingw.h
+++ b/third_party/tcmalloc/chromium/src/windows/mingw.h
@@ -45,10 +45,23 @@
# define PERFTOOLS_NO_ALIGNED_MALLOC 1
#endif
+// This must be defined before the windows.h is included. We need at
+// least 0x0400 for mutex.h to have access to TryLock, and at least
+// 0x0501 for patch_functions.cc to have access to GetModuleHandleEx.
+// (This latter is an optimization we could take out if need be.)
+#ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0501
+#endif
+
#include "windows/port.h"
#define HAVE_SNPRINTF 1
+// Some mingw distributions have a pthreads wrapper, but it doesn't
+// work as well as native windows spinlocks (at least for us). So
+// pretend the pthreads wrapper doesn't exist, even when it does.
+#undef HAVE_PTHREAD
+
#endif /* __MINGW32__ */
#endif /* GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_ */
diff --git a/third_party/tcmalloc/chromium/src/windows/patch_functions.cc b/third_party/tcmalloc/chromium/src/windows/patch_functions.cc
index deb841b..f837e7a 100644
--- a/third_party/tcmalloc/chromium/src/windows/patch_functions.cc
+++ b/third_party/tcmalloc/chromium/src/windows/patch_functions.cc
@@ -122,6 +122,11 @@ const char kMangledDeleteArrayNothrow[] = "??_V@YAXPAXABUnothrow_t@std@@@Z";
extern "C" PERFTOOLS_DLL_DECL void _tcmalloc();
void _tcmalloc() { }
+// This is the version needed for windows x64, which has a different
+// decoration scheme which doesn't auto-add a leading underscore.
+extern "C" PERFTOOLS_DLL_DECL void __tcmalloc();
+void __tcmalloc() { }
+
namespace { // most everything here is in an unnamed namespace
typedef void (*GenericFnPtr)();
@@ -175,7 +180,7 @@ class LibcInfo {
kNew, kNewArray, kDelete, kDeleteArray,
kNewNothrow, kNewArrayNothrow, kDeleteNothrow, kDeleteArrayNothrow,
// These are windows-only functions from malloc.h
- k_Msize, k_Expand, k_Aligned_malloc, k_Aligned_free,
+ k_Msize, k_Expand,
kNumFunctions
};
@@ -274,12 +279,12 @@ template<int> class LibcInfoWithPatchFunctions : public LibcInfo {
const std::nothrow_t&) __THROW;
static size_t Perftools__msize(void *ptr) __THROW;
static void* Perftools__expand(void *ptr, size_t size) __THROW;
- static void* Perftools__aligned_malloc(size_t size, size_t alignment) __THROW;
- static void Perftools__aligned_free(void *ptr) __THROW;
// malloc.h also defines these functions:
+ // _aligned_malloc, _aligned_free,
// _recalloc, _aligned_offset_malloc, _aligned_realloc, _aligned_recalloc
// _aligned_offset_realloc, _aligned_offset_recalloc, _malloca, _freea
// But they seem pretty obscure, and I'm fine not overriding them for now.
+ // It may be they all call into malloc/free anyway.
};
// This is a subset of MODDULEENTRY32, that we need for patching.
@@ -300,10 +305,19 @@ struct ModuleEntryCopy {
ModuleEntryCopy(const MODULEINFO& mi) {
this->modBaseAddr = mi.lpBaseOfDll;
this->modBaseSize = mi.SizeOfImage;
- for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++)
- rgProcAddresses[i] = (GenericFnPtr)::GetProcAddress(
+ LPVOID modEndAddr = (char*)mi.lpBaseOfDll + mi.SizeOfImage;
+ for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++) {
+ FARPROC target = ::GetProcAddress(
reinterpret_cast<const HMODULE>(mi.lpBaseOfDll),
LibcInfo::function_name(i));
+ // Sometimes a DLL forwards a function to a function in another
+ // DLL. We don't want to patch those forwarded functions --
+ // they'll get patched when the other DLL is processed.
+ if (target >= modBaseAddr && target < modEndAddr)
+ rgProcAddresses[i] = (GenericFnPtr)target;
+ else
+ rgProcAddresses[i] = (GenericFnPtr)NULL;
+ }
}
};
@@ -390,7 +404,7 @@ const char* const LibcInfo::function_name_[] = {
NULL, // kMangledNewArrayNothrow,
NULL, // kMangledDeleteNothrow,
NULL, // kMangledDeleteArrayNothrow,
- "_msize", "_expand", "_aligned_malloc", "_aligned_free",
+ "_msize", "_expand",
};
// For mingw, I can't patch the new/delete here, because the
@@ -421,14 +435,6 @@ const GenericFnPtr LibcInfo::static_fn_[] = {
#endif
(GenericFnPtr)&::_msize,
(GenericFnPtr)&::_expand,
-#ifdef PERFTOOLS_NO_ALIGNED_MALLOC // for older versions of mingw
- // _aligned_malloc isn't always available in mingw, so don't try to patch.
- (GenericFnPtr)NULL,
- (GenericFnPtr)NULL,
-#else
- (GenericFnPtr)&::_aligned_malloc,
- (GenericFnPtr)&::_aligned_free,
-#endif
};
template<int T> GenericFnPtr LibcInfoWithPatchFunctions<T>::origstub_fn_[] = {
@@ -451,8 +457,6 @@ const GenericFnPtr LibcInfoWithPatchFunctions<T>::perftools_fn_[] = {
(GenericFnPtr)&Perftools_deletearray_nothrow,
(GenericFnPtr)&Perftools__msize,
(GenericFnPtr)&Perftools__expand,
- (GenericFnPtr)&Perftools__aligned_malloc,
- (GenericFnPtr)&Perftools__aligned_free,
};
/*static*/ WindowsInfo::FunctionInfo WindowsInfo::function_info_[] = {
@@ -908,21 +912,6 @@ void* LibcInfoWithPatchFunctions<T>::Perftools__expand(void *ptr,
return NULL;
}
-template<int T>
-void* LibcInfoWithPatchFunctions<T>::Perftools__aligned_malloc(size_t size,
- size_t alignment)
- __THROW {
- void* result = do_memalign_or_cpp_memalign(alignment, size);
- MallocHook::InvokeNewHook(result, size);
- return result;
-}
-
-template<int T>
-void LibcInfoWithPatchFunctions<T>::Perftools__aligned_free(void *ptr) __THROW {
- MallocHook::InvokeDeleteHook(ptr);
- do_free_with_callback(ptr, (void (*)(void*))origstub_fn_[k_Aligned_free]);
-}
-
LPVOID WINAPI WindowsInfo::Perftools_HeapAlloc(HANDLE hHeap, DWORD dwFlags,
DWORD_PTR dwBytes) {
LPVOID result = ((LPVOID (WINAPI *)(HANDLE, DWORD, DWORD_PTR))
diff --git a/third_party/tcmalloc/chromium/src/windows/port.cc b/third_party/tcmalloc/chromium/src/windows/port.cc
index 59b0417..e77468c 100644
--- a/third_party/tcmalloc/chromium/src/windows/port.cc
+++ b/third_party/tcmalloc/chromium/src/windows/port.cc
@@ -35,6 +35,7 @@
# error You should only be including windows/port.cc in a windows environment!
#endif
+#define NOMINMAX // so std::max, below, compiles correctly
#include <config.h>
#include <string.h> // for strlen(), memset(), memcmp()
#include <assert.h>
@@ -43,29 +44,12 @@
#include "port.h"
#include "base/logging.h"
#include "base/spinlock.h"
+#include "internal_logging.h"
#include "system-alloc.h"
// -----------------------------------------------------------------------
// Basic libraries
-// These call the windows _vsnprintf, but always NUL-terminate.
-int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
- if (size == 0) // not even room for a \0?
- return -1; // not what C99 says to do, but what windows does
- str[size-1] = '\0';
- return _vsnprintf(str, size-1, format, ap);
-}
-
-#ifndef HAVE_SNPRINTF
-int snprintf(char *str, size_t size, const char *format, ...) {
- va_list ap;
- va_start(ap, format);
- const int r = vsnprintf(str, size, format, ap);
- va_end(ap);
- return r;
-}
-#endif
-
int getpagesize() {
static int pagesize = 0;
if (pagesize == 0) {
@@ -82,9 +66,22 @@ extern "C" PERFTOOLS_DLL_DECL void* __sbrk(std::ptrdiff_t increment) {
return NULL;
}
+// We need to write to 'stderr' without having windows allocate memory.
+// The safest way is via a low-level call like WriteConsoleA(). But
+// even then we need to be sure to print in small bursts so as to not
+// require memory allocation.
+extern "C" PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len) {
+ // Looks like windows allocates for writes of >80 bytes
+ for (int i = 0; i < len; i += 80) {
+ write(STDERR_FILENO, buf + i, std::min(80, len - i));
+ }
+}
+
+
// -----------------------------------------------------------------------
// Threads code
+// Declared (not extern "C") in thread_cache.h
bool CheckIfKernelSupportsTLS() {
// TODO(csilvers): return true (all win's since win95, at least, support this)
return false;
@@ -105,9 +102,15 @@ bool CheckIfKernelSupportsTLS() {
// Force a reference to p_thread_callback_tcmalloc and p_process_term_tcmalloc
// to prevent whole program optimization from discarding the variables.
#ifdef _MSC_VER
+#if defined(_M_IX86)
#pragma comment(linker, "/INCLUDE:__tls_used")
#pragma comment(linker, "/INCLUDE:_p_thread_callback_tcmalloc")
#pragma comment(linker, "/INCLUDE:_p_process_term_tcmalloc")
+#elif defined(_M_X64)
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:p_thread_callback_tcmalloc")
+#pragma comment(linker, "/INCLUDE:p_process_term_tcmalloc")
+#endif
#endif
// When destr_fn eventually runs, it's supposed to take as its
@@ -173,7 +176,7 @@ BOOL WINAPI DllMain(HINSTANCE h, DWORD dwReason, PVOID pv) {
#endif // #ifdef _MSC_VER
-pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)) {
+extern "C" pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)) {
// Semantics are: we create a new key, and then promise to call
// destr_fn with TlsGetValue(key) when the thread is destroyed
// (as long as TlsGetValue(key) is not NULL).
@@ -187,10 +190,38 @@ pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)) {
return key;
}
+// NOTE: this is Win2K and later. For Win98 we could use a CRITICAL_SECTION...
+extern "C" int perftools_pthread_once(pthread_once_t *once_control,
+ void (*init_routine)(void)) {
+ // Try for a fast path first. Note: this should be an acquire semantics read.
+ // It is on x86 and x64, where Windows runs.
+ if (*once_control != 1) {
+ while (true) {
+ switch (InterlockedCompareExchange(once_control, 2, 0)) {
+ case 0:
+ init_routine();
+ InterlockedExchange(once_control, 1);
+ return 0;
+ case 1:
+ // The initializer has already been executed
+ return 0;
+ default:
+ // The initializer is being processed by another thread
+ SwitchToThread();
+ }
+ }
+ }
+ return 0;
+}
+
// -----------------------------------------------------------------------
// These functions replace system-alloc.cc
+// The current system allocator. Because we don't link with system-alloc.cc,
+// we need to define our own.
+SysAllocator* sys_alloc = NULL;
+
// 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 void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
diff --git a/third_party/tcmalloc/chromium/src/windows/port.h b/third_party/tcmalloc/chromium/src/windows/port.h
index 66745d1..0faba01 100644
--- a/third_party/tcmalloc/chromium/src/windows/port.h
+++ b/third_party/tcmalloc/chromium/src/windows/port.h
@@ -40,8 +40,8 @@
#ifndef GOOGLE_BASE_WINDOWS_H_
#define GOOGLE_BASE_WINDOWS_H_
-// You should never include this file directly, but always include it
-// from either config.h (MSVC) or mingw.h (MinGW/msys).
+/* You should never include this file directly, but always include it
+ from either config.h (MSVC) or mingw.h (MinGW/msys). */
#if !defined(GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_) && \
!defined(GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_)
# error "port.h should only be included from config.h or mingw.h"
@@ -54,21 +54,45 @@
#endif
#include <windows.h>
#include <io.h> /* because we so often use open/close/etc */
+#include <direct.h> /* for _getcwd */
#include <process.h> /* for _getpid */
+#include <limits.h> /* for PATH_MAX */
#include <stdarg.h> /* for va_list */
#include <stdio.h> /* need this to override stdio's (v)snprintf */
-
-// 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i)
-// 4244: otherwise we get problems when substracting two size_t's to an int
-// 4288: VC++7 gets confused when a var is defined in a loop and then after it
-// 4267: too many false positives for "conversion gives possible data loss"
-// 4290: it's ok windows ignores the "throw" directive
-// 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv()
+#include <sys/types.h> /* for _off_t */
+#include <assert.h>
+#include <stdlib.h> /* for rand, srand, _strtoxxx */
+
+/*
+ * 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i)
+ * 4244: otherwise we get problems when substracting two size_t's to an int
+ * 4288: VC++7 gets confused when a var is defined in a loop and then after it
+ * 4267: too many false positives for "conversion gives possible data loss"
+ * 4290: it's ok windows ignores the "throw" directive
+ * 4996: Yes, we're ok using "unsafe" functions like vsnprintf and getenv()
+ */
#ifdef _MSC_VER
#pragma warning(disable:4018 4244 4288 4267 4290 4996)
#endif
-// ----------------------------------- BASIC TYPES
+#ifndef __cplusplus
+/* MSVC does not support C99 */
+# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
+# ifdef _MSC_VER
+# define inline __inline
+# else
+# define inline static
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+# define EXTERN_C extern "C"
+#else
+# define EXTERN_C extern
+#endif
+
+/* ----------------------------------- BASIC TYPES */
#ifndef HAVE_STDINT_H
#ifndef HAVE___INT64 /* we need to have all the __intX names */
@@ -83,53 +107,78 @@ typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
-#endif // #ifndef HAVE_STDINT_H
+#endif /* #ifndef HAVE_STDINT_H */
-// I guess MSVC's <types.h> doesn't include ssize_t by default?
+/* I guess MSVC's <types.h> doesn't include ssize_t by default? */
#ifdef _MSC_VER
typedef intptr_t ssize_t;
#endif
-// ----------------------------------- THREADS
+/* ----------------------------------- THREADS */
-#ifndef HAVE_PTHREAD // not true for MSVC, but may be true for MSYS
+#ifndef HAVE_PTHREAD /* not true for MSVC, but may be true for MSYS */
typedef DWORD pthread_t;
typedef DWORD pthread_key_t;
typedef LONG pthread_once_t;
-enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock
-#define pthread_self GetCurrentThreadId
-#define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2))
+enum { PTHREAD_ONCE_INIT = 0 }; /* important that this be 0! for SpinLock */
+
+inline pthread_t pthread_self(void) {
+ return GetCurrentThreadId();
+}
#ifdef __cplusplus
-// This replaces maybe_threads.{h,cc}
-extern pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)); // in port.cc
-#define perftools_pthread_key_create(pkey, destr_fn) \
- *(pkey) = PthreadKeyCreate(destr_fn)
+inline bool pthread_equal(pthread_t left, pthread_t right) {
+ return left == right;
+}
+
+/* This replaces maybe_threads.{h,cc} */
+EXTERN_C pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)); /* port.cc */
+
+inline int perftools_pthread_key_create(pthread_key_t *pkey,
+ void (*destructor)(void*)) {
+ pthread_key_t key = PthreadKeyCreate(destructor);
+ if (key != TLS_OUT_OF_INDEXES) {
+ *(pkey) = key;
+ return 0;
+ } else {
+ return GetLastError();
+ }
+}
+
inline void* perftools_pthread_getspecific(DWORD key) {
DWORD err = GetLastError();
void* rv = TlsGetValue(key);
if (err) SetLastError(err);
return rv;
}
-#define perftools_pthread_setspecific(key, val) \
- TlsSetValue((key), (val))
-// NOTE: this is Win2K and later. For Win98 we could use a CRITICAL_SECTION...
-#define perftools_pthread_once(once, init) do { \
- if (InterlockedCompareExchange(once, 1, 0) == 0) (init)(); \
-} while (0)
-#endif // __cplusplus
-#endif // HAVE_PTHREAD
-
-// __declspec(thread) isn't usable in a dll opened via LoadLibrary().
-// But it doesn't work to LoadLibrary() us anyway, because of all the
-// things we need to do before main()! So this kind of TLS is safe for us.
+
+inline int perftools_pthread_setspecific(pthread_key_t key, const void *value) {
+ if (TlsSetValue(key, (LPVOID)value))
+ return 0;
+ else
+ return GetLastError();
+}
+
+EXTERN_C int perftools_pthread_once(pthread_once_t *once_control,
+ void (*init_routine)(void));
+
+#endif /* __cplusplus */
+#endif /* HAVE_PTHREAD */
+
+/*
+ * __declspec(thread) isn't usable in a dll opened via LoadLibrary().
+ * But it doesn't work to LoadLibrary() us anyway, because of all the
+ * things we need to do before main()! So this kind of TLS is safe for us.
+ */
#define __thread __declspec(thread)
-// This code is obsolete, but I keep it around in case we are ever in
-// an environment where we can't or don't want to use google spinlocks
-// (from base/spinlock.{h,cc}). In that case, uncommenting this out,
-// and removing spinlock.cc from the build, should be enough to revert
-// back to using native spinlocks.
+/*
+ * This code is obsolete, but I keep it around in case we are ever in
+ * an environment where we can't or don't want to use google spinlocks
+ * (from base/spinlock.{h,cc}). In that case, uncommenting this out,
+ * and removing spinlock.cc from the build, should be enough to revert
+ * back to using native spinlocks.
+ */
#if 0
// Windows uses a spinlock internally for its mutexes, making our life easy!
// However, the Windows spinlock must always be initialized, making life hard,
@@ -197,51 +246,80 @@ class SpinLockHolder { // Acquires a spinlock for as long as the scope lasts
// This keeps us from using base/spinlock.h's implementation of SpinLock.
#define BASE_SPINLOCK_H_ 1
-#endif // #if 0
-
-// This replaces testutil.{h,cc}
-extern PERFTOOLS_DLL_DECL void RunInThread(void (*fn)());
-extern PERFTOOLS_DLL_DECL void RunManyInThread(void (*fn)(), int count);
-extern PERFTOOLS_DLL_DECL void RunManyInThreadWithId(void (*fn)(int), int count,
- int stacksize);
+#endif /* #if 0 */
+/* ----------------------------------- MMAP and other memory allocation */
-// ----------------------------------- MMAP and other memory allocation
-
-#ifndef HAVE_MMAP // not true for MSVC, but may be true for msys
+#ifndef HAVE_MMAP /* not true for MSVC, but may be true for msys */
#define MAP_FAILED 0
-#define MREMAP_FIXED 2 // the value in linux, though it doesn't really matter
-// These, when combined with the mmap invariants below, yield the proper action
+#define MREMAP_FIXED 2 /* the value in linux, though it doesn't really matter */
+/* These, when combined with the mmap invariants below, yield the proper action */
#define PROT_READ PAGE_READWRITE
#define PROT_WRITE PAGE_READWRITE
#define MAP_ANONYMOUS MEM_RESERVE
#define MAP_PRIVATE MEM_COMMIT
-#define MAP_SHARED MEM_RESERVE // value of this #define is 100% arbitrary
+#define MAP_SHARED MEM_RESERVE /* value of this #define is 100% arbitrary */
+
+#if __STDC__
+typedef _off_t off_t;
+#endif
+
+/* VirtualAlloc only replaces for mmap when certain invariants are kept. */
+inline void *mmap(void *addr, size_t length, int prot, int flags,
+ int fd, off_t offset) {
+ if (addr == NULL && fd == -1 && offset == 0 &&
+ prot == (PROT_READ|PROT_WRITE) && flags == (MAP_PRIVATE|MAP_ANONYMOUS)) {
+ return VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ } else {
+ return NULL;
+ }
+}
-// VirtualAlloc is only a replacement for mmap when certain invariants are kept
-#define mmap(start, length, prot, flags, fd, offset) \
- ( (start) == NULL && (fd) == -1 && (offset) == 0 && \
- (prot) == (PROT_READ|PROT_WRITE) && (flags) == (MAP_PRIVATE|MAP_ANONYMOUS)\
- ? VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) \
- : NULL )
+inline int munmap(void *addr, size_t length) {
+ return VirtualFree(addr, 0, MEM_RELEASE) ? 0 : -1;
+}
+#endif /* HAVE_MMAP */
-#define munmap(start, length) (VirtualFree(start, 0, MEM_RELEASE) ? 0 : -1)
-#endif // HAVE_MMAP
+/* We could maybe use VirtualAlloc for sbrk as well, but no need */
+inline void *sbrk(intptr_t increment) {
+ // sbrk returns -1 on failure
+ return (void*)-1;
+}
-// We could maybe use VirtualAlloc for sbrk as well, but no need
-#define sbrk(increment) ( (void*)-1 ) // sbrk returns -1 on failure
+/* ----------------------------------- STRING ROUTINES */
-// ----------------------------------- STRING ROUTINES
+/*
+ * We can't just use _vsnprintf and _snprintf as drop-in-replacements,
+ * because they don't always NUL-terminate. :-( We also can't use the
+ * name vsnprintf, since windows defines that (but not snprintf (!)).
+ */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+/* We can use safe CRT functions, which the required functionality */
+inline int perftools_vsnprintf(char *str, size_t size, const char *format,
+ va_list ap) {
+ return vsnprintf_s(str, size, _TRUNCATE, format, ap);
+}
+#else
+inline int perftools_vsnprintf(char *str, size_t size, const char *format,
+ va_list ap) {
+ if (size == 0) /* not even room for a \0? */
+ return -1; /* not what C99 says to do, but what windows does */
+ str[size-1] = '\0';
+ return _vsnprintf(str, size-1, format, ap);
+}
+#endif
-// We can't just use _vsnprintf and _snprintf as drop-in-replacements,
-// because they don't always NUL-terminate. :-( We also can't use the
-// name vsnprintf, since windows defines that (but not snprintf (!)).
-extern PERFTOOLS_DLL_DECL int snprintf(char *str, size_t size,
- const char *format, ...);
-extern PERFTOOLS_DLL_DECL int safe_vsnprintf(char *str, size_t size,
- const char *format, va_list ap);
-#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
+#ifndef HAVE_SNPRINTF
+inline int snprintf(char *str, size_t size, const char *format, ...) {
+ va_list ap;
+ int r;
+ va_start(ap, format);
+ r = perftools_vsnprintf(str, size, format, ap);
+ va_end(ap);
+ return r;
+}
+#endif
#define PRIx64 "I64x"
#define SCNx64 "I64x"
@@ -256,79 +334,132 @@ extern PERFTOOLS_DLL_DECL int safe_vsnprintf(char *str, size_t size,
# define PRIxPTR "lx"
#endif
-// ----------------------------------- FILE IO
+/* ----------------------------------- FILE IO */
+
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
#ifndef __MINGW32__
enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
#endif
-#define getcwd _getcwd
-#define access _access
-#define open _open
-#define read _read
-#define write _write
-#define lseek _lseek
-#define close _close
-#define popen _popen
-#define pclose _pclose
-#define mkdir(dirname, mode) _mkdir(dirname)
#ifndef O_RDONLY
#define O_RDONLY _O_RDONLY
#endif
-// ----------------------------------- SYSTEM/PROCESS
-typedef int pid_t;
-#define getpid _getpid
-#define getppid() (0)
+#if __STDC__ && !defined(__MINGW32__)
+/* These functions are considered non-standard */
+inline int access(const char *pathname, int mode) {
+ return _access(pathname, mode);
+}
+inline int open(const char *pathname, int flags, int mode = 0) {
+ return _open(pathname, flags, mode);
+}
+inline int close(int fd) {
+ return _close(fd);
+}
+inline ssize_t read(int fd, void *buf, size_t count) {
+ return _read(fd, buf, count);
+}
+inline ssize_t write(int fd, const void *buf, size_t count) {
+ return _write(fd, buf, count);
+}
+inline off_t lseek(int fd, off_t offset, int whence) {
+ return _lseek(fd, offset, whence);
+}
+inline char *getcwd(char *buf, size_t size) {
+ return _getcwd(buf, size);
+}
+inline int mkdir(const char *pathname, int) {
+ return _mkdir(pathname);
+}
+#endif
-// Handle case when poll is used to simulate sleep.
-#define poll(r, w, t) \
- do { \
- assert(r == 0); \
- assert(w == 0); \
- Sleep(t); \
- } while(0)
+inline FILE *popen(const char *command, const char *type) {
+ return _popen(command, type);
+}
+inline int pclose(FILE *stream) {
+ return _pclose(stream);
+}
+
+EXTERN_C PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len);
+
+/* ----------------------------------- SYSTEM/PROCESS */
+
+typedef int pid_t;
+#if __STDC__
+inline pid_t getpid(void) { return _getpid(); }
+#endif
+inline pid_t getppid(void) { return 0; }
+
+/* Handle case when poll is used to simulate sleep. */
+inline int poll(struct pollfd* fds, int nfds, int timeout) {
+ assert(fds == NULL);
+ assert(nfds == 0);
+ Sleep(timeout);
+ return 0;
+}
-extern PERFTOOLS_DLL_DECL int getpagesize(); // in port.cc
+EXTERN_C int getpagesize(); /* in port.cc */
-// ----------------------------------- OTHER
+/* ----------------------------------- OTHER */
-#define srandom srand
-#define random rand
-#define sleep(t) Sleep(t * 1000)
+inline void srandom(unsigned int seed) { srand(seed); }
+inline long random(void) { return rand(); }
+inline unsigned int sleep(unsigned int seconds) {
+ Sleep(seconds * 1000);
+ return 0;
+}
struct timespec {
int tv_sec;
int tv_nsec;
};
-#define nanosleep(tm_ptr, ignored) \
- Sleep((tm_ptr)->tv_sec * 1000 + (tm_ptr)->tv_nsec / 1000000)
+inline int nanosleep(const struct timespec *req, struct timespec *rem) {
+ Sleep(req->tv_sec * 1000 + req->tv_nsec / 1000000);
+ return 0;
+}
#ifndef __MINGW32__
-#define strtoq _strtoi64
-#define strtouq _strtoui64
-#define strtoll _strtoi64
-#define strtoull _strtoui64
-#define atoll _atoi64
+inline long long int strtoll(const char *nptr, char **endptr, int base) {
+ return _strtoi64(nptr, endptr, base);
+}
+inline unsigned long long int strtoull(const char *nptr, char **endptr,
+ int base) {
+ return _strtoui64(nptr, endptr, base);
+}
+inline long long int strtoq(const char *nptr, char **endptr, int base) {
+ return _strtoi64(nptr, endptr, base);
+}
+inline unsigned long long int strtouq(const char *nptr, char **endptr,
+ int base) {
+ return _strtoui64(nptr, endptr, base);
+}
+inline long long atoll(const char *nptr) {
+ return _atoi64(nptr);
+}
#endif
#define __THROW throw()
-// ----------------------------------- TCMALLOC-SPECIFIC
+/* ----------------------------------- TCMALLOC-SPECIFIC */
-// tcmalloc.cc calls this so we can patch VirtualAlloc() et al.
-extern PERFTOOLS_DLL_DECL void PatchWindowsFunctions();
+/* tcmalloc.cc calls this so we can patch VirtualAlloc() et al. */
+extern void PatchWindowsFunctions();
// ----------------------------------- BUILD-SPECIFIC
-// windows/port.h defines compatibility APIs for several .h files, which
-// we therefore shouldn't be #including directly. This hack keeps us from
-// doing so. TODO(csilvers): do something more principled.
+/*
+ * windows/port.h defines compatibility APIs for several .h files, which
+ * we therefore shouldn't be #including directly. This hack keeps us from
+ * doing so. TODO(csilvers): do something more principled.
+ */
#define GOOGLE_MAYBE_THREADS_H_ 1
#endif /* _WIN32 */
+#undef inline
+#undef EXTERN_C
+
#endif /* GOOGLE_BASE_WINDOWS_H_ */