| Index: runtime/vm/growable_array.h
|
| ===================================================================
|
| --- runtime/vm/growable_array.h (revision 42760)
|
| +++ runtime/vm/growable_array.h (working copy)
|
| @@ -4,6 +4,8 @@
|
| // Defines growable array classes, that differ where they are allocated:
|
| // - GrowableArray: allocated on stack.
|
| // - ZoneGrowableArray: allocated in the zone.
|
| +// - MallocGrowableArray: allocates using malloc/realloc; free is only called
|
| +// at destruction.
|
|
|
| #ifndef VM_GROWABLE_ARRAY_H_
|
| #define VM_GROWABLE_ARRAY_H_
|
| @@ -15,23 +17,24 @@
|
|
|
| namespace dart {
|
|
|
| -template<typename T, typename B>
|
| +template<typename T, typename B, typename Allocator = Zone>
|
| class BaseGrowableArray : public B {
|
| public:
|
| - explicit BaseGrowableArray(Zone* zone)
|
| - : length_(0), capacity_(0), data_(NULL), zone_(zone) {
|
| - ASSERT(zone_ != NULL);
|
| - }
|
| + explicit BaseGrowableArray(Allocator* allocator)
|
| + : length_(0), capacity_(0), data_(NULL), allocator_(allocator) {}
|
|
|
| - BaseGrowableArray(intptr_t initial_capacity, Zone* zone)
|
| - : length_(0), capacity_(0), data_(NULL), zone_(zone) {
|
| - ASSERT(zone_ != NULL);
|
| + BaseGrowableArray(intptr_t initial_capacity, Allocator* allocator)
|
| + : length_(0), capacity_(0), data_(NULL), allocator_(allocator) {
|
| if (initial_capacity > 0) {
|
| capacity_ = Utils::RoundUpToPowerOfTwo(initial_capacity);
|
| - data_ = zone_->Alloc<T>(capacity_);
|
| + data_ = allocator_->template Alloc<T>(capacity_);
|
| }
|
| }
|
|
|
| + ~BaseGrowableArray() {
|
| + allocator_->template Free<T>(data_, capacity_);
|
| + }
|
| +
|
| intptr_t length() const { return length_; }
|
| T* data() const { return data_; }
|
| bool is_empty() const { return length_ == 0; }
|
| @@ -97,7 +100,7 @@
|
| intptr_t length_;
|
| intptr_t capacity_;
|
| T* data_;
|
| - Zone* zone_; // Zone in which we are allocating the array.
|
| + Allocator* allocator_; // Used to (re)allocate the array.
|
|
|
| // Used for growing the array.
|
| void Resize(intptr_t new_length);
|
| @@ -106,8 +109,8 @@
|
| };
|
|
|
|
|
| -template<typename T, typename B>
|
| -inline void BaseGrowableArray<T, B>::Sort(
|
| +template<typename T, typename B, typename Allocator>
|
| +inline void BaseGrowableArray<T, B, Allocator>::Sort(
|
| int compare(const T*, const T*)) {
|
| typedef int (*CompareFunction)(const void*, const void*);
|
| qsort(data_, length_, sizeof(T), reinterpret_cast<CompareFunction>(compare));
|
| @@ -114,11 +117,12 @@
|
| }
|
|
|
|
|
| -template<typename T, typename B>
|
| -void BaseGrowableArray<T, B>::Resize(intptr_t new_length) {
|
| +template<typename T, typename B, typename Allocator>
|
| +void BaseGrowableArray<T, B, Allocator>::Resize(intptr_t new_length) {
|
| if (new_length > capacity_) {
|
| intptr_t new_capacity = Utils::RoundUpToPowerOfTwo(new_length);
|
| - T* new_data = zone_->Realloc<T>(data_, capacity_, new_capacity);
|
| + T* new_data =
|
| + allocator_->template Realloc<T>(data_, capacity_, new_capacity);
|
| ASSERT(new_data != NULL);
|
| data_ = new_data;
|
| capacity_ = new_capacity;
|
| @@ -127,10 +131,10 @@
|
| }
|
|
|
|
|
| -template<typename T, typename B>
|
| -void BaseGrowableArray<T, B>::SetLength(intptr_t new_length) {
|
| +template<typename T, typename B, typename Allocator>
|
| +void BaseGrowableArray<T, B, Allocator>::SetLength(intptr_t new_length) {
|
| if (new_length > capacity_) {
|
| - T* new_data = zone_->Alloc<T>(new_length);
|
| + T* new_data = allocator_->template Alloc<T>(new_length);
|
| ASSERT(new_data != NULL);
|
| data_ = new_data;
|
| capacity_ = new_length;
|
| @@ -144,13 +148,14 @@
|
| public:
|
| GrowableArray(Isolate* isolate, intptr_t initial_capacity)
|
| : BaseGrowableArray<T, ValueObject>(
|
| - initial_capacity, isolate->current_zone()) {}
|
| + initial_capacity, ASSERT_NOTNULL(isolate->current_zone())) {}
|
| explicit GrowableArray(intptr_t initial_capacity)
|
| : BaseGrowableArray<T, ValueObject>(
|
| - initial_capacity, Isolate::Current()->current_zone()) {}
|
| + initial_capacity,
|
| + ASSERT_NOTNULL(Isolate::Current()->current_zone())) {}
|
| GrowableArray()
|
| : BaseGrowableArray<T, ValueObject>(
|
| - Isolate::Current()->current_zone()) {}
|
| + ASSERT_NOTNULL(Isolate::Current()->current_zone())) {}
|
| };
|
|
|
|
|
| @@ -159,16 +164,48 @@
|
| public:
|
| ZoneGrowableArray(Isolate* isolate, intptr_t initial_capacity)
|
| : BaseGrowableArray<T, ZoneAllocated>(
|
| - initial_capacity, isolate->current_zone()) {}
|
| + initial_capacity, ASSERT_NOTNULL(isolate->current_zone())) {}
|
| explicit ZoneGrowableArray(intptr_t initial_capacity)
|
| : BaseGrowableArray<T, ZoneAllocated>(
|
| initial_capacity,
|
| - Isolate::Current()->current_zone()) {}
|
| - ZoneGrowableArray() :
|
| - BaseGrowableArray<T, ZoneAllocated>(
|
| - Isolate::Current()->current_zone()) {}
|
| + ASSERT_NOTNULL(Isolate::Current()->current_zone())) {}
|
| + ZoneGrowableArray()
|
| + : BaseGrowableArray<T, ZoneAllocated>(
|
| + ASSERT_NOTNULL(Isolate::Current()->current_zone())) {}
|
| };
|
|
|
| +
|
| +class Malloc : public AllStatic {
|
| + public:
|
| + template <class T>
|
| + static inline T* Alloc(intptr_t len) {
|
| + return reinterpret_cast<T*>(malloc(len * sizeof(T)));
|
| + }
|
| +
|
| + template <class T>
|
| + static inline T* Realloc(T* old_array, intptr_t old_len, intptr_t new_len) {
|
| + return reinterpret_cast<T*>(realloc(old_array, new_len * sizeof(T)));
|
| + }
|
| +
|
| + template <class T>
|
| + static inline void Free(T* old_array, intptr_t old_len) {
|
| + free(old_array);
|
| + }
|
| +};
|
| +
|
| +
|
| +class EmptyBase {};
|
| +
|
| +
|
| +template<typename T>
|
| +class MallocGrowableArray : public BaseGrowableArray<T, EmptyBase, Malloc> {
|
| + public:
|
| + explicit MallocGrowableArray(intptr_t initial_capacity)
|
| + : BaseGrowableArray<T, EmptyBase, Malloc>(initial_capacity, NULL) {}
|
| + MallocGrowableArray()
|
| + : BaseGrowableArray<T, EmptyBase, Malloc>(NULL) {}
|
| +};
|
| +
|
| } // namespace dart
|
|
|
| #endif // VM_GROWABLE_ARRAY_H_
|
|
|