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