cxxalloc.h (3174B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef mozilla_cxxalloc_h 6 #define mozilla_cxxalloc_h 7 8 /* 9 * We implement the default operators new/delete as part of 10 * libmozalloc, replacing their definitions in libstdc++. The 11 * operator new* definitions in libmozalloc will never return a NULL 12 * pointer. 13 * 14 * Each operator new immediately below returns a pointer to memory 15 * that can be delete'd by any of 16 * 17 * (1) the matching infallible operator delete immediately below 18 * (2) the matching system |operator delete(void*, std::nothrow)| 19 * (3) the matching system |operator delete(void*) noexcept(false)| 20 * 21 * NB: these are declared |noexcept(false)|, though they will never 22 * throw that exception. This declaration is consistent with the rule 23 * that |::operator new() noexcept(false)| will never return NULL. 24 * 25 * NB: mozilla::fallible can be used instead of std::nothrow. 26 */ 27 28 #ifndef MOZALLOC_EXPORT_NEW 29 # define MOZALLOC_EXPORT_NEW MFBT_API 30 #endif 31 32 MOZALLOC_EXPORT_NEW void* operator new(size_t size) noexcept(false) { 33 return moz_xmalloc(size); 34 } 35 36 MOZALLOC_EXPORT_NEW void* operator new(size_t size, 37 const std::nothrow_t&) noexcept(true) { 38 return malloc_impl(size); 39 } 40 41 MOZALLOC_EXPORT_NEW void* operator new[](size_t size) noexcept(false) { 42 return moz_xmalloc(size); 43 } 44 45 // Inlining `new` like this is technically against C++ spec, but we crave perf. 46 MOZALLOC_EXPORT_NEW void* operator new[](size_t size, 47 const std::nothrow_t&) noexcept(true) { 48 #if defined(__GNUC__) && !defined(__clang__) 49 // GCC-14 codegen at -O2 causes false positive due to converting 50 // `new A[n]` to `malloc(-1)` when `n > PTRDIFF_MAX/sizeof(A)`. 51 // (See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85783, WONTFIX'd) 52 # pragma GCC diagnostic push 53 # pragma GCC diagnostic ignored "-Walloc-size-larger-than=" 54 #endif 55 56 return malloc_impl(size); 57 58 #if defined(__GNUC__) && !defined(__clang__) 59 # pragma GCC diagnostic pop 60 #endif 61 } 62 63 MOZALLOC_EXPORT_NEW void operator delete(void* ptr) noexcept(true) { 64 return free_impl(ptr); 65 } 66 67 MOZALLOC_EXPORT_NEW void operator delete(void* ptr, 68 const std::nothrow_t&) noexcept(true) { 69 return free_impl(ptr); 70 } 71 72 MOZALLOC_EXPORT_NEW void operator delete[](void* ptr) noexcept(true) { 73 return free_impl(ptr); 74 } 75 76 MOZALLOC_EXPORT_NEW void operator delete[]( 77 void* ptr, const std::nothrow_t&) noexcept(true) { 78 return free_impl(ptr); 79 } 80 81 #if defined(XP_WIN) 82 // We provide the global sized delete overloads unconditionally because the 83 // MSVC runtime headers do, despite compiling with /Zc:sizedDealloc- 84 MOZALLOC_EXPORT_NEW void operator delete(void* ptr, 85 size_t /*size*/) noexcept(true) { 86 return free_impl(ptr); 87 } 88 89 MOZALLOC_EXPORT_NEW void operator delete[](void* ptr, 90 size_t /*size*/) noexcept(true) { 91 return free_impl(ptr); 92 } 93 #endif 94 95 #endif /* mozilla_cxxalloc_h */