summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2019-10-15 09:59:19 +0300
committerIvan Maidanski <ivmai@mail.ru>2019-10-15 09:59:19 +0300
commiteb571cb86d7a3c0fc08ce769dbcee8fe63132878 (patch)
treebd059d6ae42c79c34972073de84f92f468910303
parente1eec522eb58c0aa13ca7901d7a179e11e1ee763 (diff)
downloadbdwgc-eb571cb86d7a3c0fc08ce769dbcee8fe63132878.tar.gz
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.
-rw-r--r--doc/README.macros4
-rw-r--r--gc_cpp.cc30
-rw-r--r--include/gc_cpp.h25
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,