xref: /trunk/main/sal/cpprt/operators_new_delete.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 
size__anon7200b5f80111::AllocatorTraits67     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 
init__anon7200b5f80111::AllocatorTraits80     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 
fini__anon7200b5f80111::AllocatorTraits93     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 
default_handler(void)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 
allocate(std::size_t n,AllocatorTraits const & rTraits)147 static void* allocate (
148     std::size_t n, AllocatorTraits const & rTraits)
149 {
150     n = rTraits.size (n);
151     for (;;)
152     {
153         void * p = rtl_allocateMemory (sal_Size(n));
154         if (p != 0)
155             return rTraits.init (p);
156 
157         std::new_handler d = default_handler, f = std::set_new_handler (d);
158         if (f != d)
159             std::set_new_handler (f);
160 
161         if (f == 0)
162             throw std::bad_alloc();
163         (*f)();
164     }
165 }
166 
167 // =======================================================================
168 
allocate(std::size_t n,AllocatorTraits const & rTraits,std::nothrow_t const &)169 static void* allocate (
170     std::size_t n, AllocatorTraits const & rTraits, std::nothrow_t const &)
171     SAL_THROW(())
172 {
173     try
174     {
175         return allocate (n, rTraits);
176     }
177     catch (std::bad_alloc const &)
178     {
179         return (0);
180     }
181 }
182 
183 // =======================================================================
184 
deallocate(void * p,AllocatorTraits const & rTraits)185 static void deallocate (void * p, AllocatorTraits const & rTraits)
186     SAL_THROW(())
187 {
188     if (p)
189     {
190         rtl_freeMemory (rTraits.fini(p));
191     }
192 }
193 
194 // =======================================================================
195 // T * p = new T; delete p;
196 // =======================================================================
197 
operator new(std::size_t n)198 void* SAL_CALL operator new (std::size_t n)
199 {
200     return allocate (n, ScalarTraits());
201 }
202 
203 // =======================================================================
204 
operator delete(void * p)205 void SAL_CALL operator delete (void * p) throw ()
206 {
207     deallocate (p, ScalarTraits());
208 }
209 
210 // =======================================================================
211 // T * p = new(nothrow) T; delete(nothrow) p;
212 // =======================================================================
213 
operator new(std::size_t n,std::nothrow_t const &)214 void* SAL_CALL operator new (std::size_t n, std::nothrow_t const &) throw ()
215 {
216     return allocate (n, ScalarTraits(), nothrow_t());
217 }
218 
219 // =======================================================================
220 
operator delete(void * p,std::nothrow_t const &)221 void SAL_CALL operator delete (void * p, std::nothrow_t const &) throw ()
222 {
223     deallocate (p, ScalarTraits());
224 }
225 
226 // =======================================================================
227 // T * p = new T[n]; delete[] p;
228 // =======================================================================
229 
operator new[](std::size_t n)230 void* SAL_CALL operator new[] (std::size_t n)
231 {
232     return allocate (n, VectorTraits());
233 }
234 
235 // =======================================================================
236 
operator delete[](void * p)237 void SAL_CALL operator delete[] (void * p) throw ()
238 {
239     deallocate (p, VectorTraits());
240 }
241 
242 // =======================================================================
243 // T * p = new(nothrow) T[n]; delete(nothrow)[] p;
244 // =======================================================================
245 
operator new[](std::size_t n,std::nothrow_t const &)246 void* SAL_CALL operator new[] (std::size_t n, std::nothrow_t const &) throw ()
247 {
248     return allocate (n, VectorTraits(), nothrow_t());
249 }
250 
251 // =======================================================================
252 
operator delete[](void * p,std::nothrow_t const &)253 void SAL_CALL operator delete[] (void * p, std::nothrow_t const &) throw ()
254 {
255     deallocate (p, VectorTraits());
256 }
257 
258 // =======================================================================
259