1 // Copyright 2011 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_ZONE_H_ 29 #define V8_ZONE_H_ 30 31 namespace v8 { 32 namespace internal { 33 34 35 // Zone scopes are in one of two modes. Either they delete the zone 36 // on exit or they do not. 37 enum ZoneScopeMode { 38 DELETE_ON_EXIT, 39 DONT_DELETE_ON_EXIT 40 }; 41 42 class Segment; 43 44 // The Zone supports very fast allocation of small chunks of 45 // memory. The chunks cannot be deallocated individually, but instead 46 // the Zone supports deallocating all chunks in one fast 47 // operation. The Zone is used to hold temporary data structures like 48 // the abstract syntax tree, which is deallocated after compilation. 49 50 // Note: There is no need to initialize the Zone; the first time an 51 // allocation is attempted, a segment of memory will be requested 52 // through a call to malloc(). 53 54 // Note: The implementation is inherently not thread safe. Do not use 55 // from multi-threaded code. 56 57 class Zone { 58 public: 59 // Allocate 'size' bytes of memory in the Zone; expands the Zone by 60 // allocating new segments of memory on demand using malloc(). 61 inline void* New(int size); 62 63 template <typename T> 64 inline T* NewArray(int length); 65 66 // Delete all objects and free all memory allocated in the Zone. 67 void DeleteAll(); 68 69 // Returns true if more memory has been allocated in zones than 70 // the limit allows. 71 inline bool excess_allocation(); 72 73 inline void adjust_segment_bytes_allocated(int delta); 74 75 static unsigned allocation_size_; 76 77 private: 78 friend class Isolate; 79 friend class ZoneScope; 80 81 // All pointers returned from New() have this alignment. 82 static const int kAlignment = kPointerSize; 83 84 // Never allocate segments smaller than this size in bytes. 85 static const int kMinimumSegmentSize = 8 * KB; 86 87 // Never allocate segments larger than this size in bytes. 88 static const int kMaximumSegmentSize = 1 * MB; 89 90 // Never keep segments larger than this size in bytes around. 91 static const int kMaximumKeptSegmentSize = 64 * KB; 92 93 // Report zone excess when allocation exceeds this limit. 94 int zone_excess_limit_; 95 96 // The number of bytes allocated in segments. Note that this number 97 // includes memory allocated from the OS but not yet allocated from 98 // the zone. 99 int segment_bytes_allocated_; 100 101 // Each isolate gets its own zone. 102 Zone(); 103 104 // Expand the Zone to hold at least 'size' more bytes and allocate 105 // the bytes. Returns the address of the newly allocated chunk of 106 // memory in the Zone. Should only be called if there isn't enough 107 // room in the Zone already. 108 Address NewExpand(int size); 109 110 // Creates a new segment, sets it size, and pushes it to the front 111 // of the segment chain. Returns the new segment. 112 Segment* NewSegment(int size); 113 114 // Deletes the given segment. Does not touch the segment chain. 115 void DeleteSegment(Segment* segment, int size); 116 117 // The free region in the current (front) segment is represented as 118 // the half-open interval [position, limit). The 'position' variable 119 // is guaranteed to be aligned as dictated by kAlignment. 120 Address position_; 121 Address limit_; 122 123 int scope_nesting_; 124 125 Segment* segment_head_; 126 Isolate* isolate_; 127 }; 128 129 130 // ZoneObject is an abstraction that helps define classes of objects 131 // allocated in the Zone. Use it as a base class; see ast.h. 132 class ZoneObject { 133 public: 134 // Allocate a new ZoneObject of 'size' bytes in the Zone. 135 inline void* operator new(size_t size); 136 inline void* operator new(size_t size, Zone* zone); 137 138 // Ideally, the delete operator should be private instead of 139 // public, but unfortunately the compiler sometimes synthesizes 140 // (unused) destructors for classes derived from ZoneObject, which 141 // require the operator to be visible. MSVC requires the delete 142 // operator to be public. 143 144 // ZoneObjects should never be deleted individually; use 145 // Zone::DeleteAll() to delete all zone objects in one go. 146 void operator delete(void*, size_t) { UNREACHABLE(); } 147 }; 148 149 150 class AssertNoZoneAllocation { 151 public: 152 inline AssertNoZoneAllocation(); 153 inline ~AssertNoZoneAllocation(); 154 private: 155 bool prev_; 156 }; 157 158 159 // The ZoneListAllocationPolicy is used to specialize the GenericList 160 // implementation to allocate ZoneLists and their elements in the 161 // Zone. 162 class ZoneListAllocationPolicy { 163 public: 164 // Allocate 'size' bytes of memory in the zone. 165 static inline void* New(int size); 166 167 // De-allocation attempts are silently ignored. 168 static void Delete(void* p) { } 169 }; 170 171 172 // ZoneLists are growable lists with constant-time access to the 173 // elements. The list itself and all its elements are allocated in the 174 // Zone. ZoneLists cannot be deleted individually; you can delete all 175 // objects in the Zone by calling Zone::DeleteAll(). 176 template<typename T> 177 class ZoneList: public List<T, ZoneListAllocationPolicy> { 178 public: 179 // Construct a new ZoneList with the given capacity; the length is 180 // always zero. The capacity must be non-negative. 181 explicit ZoneList(int capacity) 182 : List<T, ZoneListAllocationPolicy>(capacity) { } 183 184 // Construct a new ZoneList by copying the elements of the given ZoneList. 185 explicit ZoneList(const ZoneList<T>& other) 186 : List<T, ZoneListAllocationPolicy>(other.length()) { 187 AddAll(other); 188 } 189 }; 190 191 192 // Introduce a convenience type for zone lists of map handles. 193 typedef ZoneList<Handle<Map> > ZoneMapList; 194 195 196 // ZoneScopes keep track of the current parsing and compilation 197 // nesting and cleans up generated ASTs in the Zone when exiting the 198 // outer-most scope. 199 class ZoneScope BASE_EMBEDDED { 200 public: 201 // TODO(isolates): pass isolate pointer here. 202 inline explicit ZoneScope(ZoneScopeMode mode); 203 204 virtual ~ZoneScope(); 205 206 inline bool ShouldDeleteOnExit(); 207 208 // For ZoneScopes that do not delete on exit by default, call this 209 // method to request deletion on exit. 210 void DeleteOnExit() { 211 mode_ = DELETE_ON_EXIT; 212 } 213 214 inline static int nesting(); 215 216 private: 217 Isolate* isolate_; 218 ZoneScopeMode mode_; 219 }; 220 221 222 // A zone splay tree. The config type parameter encapsulates the 223 // different configurations of a concrete splay tree (see splay-tree.h). 224 // The tree itself and all its elements are allocated in the Zone. 225 template <typename Config> 226 class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> { 227 public: 228 ZoneSplayTree() 229 : SplayTree<Config, ZoneListAllocationPolicy>() {} 230 ~ZoneSplayTree(); 231 }; 232 233 234 } } // namespace v8::internal 235 236 #endif // V8_ZONE_H_ 237