* Fix tcmalloc_unittest on MSVC 10 in release mode (csilvers)
* Fix malloc_hook_c.h to compile with -ansi under gcc (csilvers) git-svn-id: http://gperftools.googlecode.com/svn/trunk@104 6b5cf1ce-ec42-a296-1ba9-69fdba395a50
This commit is contained in:
parent
7375b4f3cb
commit
dd3d9d969e
13
NEWS
13
NEWS
|
@ -1,4 +1,15 @@
|
||||||
== 04 February 2011 ==
|
== 7 February 2011 ==
|
||||||
|
|
||||||
|
Thanks to endlessr..., who
|
||||||
|
[http://code.google.com/p/google-perftools/issues/detail?id=307 identified]
|
||||||
|
why some tests were failing under MSVC 10 in release mode. It does not look
|
||||||
|
like these failures point toward any problem with tcmalloc itself; rather, the
|
||||||
|
problem is with the test, which made some assumptions that broke under the
|
||||||
|
some aggressive optimizations used in MSVC 10. I'll fix the test, but in
|
||||||
|
the meantime, feel free to use perftools even when compiled under MSVC
|
||||||
|
10.
|
||||||
|
|
||||||
|
== 4 February 2011 ==
|
||||||
|
|
||||||
I've just released perftools 1.7
|
I've just released perftools 1.7
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
// Annoying stuff for windows -- makes sure clients can import these functions
|
/* Annoying stuff for windows; makes sure clients can import these functions */
|
||||||
#ifndef PERFTOOLS_DLL_DECL
|
#ifndef PERFTOOLS_DLL_DECL
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
# define PERFTOOLS_DLL_DECL __declspec(dllimport)
|
# define PERFTOOLS_DLL_DECL __declspec(dllimport)
|
||||||
|
@ -49,6 +49,10 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get the current stack trace. Try to skip all routines up to and
|
/* Get the current stack trace. Try to skip all routines up to and
|
||||||
* and including the caller of MallocHook::Invoke*.
|
* and including the caller of MallocHook::Invoke*.
|
||||||
* Use "skip_count" (similarly to GetStackTrace from stacktrace.h)
|
* Use "skip_count" (similarly to GetStackTrace from stacktrace.h)
|
||||||
|
@ -108,4 +112,8 @@ typedef void (*MallocHook_SbrkHook)(const void* result, ptrdiff_t increment);
|
||||||
PERFTOOLS_DLL_DECL
|
PERFTOOLS_DLL_DECL
|
||||||
MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook);
|
MallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _MALLOC_HOOK_C_H_ */
|
#endif /* _MALLOC_HOOK_C_H_ */
|
||||||
|
|
|
@ -871,7 +871,10 @@ static void TestReleaseToSystem() {
|
||||||
#endif // #ifndef DEBUGALLOCATION
|
#endif // #ifndef DEBUGALLOCATION
|
||||||
}
|
}
|
||||||
|
|
||||||
bool g_no_memory = false;
|
// On MSVC10, in release mode, the optimizer convinces itself
|
||||||
|
// g_no_memory is never changed (I guess it doesn't realize OnNoMemory
|
||||||
|
// might be called). Work around this by setting the var volatile.
|
||||||
|
volatile bool g_no_memory = false;
|
||||||
std::new_handler g_old_handler = NULL;
|
std::new_handler g_old_handler = NULL;
|
||||||
static void OnNoMemory() {
|
static void OnNoMemory() {
|
||||||
g_no_memory = true;
|
g_no_memory = true;
|
||||||
|
@ -999,6 +1002,7 @@ static int RunAllTests(int argc, char** argv) {
|
||||||
SetDeleteHook(); // ditto
|
SetDeleteHook(); // ditto
|
||||||
|
|
||||||
void* p1 = malloc(10);
|
void* p1 = malloc(10);
|
||||||
|
CHECK(p1 != NULL); // force use of this variable
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
// Also test the non-standard tc_malloc_size
|
// Also test the non-standard tc_malloc_size
|
||||||
size_t actual_p1_size = tc_malloc_size(p1);
|
size_t actual_p1_size = tc_malloc_size(p1);
|
||||||
|
@ -1009,19 +1013,23 @@ static int RunAllTests(int argc, char** argv) {
|
||||||
|
|
||||||
|
|
||||||
p1 = calloc(10, 2);
|
p1 = calloc(10, 2);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
p1 = realloc(p1, 30);
|
p1 = realloc(p1, 30);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
cfree(p1); // synonym for free
|
cfree(p1); // synonym for free
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
|
||||||
CHECK_EQ(posix_memalign(&p1, sizeof(p1), 40), 0);
|
CHECK_EQ(posix_memalign(&p1, sizeof(p1), 40), 0);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
free(p1);
|
free(p1);
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
|
||||||
p1 = memalign(sizeof(p1) * 2, 50);
|
p1 = memalign(sizeof(p1) * 2, 50);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
free(p1);
|
free(p1);
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
@ -1035,43 +1043,51 @@ static int RunAllTests(int argc, char** argv) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p1 = valloc(60);
|
p1 = valloc(60);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
free(p1);
|
free(p1);
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
|
||||||
p1 = pvalloc(70);
|
p1 = pvalloc(70);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
free(p1);
|
free(p1);
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
|
||||||
char* p2 = new char;
|
char* p2 = new char;
|
||||||
|
CHECK(p2 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
delete p2;
|
delete p2;
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
|
||||||
p2 = new char[100];
|
p2 = new char[100];
|
||||||
|
CHECK(p2 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
delete[] p2;
|
delete[] p2;
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
|
||||||
p2 = new(std::nothrow) char;
|
p2 = new(std::nothrow) char;
|
||||||
|
CHECK(p2 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
delete p2;
|
delete p2;
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
|
||||||
p2 = new(std::nothrow) char[100];
|
p2 = new(std::nothrow) char[100];
|
||||||
|
CHECK(p2 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
delete[] p2;
|
delete[] p2;
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
|
||||||
// Another way of calling operator new
|
// Another way of calling operator new
|
||||||
p2 = static_cast<char*>(::operator new(100));
|
p2 = static_cast<char*>(::operator new(100));
|
||||||
|
CHECK(p2 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
::operator delete(p2);
|
::operator delete(p2);
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
|
||||||
// Try to call nothrow's delete too. Compilers use this.
|
// Try to call nothrow's delete too. Compilers use this.
|
||||||
p2 = static_cast<char*>(::operator new(100, std::nothrow));
|
p2 = static_cast<char*>(::operator new(100, std::nothrow));
|
||||||
|
CHECK(p2 != NULL);
|
||||||
VerifyNewHookWasCalled();
|
VerifyNewHookWasCalled();
|
||||||
::operator delete(p2, std::nothrow);
|
::operator delete(p2, std::nothrow);
|
||||||
VerifyDeleteHookWasCalled();
|
VerifyDeleteHookWasCalled();
|
||||||
|
@ -1087,8 +1103,10 @@ static int RunAllTests(int argc, char** argv) {
|
||||||
int size = 8192*2;
|
int size = 8192*2;
|
||||||
p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE,
|
p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE,
|
||||||
-1, 0);
|
-1, 0);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifyMmapHookWasCalled();
|
VerifyMmapHookWasCalled();
|
||||||
p1 = mremap(p1, size, size/2, 0);
|
p1 = mremap(p1, size, size/2, 0);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifyMremapHookWasCalled();
|
VerifyMremapHookWasCalled();
|
||||||
size /= 2;
|
size /= 2;
|
||||||
munmap(p1, size);
|
munmap(p1, size);
|
||||||
|
@ -1097,6 +1115,7 @@ static int RunAllTests(int argc, char** argv) {
|
||||||
int fd = open("/dev/zero", O_RDONLY);
|
int fd = open("/dev/zero", O_RDONLY);
|
||||||
CHECK_GE(fd, 0); // make sure the open succeeded
|
CHECK_GE(fd, 0); // make sure the open succeeded
|
||||||
p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);
|
p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifyMmapHookWasCalled();
|
VerifyMmapHookWasCalled();
|
||||||
munmap(p1, 8192);
|
munmap(p1, 8192);
|
||||||
VerifyMunmapHookWasCalled();
|
VerifyMunmapHookWasCalled();
|
||||||
|
@ -1115,11 +1134,14 @@ static int RunAllTests(int argc, char** argv) {
|
||||||
#if defined(HAVE_SBRK) && defined(__linux) && \
|
#if defined(HAVE_SBRK) && defined(__linux) && \
|
||||||
(defined(__i386__) || defined(__x86_64__))
|
(defined(__i386__) || defined(__x86_64__))
|
||||||
p1 = sbrk(8192);
|
p1 = sbrk(8192);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifySbrkHookWasCalled();
|
VerifySbrkHookWasCalled();
|
||||||
p1 = sbrk(-8192);
|
p1 = sbrk(-8192);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
VerifySbrkHookWasCalled();
|
VerifySbrkHookWasCalled();
|
||||||
// However, sbrk hook should *not* be called with sbrk(0)
|
// However, sbrk hook should *not* be called with sbrk(0)
|
||||||
p1 = sbrk(0);
|
p1 = sbrk(0);
|
||||||
|
CHECK(p1 != NULL);
|
||||||
CHECK_EQ(g_SbrkHook_calls, 0);
|
CHECK_EQ(g_SbrkHook_calls, 0);
|
||||||
#else // this is just to quiet the compiler: make sure all fns are called
|
#else // this is just to quiet the compiler: make sure all fns are called
|
||||||
IncrementCallsToSbrkHook();
|
IncrementCallsToSbrkHook();
|
||||||
|
|
Loading…
Reference in New Issue