]> granicus.if.org Git - gc/commitdiff
New macro to avoid system-wide new/delete inlining in gc_cpp.h (Win32)
authorIvan Maidanski <ivmai@mail.ru>
Tue, 15 Oct 2019 06:59:19 +0000 (09:59 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 15 Oct 2019 06:59:19 +0000 (09:59 +0300)
(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
gc_cpp.cc
include/gc_cpp.h

index 3ce176cf30122d78ee89155d36b10e55b28bf5ad..5d4a198bf66559614f23f7db2ee08ec74ae9d91d 100644 (file)
@@ -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
index 92a35b92c1e6e27ccb9e513158f8ff58265ee05c..300b24e81eac925b2757142a8fd7258ae9eb8a1b 100644 (file)
--- 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
index a199318885b6a67bc1d09e7f09f3887a196579f5..e2c062de0eca2ad702a7aa061829af7682e197bf 100644 (file)
@@ -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,