1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sal.hxx" 26 27 #ifdef WNT /* avoid 'std::bad_alloc' unresolved externals */ 28 #define _CRTIMP 29 #define _NTSDK 30 #endif /* WNT */ 31 32 #ifndef INCLUDED_ALGORITHM 33 #include <algorithm> 34 #define INCLUDED_ALGORITHM 35 #endif 36 37 #ifndef INCLUDED_NEW 38 #include <new> 39 #define INCLUDED_NEW 40 #endif 41 42 #ifndef INCLUDED_STRING_H 43 #include <string.h> 44 #define INCLUDED_STRING_H 45 #endif 46 #include <osl/diagnose.h> 47 #include <rtl/alloc.h> 48 49 using std::nothrow_t; 50 51 // ======================================================================= 52 // AllocatorTraits 53 // ======================================================================= 54 55 namespace 56 { 57 58 struct AllocatorTraits 59 { 60 typedef char const signature_type[8]; 61 const signature_type & m_signature; 62 63 explicit AllocatorTraits (signature_type const & s) SAL_THROW(()) 64 : m_signature (s) 65 {} 66 67 std::size_t size (std::size_t n) const SAL_THROW(()) 68 { 69 n = std::max(n, std::size_t(1)); 70 #if OSL_DEBUG_LEVEL > 0 71 # ifdef NEED_ALIGN16 72 n += 2*sizeof(signature_type); 73 # else 74 n += sizeof(signature_type); 75 # endif 76 #endif /* OSL_DEBUG_LEVEL */ 77 return n; 78 } 79 80 void* init (void * p) const SAL_THROW(()) 81 { 82 #if OSL_DEBUG_LEVEL > 0 83 memcpy (p, m_signature, sizeof(signature_type)); 84 # ifdef NEED_ALIGN16 85 p = static_cast<char*>(p) + 2*sizeof(signature_type); 86 # else 87 p = static_cast<char*>(p) + sizeof(signature_type); 88 # endif 89 #endif /* OSL_DEBUG_LEVEL */ 90 return p; 91 } 92 93 void* fini (void * p) const SAL_THROW(()) 94 { 95 #if OSL_DEBUG_LEVEL > 0 96 # ifdef NEED_ALIGN16 97 p = static_cast<char*>(p) - 2*sizeof(signature_type); 98 # else 99 p = static_cast<char*>(p) - sizeof(signature_type); 100 # endif 101 if (memcmp (p, m_signature, sizeof(signature_type)) != 0) 102 { 103 OSL_ENSURE(0, "operator delete mismatch"); 104 } 105 #endif /* OSL_DEBUG_LEVEL */ 106 return p; 107 } 108 }; 109 110 // ======================================================================= 111 112 struct VectorTraits : public AllocatorTraits 113 { 114 static const signature_type g_signature; 115 116 VectorTraits() SAL_THROW(()) 117 : AllocatorTraits (g_signature) 118 {} 119 }; 120 121 struct ScalarTraits : public AllocatorTraits 122 { 123 static const signature_type g_signature; 124 125 ScalarTraits() SAL_THROW(()) 126 : AllocatorTraits (g_signature) 127 {} 128 }; 129 130 const AllocatorTraits::signature_type VectorTraits::g_signature = "new[]()"; 131 const AllocatorTraits::signature_type ScalarTraits::g_signature = "new() "; 132 133 } // anonymous namespace 134 135 // ======================================================================= 136 // Allocator 137 // ======================================================================= 138 139 static void default_handler (void) 140 { 141 // Multithreading race in 'std::set_new_handler()' call sequence below. 142 throw std::bad_alloc(); 143 } 144 145 // ======================================================================= 146 147 static void* allocate ( 148 std::size_t n, AllocatorTraits const & rTraits) 149 SAL_THROW((std::bad_alloc)) 150 { 151 n = rTraits.size (n); 152 for (;;) 153 { 154 void * p = rtl_allocateMemory (sal_Size(n)); 155 if (p != 0) 156 return rTraits.init (p); 157 158 std::new_handler d = default_handler, f = std::set_new_handler (d); 159 if (f != d) 160 std::set_new_handler (f); 161 162 if (f == 0) 163 throw std::bad_alloc(); 164 (*f)(); 165 } 166 } 167 168 // ======================================================================= 169 170 static void* allocate ( 171 std::size_t n, AllocatorTraits const & rTraits, std::nothrow_t const &) 172 SAL_THROW(()) 173 { 174 try 175 { 176 return allocate (n, rTraits); 177 } 178 catch (std::bad_alloc const &) 179 { 180 return (0); 181 } 182 } 183 184 // ======================================================================= 185 186 static void deallocate (void * p, AllocatorTraits const & rTraits) 187 SAL_THROW(()) 188 { 189 if (p) 190 { 191 rtl_freeMemory (rTraits.fini(p)); 192 } 193 } 194 195 // ======================================================================= 196 // T * p = new T; delete p; 197 // ======================================================================= 198 199 void* SAL_CALL operator new (std::size_t n) throw (std::bad_alloc) 200 { 201 return allocate (n, ScalarTraits()); 202 } 203 204 // ======================================================================= 205 206 void SAL_CALL operator delete (void * p) throw () 207 { 208 deallocate (p, ScalarTraits()); 209 } 210 211 // ======================================================================= 212 // T * p = new(nothrow) T; delete(nothrow) p; 213 // ======================================================================= 214 215 void* SAL_CALL operator new (std::size_t n, std::nothrow_t const &) throw () 216 { 217 return allocate (n, ScalarTraits(), nothrow_t()); 218 } 219 220 // ======================================================================= 221 222 void SAL_CALL operator delete (void * p, std::nothrow_t const &) throw () 223 { 224 deallocate (p, ScalarTraits()); 225 } 226 227 // ======================================================================= 228 // T * p = new T[n]; delete[] p; 229 // ======================================================================= 230 231 void* SAL_CALL operator new[] (std::size_t n) throw (std::bad_alloc) 232 { 233 return allocate (n, VectorTraits()); 234 } 235 236 // ======================================================================= 237 238 void SAL_CALL operator delete[] (void * p) throw () 239 { 240 deallocate (p, VectorTraits()); 241 } 242 243 // ======================================================================= 244 // T * p = new(nothrow) T[n]; delete(nothrow)[] p; 245 // ======================================================================= 246 247 void* SAL_CALL operator new[] (std::size_t n, std::nothrow_t const &) throw () 248 { 249 return allocate (n, VectorTraits(), nothrow_t()); 250 } 251 252 // ======================================================================= 253 254 void SAL_CALL operator delete[] (void * p, std::nothrow_t const &) throw () 255 { 256 deallocate (p, VectorTraits()); 257 } 258 259 // ======================================================================= 260