From eb571cb86d7a3c0fc08ce769dbcee8fe63132878 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 15 Oct 2019 09:59:19 +0300 Subject: [PATCH] New macro to avoid system-wide new/delete inlining in gc_cpp.h (Win32) (fix of commit 3d784ed) * doc/README.macros (GC_NO_INLINE_STD_NEW): Document. * gc_cpp.cc [(_MSC_VER || __DMC__) && GC_NO_INLINE_STD_NEW && GC_NEW_DELETE_NEED_THROW] (GC_DECL_NEW_THROW): Define. * gc_cpp.cc [(_MSC_VER || __DMC__) && GC_NO_INLINE_STD_NEW] (operator new, operator delete): Likewise. * include/gc_cpp.h [_MSC_VER || __DMC__ || (__BORLANDC__ || __CYGWIN__ || __MINGW32__ || __WATCOMC__) && !GC_BUILD && !GC_NOT_DLL] (operator new, operator delete): Do not define inline function if GC_NO_INLINE_STD_NEW. * gc_cpp.cc [GC_NO_INLINE_STD_NEW && _MSC_VER] (operator new, operator delete): Declare; move comment. --- doc/README.macros | 4 ++++ gc_cpp.cc | 30 ++++++++++++++++++++++++++++-- include/gc_cpp.h | 25 ++++++++++++++++++++----- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/doc/README.macros b/doc/README.macros index 3ce176cf..5d4a198b 100644 --- a/doc/README.macros +++ b/doc/README.macros @@ -57,6 +57,10 @@ _ENABLE_ARRAYNEW operator new[] and delete[] are separately overloadable. Used in gc_cpp.h. +GC_NO_INLINE_STD_NEW Tested by gc_cpp.cc and gc_cpp.h. MS Windows only. + Define the system-wide new and delete operators in gccpp.dll + instead of providing an inline version of the operators. + _DLL Tested by gc_config_macros.h. Defined by Visual C++ if runtime dynamic libraries are in use. Used (only if none of GC_DLL, GC_NOT_DLL, __GNUC__ are defined) to test whether diff --git a/gc_cpp.cc b/gc_cpp.cc index 92a35b92..300b24e8 100644 --- a/gc_cpp.cc +++ b/gc_cpp.cc @@ -44,7 +44,7 @@ GC_API void GC_CALL GC_throw_bad_alloc() { GC_ALLOCATOR_THROW_OR_ABORT(); } -#if !defined(_MSC_VER) && !defined(__DMC__) +#if !(defined(_MSC_VER) || defined(__DMC__)) || defined(GC_NO_INLINE_STD_NEW) # if !defined(GC_NEW_DELETE_THROW_NOT_NEEDED) \ && !defined(GC_NEW_DELETE_NEED_THROW) && GC_GNUC_PREREQ(4, 2) \ @@ -71,6 +71,23 @@ GC_API void GC_CALL GC_throw_bad_alloc() { return obj; } +# ifdef _MSC_VER + // This new operator is used by VC++ in case of Debug builds. + void* operator new(size_t size, int /* nBlockUse */, + const char* szFileName, int nLine) + { +# ifdef GC_DEBUG + void* obj = GC_debug_malloc_uncollectable(size, szFileName, nLine); +# else + void* obj = GC_MALLOC_UNCOLLECTABLE(size); + (void)szFileName; (void)nLine; +# endif + if (0 == obj) + GC_ALLOCATOR_THROW_OR_ABORT(); + return obj; + } +# endif // _MSC_VER + void operator delete(void* obj) GC_NOEXCEPT { GC_FREE(obj); } @@ -83,6 +100,15 @@ GC_API void GC_CALL GC_throw_bad_alloc() { return obj; } +# ifdef _MSC_VER + // This new operator is used by VC++ 7+ in Debug builds. + void* operator new[](size_t size, int nBlockUse, + const char* szFileName, int nLine) + { + return operator new(size, nBlockUse, szFileName, nLine); + } +# endif // _MSC_VER + void operator delete[](void* obj) GC_NOEXCEPT { GC_FREE(obj); } @@ -102,4 +128,4 @@ GC_API void GC_CALL GC_throw_bad_alloc() { # endif # endif // C++14 -#endif // !_MSC_VER +#endif // !_MSC_VER && !__DMC__ || GC_NO_INLINE_STD_NEW diff --git a/include/gc_cpp.h b/include/gc_cpp.h index a1993188..e2c062de 100644 --- a/include/gc_cpp.h +++ b/include/gc_cpp.h @@ -306,16 +306,13 @@ inline void* operator new(size_t size, GC_NS_QUALIFY(GCPlacement) gcp, void*) GC_NOEXCEPT; #endif +#ifndef GC_NO_INLINE_STD_NEW + #if defined(_MSC_VER) || defined(__DMC__) \ || ((defined(__BORLANDC__) || defined(__CYGWIN__) \ || defined(__CYGWIN32__) || defined(__MINGW32__) \ || defined(__WATCOMC__)) \ && !defined(GC_BUILD) && !defined(GC_NOT_DLL)) - // The following ensures that the system default operator new[] does not - // get undefined, which is what seems to happen on VC++ 6 for some reason - // if we define a multi-argument operator new[]. - // There seems to be no way to redirect new in this environment without - // including this everywhere. // Inlining done to avoid mix up of new and delete operators by VC++ 9 (due // to arbitrary ordering during linking). @@ -392,6 +389,24 @@ inline void* operator new(size_t size, GC_NS_QUALIFY(GCPlacement) gcp, #endif // _MSC_VER +#elif defined(_MSC_VER) + // The following ensures that the system default operator new[] does not + // get undefined, which is what seems to happen on VC++ 6 for some reason + // if we define a multi-argument operator new[]. + // There seems to be no way to redirect new in this environment without + // including this everywhere. +# ifdef GC_OPERATOR_NEW_ARRAY + void *operator new[](size_t size); + void operator delete[](void* obj); +# endif + + void* operator new(size_t size); + void operator delete(void* obj); + + void* operator new(size_t size, int /* nBlockUse */, + const char * szFileName, int nLine); +#endif // GC_NO_INLINE_STD_NEW && _MSC_VER + #ifdef GC_OPERATOR_NEW_ARRAY // The operator new for arrays, identical to the above. inline void* operator new[](size_t size, GC_NS_QUALIFY(GCPlacement) gcp, -- 2.40.0