gc_cpp.cc raw

   1  /*
   2   * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
   3   *
   4   * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
   5   * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
   6   *
   7   * Permission is hereby granted to use or copy this program
   8   * for any purpose, provided the above notices are retained on all copies.
   9   * Permission to modify the code and to distribute modified code is granted,
  10   * provided the above notices are retained, and a notice that the code was
  11   * modified is included with the above copyright notice.
  12   */
  13  
  14  // This implementation module for `gc_cpp.h` file provides an implementation
  15  // of the global operators `new`/`delete` that calls the memory allocator of
  16  // the collector.  All objects allocated by this implementation will be
  17  // uncollectible but part of the root set of the collector.
  18  //
  19  // You should ensure (using implementation-dependent techniques) that the
  20  // linker finds this module before the library that defines the default
  21  // built-in operators `new` and `delete`.
  22  
  23  #ifdef HAVE_CONFIG_H
  24  #  include "config.h"
  25  #endif
  26  
  27  #ifndef GC_BUILD
  28  #  define GC_BUILD
  29  #endif
  30  
  31  #define GC_DONT_INCL_WINDOWS_H
  32  #include "gc/gc.h"
  33  
  34  #ifndef GC_INCLUDE_NEW
  35  #  define GC_INCLUDE_NEW
  36  #endif
  37  #include "gc/gc_cpp.h"
  38  
  39  #if (!defined(_MSC_VER) && !defined(__DMC__) \
  40       || defined(GC_NO_INLINE_STD_NEW))       \
  41      && !defined(GC_INLINE_STD_NEW) && !defined(SKIP_GCCPP_DEFINITIONS)
  42  
  43  #  if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS)
  44  #    define GC_ALLOCATOR_THROW_OR_ABORT() GC_abort_on_oom()
  45  #  else
  46  // Use `bad_alloc()` directly instead of `GC_throw_bad_alloc()` call.
  47  #    define GC_ALLOCATOR_THROW_OR_ABORT() throw std::bad_alloc()
  48  #  endif
  49  
  50  void *
  51  operator new(GC_SIZE_T size) GC_DECL_NEW_THROW
  52  {
  53    void *obj = GC_MALLOC_UNCOLLECTABLE(size);
  54    if (0 == obj)
  55      GC_ALLOCATOR_THROW_OR_ABORT();
  56    return obj;
  57  }
  58  
  59  #  ifdef _MSC_VER
  60  // This operator `new` is used by VC++ in case of `Debug` builds.
  61  void *
  62  operator new(GC_SIZE_T size, int /* `nBlockUse` */, const char *szFileName,
  63               int nLine)
  64  {
  65  #    ifdef GC_DEBUG
  66    void *obj = GC_debug_malloc_uncollectable(size, szFileName, nLine);
  67  #    else
  68    void *obj = GC_MALLOC_UNCOLLECTABLE(size);
  69    (void)szFileName;
  70    (void)nLine;
  71  #    endif
  72    if (0 == obj)
  73      GC_ALLOCATOR_THROW_OR_ABORT();
  74    return obj;
  75  }
  76  #  endif // _MSC_VER
  77  
  78  void
  79  operator delete(void *obj) GC_NOEXCEPT
  80  {
  81    GC_FREE(obj);
  82  }
  83  
  84  #  ifdef GC_OPERATOR_NEW_NOTHROW
  85  void *
  86  operator new(GC_SIZE_T size, const std::nothrow_t &) GC_NOEXCEPT
  87  {
  88    return GC_MALLOC_UNCOLLECTABLE(size);
  89  }
  90  
  91  void
  92  operator delete(void *obj, const std::nothrow_t &) GC_NOEXCEPT
  93  {
  94    GC_FREE(obj);
  95  }
  96  #  endif // GC_OPERATOR_NEW_NOTHROW
  97  
  98  #  if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK)
  99  void *
 100  operator new[](GC_SIZE_T size) GC_DECL_NEW_THROW
 101  {
 102    void *obj = GC_MALLOC_UNCOLLECTABLE(size);
 103    if (0 == obj)
 104      GC_ALLOCATOR_THROW_OR_ABORT();
 105    return obj;
 106  }
 107  
 108  #    ifdef _MSC_VER
 109  // This operator `new` is used by VC++ 7 (or later) in `Debug` builds.
 110  void *
 111  operator new[](GC_SIZE_T size, int nBlockUse, const char *szFileName,
 112                 int nLine)
 113  {
 114    return operator new(size, nBlockUse, szFileName, nLine);
 115  }
 116  #    endif // _MSC_VER
 117  
 118  void
 119  operator delete[](void *obj) GC_NOEXCEPT
 120  {
 121    GC_FREE(obj);
 122  }
 123  
 124  #    ifdef GC_OPERATOR_NEW_NOTHROW
 125  void *
 126  operator new[](GC_SIZE_T size, const std::nothrow_t &) GC_NOEXCEPT
 127  {
 128    return GC_MALLOC_UNCOLLECTABLE(size);
 129  }
 130  
 131  void
 132  operator delete[](void *obj, const std::nothrow_t &) GC_NOEXCEPT
 133  {
 134    GC_FREE(obj);
 135  }
 136  #    endif
 137  #  endif // GC_OPERATOR_NEW_ARRAY
 138  
 139  #  ifdef GC_OPERATOR_SIZED_DELETE
 140  void
 141  operator delete(void *obj, GC_SIZE_T) GC_NOEXCEPT
 142  {
 143    GC_FREE(obj);
 144  }
 145  
 146  #    if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK)
 147  void
 148  operator delete[](void *obj, GC_SIZE_T) GC_NOEXCEPT
 149  {
 150    GC_FREE(obj);
 151  }
 152  #    endif
 153  #  endif // GC_OPERATOR_SIZED_DELETE
 154  
 155  #endif // !_MSC_VER && !__DMC__ || GC_NO_INLINE_STD_NEW
 156