| 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;
|
| }
|
|
|