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