1 // Copyright 2008 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_ALLOCATION_H_ 29 #define V8_ALLOCATION_H_ 30 31 namespace v8 { 32 namespace internal { 33 34 35 // A class that controls whether allocation is allowed. This is for 36 // the C++ heap only! 37 class NativeAllocationChecker { 38 public: 39 typedef enum { ALLOW, DISALLOW } NativeAllocationAllowed; 40 explicit inline NativeAllocationChecker(NativeAllocationAllowed allowed) 41 : allowed_(allowed) { 42 #ifdef DEBUG 43 if (allowed == DISALLOW) { 44 allocation_disallowed_++; 45 } 46 #endif 47 } 48 ~NativeAllocationChecker() { 49 #ifdef DEBUG 50 if (allowed_ == DISALLOW) { 51 allocation_disallowed_--; 52 } 53 #endif 54 ASSERT(allocation_disallowed_ >= 0); 55 } 56 static inline bool allocation_allowed() { 57 return allocation_disallowed_ == 0; 58 } 59 private: 60 // This static counter ensures that NativeAllocationCheckers can be nested. 61 static int allocation_disallowed_; 62 // This flag applies to this particular instance. 63 NativeAllocationAllowed allowed_; 64 }; 65 66 67 // Superclass for classes managed with new & delete. 68 class Malloced { 69 public: 70 void* operator new(size_t size) { return New(size); } 71 void operator delete(void* p) { Delete(p); } 72 73 static void FatalProcessOutOfMemory(); 74 static void* New(size_t size); 75 static void Delete(void* p); 76 }; 77 78 79 // A macro is used for defining the base class used for embedded instances. 80 // The reason is some compilers allocate a minimum of one word for the 81 // superclass. The macro prevents the use of new & delete in debug mode. 82 // In release mode we are not willing to pay this overhead. 83 84 #ifdef DEBUG 85 // Superclass for classes with instances allocated inside stack 86 // activations or inside other objects. 87 class Embedded { 88 public: 89 void* operator new(size_t size); 90 void operator delete(void* p); 91 }; 92 #define BASE_EMBEDDED : public Embedded 93 #else 94 #define BASE_EMBEDDED 95 #endif 96 97 98 // Superclass for classes only using statics. 99 class AllStatic { 100 #ifdef DEBUG 101 public: 102 void* operator new(size_t size); 103 void operator delete(void* p); 104 #endif 105 }; 106 107 108 template <typename T> 109 static T* NewArray(int size) { 110 ASSERT(NativeAllocationChecker::allocation_allowed()); 111 T* result = new T[size]; 112 if (result == NULL) Malloced::FatalProcessOutOfMemory(); 113 return result; 114 } 115 116 117 template <typename T> 118 static void DeleteArray(T* array) { 119 delete[] array; 120 } 121 122 123 // The normal strdup functions use malloc. These versions of StrDup 124 // and StrNDup uses new and calls the FatalProcessOutOfMemory handler 125 // if allocation fails. 126 char* StrDup(const char* str); 127 char* StrNDup(const char* str, int n); 128 129 130 // Allocation policy for allocating in the C free store using malloc 131 // and free. Used as the default policy for lists. 132 class FreeStoreAllocationPolicy { 133 public: 134 INLINE(static void* New(size_t size)) { return Malloced::New(size); } 135 INLINE(static void Delete(void* p)) { Malloced::Delete(p); } 136 }; 137 138 139 // Allocation policy for allocating in preallocated space. 140 // Used as an allocation policy for ScopeInfo when generating 141 // stack traces. 142 class PreallocatedStorage : public AllStatic { 143 public: 144 explicit PreallocatedStorage(size_t size); 145 size_t size() { return size_; } 146 static void* New(size_t size); 147 static void Delete(void* p); 148 149 // Preallocate a set number of bytes. 150 static void Init(size_t size); 151 152 private: 153 size_t size_; 154 PreallocatedStorage* previous_; 155 PreallocatedStorage* next_; 156 static bool preallocated_; 157 158 static PreallocatedStorage in_use_list_; 159 static PreallocatedStorage free_list_; 160 161 void LinkTo(PreallocatedStorage* other); 162 void Unlink(); 163 DISALLOW_IMPLICIT_CONSTRUCTORS(PreallocatedStorage); 164 }; 165 166 167 } } // namespace v8::internal 168 169 #endif // V8_ALLOCATION_H_ 170