Index: runtime/vm/zone.h |
=================================================================== |
--- runtime/vm/zone.h (revision 42781) |
+++ runtime/vm/zone.h (working copy) |
@@ -117,6 +117,10 @@ |
void DumpZoneSizes(); |
#endif |
+ // Overflow check (FATAL) for array length. |
+ template <class ElementType> |
+ static inline void CheckLength(intptr_t len); |
+ |
// This buffer is used for allocation before any segments. |
// This would act as the initial stack allocated chunk so that we don't |
// end up calling malloc/free on zone scopes that allocate less than |
@@ -225,26 +229,48 @@ |
return result; |
} |
+ |
template <class ElementType> |
-inline ElementType* Zone::Alloc(intptr_t len) { |
- const intptr_t element_size = sizeof(ElementType); |
- if (len > (kIntptrMax / element_size)) { |
- FATAL2("Zone::Alloc: 'len' is too large: len=%" Pd ", element_size=%" Pd, |
- len, element_size); |
+inline void Zone::CheckLength(intptr_t len) { |
+ const intptr_t kElementSize = sizeof(ElementType); |
+ if (len > (kIntptrMax / kElementSize)) { |
+ FATAL2("Zone::Alloc: 'len' is too large: len=%" Pd ", kElementSize=%" Pd, |
+ len, kElementSize); |
} |
- return reinterpret_cast<ElementType*>(AllocUnsafe(len * element_size)); |
} |
+ |
template <class ElementType> |
+inline ElementType* Zone::Alloc(intptr_t len) { |
+ CheckLength<ElementType>(len); |
+ return reinterpret_cast<ElementType*>(AllocUnsafe(len * sizeof(ElementType))); |
+} |
+ |
+template <class ElementType> |
inline ElementType* Zone::Realloc(ElementType* old_data, |
- intptr_t old_len, |
- intptr_t new_len) { |
+ intptr_t old_len, |
+ intptr_t new_len) { |
+ CheckLength<ElementType>(new_len); |
+ const intptr_t kElementSize = sizeof(ElementType); |
+ uword old_end = reinterpret_cast<uword>(old_data) + (old_len * kElementSize); |
+ // Resize existing allocation if nothing was allocated in between... |
+ if (Utils::RoundUp(old_end, kAlignment) == position_) { |
+ uword new_end = |
+ reinterpret_cast<uword>(old_data) + (new_len * kElementSize); |
+ // ...and there is sufficient space. |
+ if (new_end <= limit_) { |
+ position_ = Utils::RoundUp(new_end, kAlignment); |
+ return old_data; |
+ } |
+ } |
+ if (new_len <= old_len) { |
+ return old_data; |
+ } |
ElementType* new_data = Alloc<ElementType>(new_len); |
if (old_data != 0) { |
memmove(reinterpret_cast<void*>(new_data), |
reinterpret_cast<void*>(old_data), |
- Utils::Minimum(old_len * sizeof(ElementType), |
- new_len * sizeof(ElementType))); |
+ old_len * kElementSize); |
} |
return new_data; |
} |