OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_ZONE_H_ | 5 #ifndef VM_ZONE_H_ |
6 #define VM_ZONE_H_ | 6 #define VM_ZONE_H_ |
7 | 7 |
8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
9 #include "vm/allocation.h" | 9 #include "vm/allocation.h" |
10 #include "vm/handles.h" | 10 #include "vm/handles.h" |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 } | 110 } |
111 | 111 |
112 // Delete all objects and free all memory allocated in the zone. | 112 // Delete all objects and free all memory allocated in the zone. |
113 void DeleteAll(); | 113 void DeleteAll(); |
114 | 114 |
115 #if defined(DEBUG) | 115 #if defined(DEBUG) |
116 // Dump the current allocated sizes in the zone object. | 116 // Dump the current allocated sizes in the zone object. |
117 void DumpZoneSizes(); | 117 void DumpZoneSizes(); |
118 #endif | 118 #endif |
119 | 119 |
| 120 // Overflow check (FATAL) for array length. |
| 121 template <class ElementType> |
| 122 static inline void CheckLength(intptr_t len); |
| 123 |
120 // This buffer is used for allocation before any segments. | 124 // This buffer is used for allocation before any segments. |
121 // This would act as the initial stack allocated chunk so that we don't | 125 // This would act as the initial stack allocated chunk so that we don't |
122 // end up calling malloc/free on zone scopes that allocate less than | 126 // end up calling malloc/free on zone scopes that allocate less than |
123 // kChunkSize | 127 // kChunkSize |
124 uint8_t buffer_[kInitialChunkSize]; | 128 uint8_t buffer_[kInitialChunkSize]; |
125 MemoryRegion initial_buffer_; | 129 MemoryRegion initial_buffer_; |
126 | 130 |
127 // The free region in the current (head) segment or the initial buffer is | 131 // The free region in the current (head) segment or the initial buffer is |
128 // represented as the half-open interval [position, limit). The 'position' | 132 // represented as the half-open interval [position, limit). The 'position' |
129 // variable is guaranteed to be aligned as dictated by kAlignment. | 133 // variable is guaranteed to be aligned as dictated by kAlignment. |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 position_ += size; | 222 position_ += size; |
219 } else { | 223 } else { |
220 result = AllocateExpand(size); | 224 result = AllocateExpand(size); |
221 } | 225 } |
222 | 226 |
223 // Check that the result has the proper alignment and return it. | 227 // Check that the result has the proper alignment and return it. |
224 ASSERT(Utils::IsAligned(result, kAlignment)); | 228 ASSERT(Utils::IsAligned(result, kAlignment)); |
225 return result; | 229 return result; |
226 } | 230 } |
227 | 231 |
| 232 |
| 233 template <class ElementType> |
| 234 inline void Zone::CheckLength(intptr_t len) { |
| 235 const intptr_t kElementSize = sizeof(ElementType); |
| 236 if (len > (kIntptrMax / kElementSize)) { |
| 237 FATAL2("Zone::Alloc: 'len' is too large: len=%" Pd ", kElementSize=%" Pd, |
| 238 len, kElementSize); |
| 239 } |
| 240 } |
| 241 |
| 242 |
228 template <class ElementType> | 243 template <class ElementType> |
229 inline ElementType* Zone::Alloc(intptr_t len) { | 244 inline ElementType* Zone::Alloc(intptr_t len) { |
230 const intptr_t element_size = sizeof(ElementType); | 245 CheckLength<ElementType>(len); |
231 if (len > (kIntptrMax / element_size)) { | 246 return reinterpret_cast<ElementType*>(AllocUnsafe(len * sizeof(ElementType))); |
232 FATAL2("Zone::Alloc: 'len' is too large: len=%" Pd ", element_size=%" Pd, | |
233 len, element_size); | |
234 } | |
235 return reinterpret_cast<ElementType*>(AllocUnsafe(len * element_size)); | |
236 } | 247 } |
237 | 248 |
238 template <class ElementType> | 249 template <class ElementType> |
239 inline ElementType* Zone::Realloc(ElementType* old_data, | 250 inline ElementType* Zone::Realloc(ElementType* old_data, |
240 intptr_t old_len, | 251 intptr_t old_len, |
241 intptr_t new_len) { | 252 intptr_t new_len) { |
| 253 CheckLength<ElementType>(new_len); |
| 254 const intptr_t kElementSize = sizeof(ElementType); |
| 255 uword old_end = reinterpret_cast<uword>(old_data) + (old_len * kElementSize); |
| 256 // Resize existing allocation if nothing was allocated in between... |
| 257 if (Utils::RoundUp(old_end, kAlignment) == position_) { |
| 258 uword new_end = |
| 259 reinterpret_cast<uword>(old_data) + (new_len * kElementSize); |
| 260 // ...and there is sufficient space. |
| 261 if (new_end <= limit_) { |
| 262 position_ = Utils::RoundUp(new_end, kAlignment); |
| 263 return old_data; |
| 264 } |
| 265 } |
| 266 if (new_len <= old_len) { |
| 267 return old_data; |
| 268 } |
242 ElementType* new_data = Alloc<ElementType>(new_len); | 269 ElementType* new_data = Alloc<ElementType>(new_len); |
243 if (old_data != 0) { | 270 if (old_data != 0) { |
244 memmove(reinterpret_cast<void*>(new_data), | 271 memmove(reinterpret_cast<void*>(new_data), |
245 reinterpret_cast<void*>(old_data), | 272 reinterpret_cast<void*>(old_data), |
246 Utils::Minimum(old_len * sizeof(ElementType), | 273 old_len * kElementSize); |
247 new_len * sizeof(ElementType))); | |
248 } | 274 } |
249 return new_data; | 275 return new_data; |
250 } | 276 } |
251 | 277 |
252 } // namespace dart | 278 } // namespace dart |
253 | 279 |
254 #endif // VM_ZONE_H_ | 280 #endif // VM_ZONE_H_ |
OLD | NEW |