00001 // Copyright 2008 the V8 project authors. All rights reserved. 00002 // Redistribution and use in source and binary forms, with or without 00003 // modification, are permitted provided that the following conditions are 00004 // met: 00005 // 00006 // * Redistributions of source code must retain the above copyright 00007 // notice, this list of conditions and the following disclaimer. 00008 // * Redistributions in binary form must reproduce the above 00009 // copyright notice, this list of conditions and the following 00010 // disclaimer in the documentation and/or other materials provided 00011 // with the distribution. 00012 // * Neither the name of Google Inc. nor the names of its 00013 // contributors may be used to endorse or promote products derived 00014 // from this software without specific prior written permission. 00015 // 00016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00017 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00018 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00019 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00020 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00021 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00026 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 00028 #ifndef V8_ALLOCATION_H_ 00029 #define V8_ALLOCATION_H_ 00030 00031 namespace v8 { namespace internal { 00032 00033 00034 // A class that controls whether allocation is allowed. This is for 00035 // the C++ heap only! 00036 class NativeAllocationChecker { 00037 public: 00038 typedef enum { ALLOW, DISALLOW } NativeAllocationAllowed; 00039 explicit inline NativeAllocationChecker(NativeAllocationAllowed allowed) 00040 : allowed_(allowed) { 00041 #ifdef DEBUG 00042 if (allowed == DISALLOW) { 00043 allocation_disallowed_++; 00044 } 00045 #endif 00046 } 00047 ~NativeAllocationChecker() { 00048 #ifdef DEBUG 00049 if (allowed_ == DISALLOW) { 00050 allocation_disallowed_--; 00051 } 00052 #endif 00053 ASSERT(allocation_disallowed_ >= 0); 00054 } 00055 static inline bool allocation_allowed() { 00056 return allocation_disallowed_ == 0; 00057 } 00058 private: 00059 // This static counter ensures that NativeAllocationCheckers can be nested. 00060 static int allocation_disallowed_; 00061 // This flag applies to this particular instance. 00062 NativeAllocationAllowed allowed_; 00063 }; 00064 00065 00066 // Superclass for classes managed with new & delete. 00067 class Malloced { 00068 public: 00069 void* operator new(size_t size) { return New(size); } 00070 void operator delete(void* p) { Delete(p); } 00071 00072 static void FatalProcessOutOfMemory(); 00073 static void* New(size_t size); 00074 static void Delete(void* p); 00075 }; 00076 00077 00078 // A macro is used for defining the base class used for embedded instances. 00079 // The reason is some compilers allocate a minimum of one word for the 00080 // superclass. The macro prevents the use of new & delete in debug mode. 00081 // In release mode we are not willing to pay this overhead. 00082 00083 #ifdef DEBUG 00084 // Superclass for classes with instances allocated inside stack 00085 // activations or inside other objects. 00086 class Embedded { 00087 public: 00088 void* operator new(size_t size); 00089 void operator delete(void* p); 00090 }; 00091 #define BASE_EMBEDDED : public Embedded 00092 #else 00093 #define BASE_EMBEDDED 00094 #endif 00095 00096 00097 // Superclass for classes only using statics. 00098 class AllStatic { 00099 #ifdef DEBUG 00100 public: 00101 void* operator new(size_t size); 00102 void operator delete(void* p); 00103 #endif 00104 }; 00105 00106 00107 template <typename T> 00108 static T* NewArray(int size) { 00109 ASSERT(NativeAllocationChecker::allocation_allowed()); 00110 T* result = new T[size]; 00111 if (result == NULL) Malloced::FatalProcessOutOfMemory(); 00112 return result; 00113 } 00114 00115 00116 template <typename T> 00117 static void DeleteArray(T* array) { 00118 delete[] array; 00119 } 00120 00121 00122 // The normal strdup function uses malloc. This version of StrDup 00123 // uses new and calls the FatalProcessOutOfMemory handler if 00124 // allocation fails. 00125 char* StrDup(const char* str); 00126 00127 00128 // Allocation policy for allocating in the C free store using malloc 00129 // and free. Used as the default policy for lists. 00130 class FreeStoreAllocationPolicy { 00131 public: 00132 INLINE(static void* New(size_t size)) { return Malloced::New(size); } 00133 INLINE(static void Delete(void* p)) { Malloced::Delete(p); } 00134 }; 00135 00136 00137 // Allocation policy for allocating in preallocated space. 00138 // Used as an allocation policy for ScopeInfo when generating 00139 // stack traces. 00140 class PreallocatedStorage : public AllStatic { 00141 public: 00142 explicit PreallocatedStorage(size_t size); 00143 size_t size() { return size_; } 00144 static void* New(size_t size); 00145 static void Delete(void* p); 00146 00147 // Preallocate a set number of bytes. 00148 static void Init(size_t size); 00149 00150 private: 00151 size_t size_; 00152 PreallocatedStorage* previous_; 00153 PreallocatedStorage* next_; 00154 static bool preallocated_; 00155 00156 static PreallocatedStorage in_use_list_; 00157 static PreallocatedStorage free_list_; 00158 00159 void LinkTo(PreallocatedStorage* other); 00160 void Unlink(); 00161 DISALLOW_IMPLICIT_CONSTRUCTORS(PreallocatedStorage); 00162 }; 00163 00164 00165 } } // namespace v8::internal 00166 00167 #endif // V8_ALLOCATION_H_