| Index: runtime/vm/object.cc
|
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
|
| index 728e2ffe6446a8833d056194b9aef8d727408440..bedc689da0dde1520f266bd088eacebad189f803 100644
|
| --- a/runtime/vm/object.cc
|
| +++ b/runtime/vm/object.cc
|
| @@ -3020,7 +3020,7 @@ bool Class::ApplyPatch(const Class& patch, Error* error) const {
|
| // Preserve the original implicit constructor.
|
| new_functions.Add(orig_implicit_ctor);
|
| }
|
| - Array& new_list = Array::Handle(Array::MakeArray(new_functions));
|
| + Array& new_list = Array::Handle(Array::MakeFixedLength(new_functions));
|
| SetFunctions(new_list);
|
|
|
| // Merge the two list of fields. Raise an error when duplicates are found or
|
| @@ -3084,7 +3084,7 @@ static RawString* BuildClosureSource(const Array& formal_params,
|
| src_pieces.Add(Symbols::RParenArrow());
|
| src_pieces.Add(expr);
|
| src_pieces.Add(Symbols::Semicolon());
|
| - return String::ConcatAll(Array::Handle(Array::MakeArray(src_pieces)));
|
| + return String::ConcatAll(Array::Handle(Array::MakeFixedLength(src_pieces)));
|
| }
|
|
|
|
|
| @@ -8679,7 +8679,7 @@ RawString* TokenStream::GenerateSource(TokenPosition start_pos,
|
| prev = curr;
|
| curr = next;
|
| }
|
| - const Array& source = Array::Handle(Array::MakeArray(literals));
|
| + const Array& source = Array::Handle(Array::MakeFixedLength(literals));
|
| return String::ConcatAll(source);
|
| }
|
|
|
| @@ -9400,7 +9400,7 @@ intptr_t Script::GetTokenLineUsingLineStarts(
|
| }
|
| tkit.Advance();
|
| }
|
| - line_starts_array = Array::MakeArray(line_starts_list);
|
| + line_starts_array = Array::MakeFixedLength(line_starts_list);
|
| set_line_starts(line_starts_array);
|
| }
|
|
|
| @@ -10648,7 +10648,7 @@ RawArray* Library::LoadedScripts() const {
|
| }
|
|
|
| // Create the array of scripts and cache it in loaded_scripts_.
|
| - const Array& scripts_array = Array::Handle(Array::MakeArray(scripts));
|
| + const Array& scripts_array = Array::Handle(Array::MakeFixedLength(scripts));
|
| StorePointer(&raw_ptr()->loaded_scripts_, scripts_array.raw());
|
| }
|
| return loaded_scripts();
|
| @@ -22066,19 +22066,30 @@ RawArray* Array::Grow(const Array& source,
|
| }
|
|
|
|
|
| -RawArray* Array::MakeArray(const GrowableObjectArray& growable_array) {
|
| +RawArray* Array::MakeFixedLength(const GrowableObjectArray& growable_array,
|
| + bool unique) {
|
| ASSERT(!growable_array.IsNull());
|
| + Thread* thread = Thread::Current();
|
| + Zone* zone = thread->zone();
|
| intptr_t used_len = growable_array.Length();
|
| // Get the type arguments and prepare to copy them.
|
| const TypeArguments& type_arguments =
|
| TypeArguments::Handle(growable_array.GetTypeArguments());
|
| - if ((used_len == 0) && (type_arguments.IsNull())) {
|
| - // This is a raw List (as in no type arguments), so we can return the
|
| - // simple empty array.
|
| - return Object::empty_array().raw();
|
| + if (used_len == 0) {
|
| + if (type_arguments.IsNull() && !unique) {
|
| + // This is a raw List (as in no type arguments), so we can return the
|
| + // simple empty array.
|
| + return Object::empty_array().raw();
|
| + }
|
| +
|
| + // The backing array may be a shared instance, or may not have correct
|
| + // type parameters. Create a new empty array.
|
| + Heap::Space space = thread->IsMutatorThread() ? Heap::kNew : Heap::kOld;
|
| + Array& array = Array::Handle(zone, Array::New(0, space));
|
| + array.SetTypeArguments(type_arguments);
|
| + return array.raw();
|
| }
|
| intptr_t capacity_len = growable_array.Capacity();
|
| - Zone* zone = Thread::Current()->zone();
|
| const Array& array = Array::Handle(zone, growable_array.data());
|
| array.SetTypeArguments(type_arguments);
|
| intptr_t capacity_size = Array::InstanceSize(capacity_len);
|
| @@ -22157,8 +22168,8 @@ RawImmutableArray* ImmutableArray::New(intptr_t len, Heap::Space space) {
|
| void GrowableObjectArray::Add(const Object& value, Heap::Space space) const {
|
| ASSERT(!IsNull());
|
| if (Length() == Capacity()) {
|
| - // TODO(Issue 2500): Need a better growth strategy.
|
| - intptr_t new_capacity = (Capacity() == 0) ? 4 : Capacity() * 2;
|
| + // Grow from 0 to 3, and then double + 1.
|
| + intptr_t new_capacity = (Capacity() * 2) | 3;
|
| if (new_capacity <= Capacity()) {
|
| Exceptions::ThrowOOM();
|
| UNREACHABLE();
|
| @@ -22195,7 +22206,9 @@ RawObject* GrowableObjectArray::RemoveLast() const {
|
|
|
| RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity,
|
| Heap::Space space) {
|
| - const Array& data = Array::Handle(Array::New(capacity, space));
|
| + RawArray* raw_data = (capacity == 0) ? Object::empty_array().raw()
|
| + : Array::New(capacity, space);
|
| + const Array& data = Array::Handle(raw_data);
|
| return New(data, space);
|
| }
|
|
|
|
|