Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: runtime/vm/object.cc

Issue 2949803002: New growth strategy for growable arrays (Closed)
Patch Set: Branch-free grow size computation. Renamed function names to be clearer. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 3002 matching lines...) Expand 10 before | Expand all | Expand 10 after
3013 // Do not preserve the original implicit constructor, if any. 3013 // Do not preserve the original implicit constructor, if any.
3014 orig_implicit_ctor = Function::null(); 3014 orig_implicit_ctor = Function::null();
3015 } 3015 }
3016 func.set_owner(patch_class); 3016 func.set_owner(patch_class);
3017 new_functions.Add(func); 3017 new_functions.Add(func);
3018 } 3018 }
3019 if (!orig_implicit_ctor.IsNull()) { 3019 if (!orig_implicit_ctor.IsNull()) {
3020 // Preserve the original implicit constructor. 3020 // Preserve the original implicit constructor.
3021 new_functions.Add(orig_implicit_ctor); 3021 new_functions.Add(orig_implicit_ctor);
3022 } 3022 }
3023 Array& new_list = Array::Handle(Array::MakeArray(new_functions)); 3023 Array& new_list = Array::Handle(Array::MakeFixedLength(new_functions));
3024 SetFunctions(new_list); 3024 SetFunctions(new_list);
3025 3025
3026 // Merge the two list of fields. Raise an error when duplicates are found or 3026 // Merge the two list of fields. Raise an error when duplicates are found or
3027 // when a public field is being added. 3027 // when a public field is being added.
3028 orig_list = fields(); 3028 orig_list = fields();
3029 orig_len = orig_list.Length(); 3029 orig_len = orig_list.Length();
3030 patch_list = patch.fields(); 3030 patch_list = patch.fields();
3031 patch_len = patch_list.Length(); 3031 patch_len = patch_list.Length();
3032 3032
3033 Field& field = Field::Handle(); 3033 Field& field = Field::Handle();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3077 for (intptr_t i = 0; i < num_formals; i++) { 3077 for (intptr_t i = 0; i < num_formals; i++) {
3078 if (i > 0) { 3078 if (i > 0) {
3079 src_pieces.Add(Symbols::CommaSpace()); 3079 src_pieces.Add(Symbols::CommaSpace());
3080 } 3080 }
3081 piece ^= formal_params.At(i); 3081 piece ^= formal_params.At(i);
3082 src_pieces.Add(piece); 3082 src_pieces.Add(piece);
3083 } 3083 }
3084 src_pieces.Add(Symbols::RParenArrow()); 3084 src_pieces.Add(Symbols::RParenArrow());
3085 src_pieces.Add(expr); 3085 src_pieces.Add(expr);
3086 src_pieces.Add(Symbols::Semicolon()); 3086 src_pieces.Add(Symbols::Semicolon());
3087 return String::ConcatAll(Array::Handle(Array::MakeArray(src_pieces))); 3087 return String::ConcatAll(Array::Handle(Array::MakeFixedLength(src_pieces)));
3088 } 3088 }
3089 3089
3090 3090
3091 RawFunction* Function::EvaluateHelper(const Class& cls, 3091 RawFunction* Function::EvaluateHelper(const Class& cls,
3092 const String& expr, 3092 const String& expr,
3093 const Array& param_names, 3093 const Array& param_names,
3094 bool is_static) { 3094 bool is_static) {
3095 const String& func_src = 3095 const String& func_src =
3096 String::Handle(BuildClosureSource(param_names, expr)); 3096 String::Handle(BuildClosureSource(param_names, expr));
3097 Script& script = Script::Handle(); 3097 Script& script = Script::Handle();
(...skipping 5574 matching lines...) Expand 10 before | Expand all | Expand 10 after
8672 if (curr == Token::kNEWLINE) { 8672 if (curr == Token::kNEWLINE) {
8673 for (int i = 0; i < indent; i++) { 8673 for (int i = 0; i < indent; i++) {
8674 literals.Add(Symbols::TwoSpaces()); 8674 literals.Add(Symbols::TwoSpaces());
8675 } 8675 }
8676 } 8676 }
8677 8677
8678 // Setup for next iteration. 8678 // Setup for next iteration.
8679 prev = curr; 8679 prev = curr;
8680 curr = next; 8680 curr = next;
8681 } 8681 }
8682 const Array& source = Array::Handle(Array::MakeArray(literals)); 8682 const Array& source = Array::Handle(Array::MakeFixedLength(literals));
8683 return String::ConcatAll(source); 8683 return String::ConcatAll(source);
8684 } 8684 }
8685 8685
8686 8686
8687 intptr_t TokenStream::ComputeSourcePosition(TokenPosition tok_pos) const { 8687 intptr_t TokenStream::ComputeSourcePosition(TokenPosition tok_pos) const {
8688 Zone* zone = Thread::Current()->zone(); 8688 Zone* zone = Thread::Current()->zone();
8689 Iterator iterator(zone, *this, TokenPosition::kMinSource, 8689 Iterator iterator(zone, *this, TokenPosition::kMinSource,
8690 Iterator::kAllTokens); 8690 Iterator::kAllTokens);
8691 intptr_t src_pos = 0; 8691 intptr_t src_pos = 0;
8692 Token::Kind kind = iterator.CurrentTokenKind(); 8692 Token::Kind kind = iterator.CurrentTokenKind();
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
9393 token_pos = Smi::New(0); 9393 token_pos = Smi::New(0);
9394 line_starts_list.Add(token_pos); 9394 line_starts_list.Add(token_pos);
9395 while (tkit.CurrentTokenKind() != Token::kEOS) { 9395 while (tkit.CurrentTokenKind() != Token::kEOS) {
9396 if (tkit.CurrentTokenKind() == Token::kNEWLINE) { 9396 if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
9397 cur_line++; 9397 cur_line++;
9398 token_pos = Smi::New(tkit.CurrentPosition().value() + 1); 9398 token_pos = Smi::New(tkit.CurrentPosition().value() + 1);
9399 line_starts_list.Add(token_pos); 9399 line_starts_list.Add(token_pos);
9400 } 9400 }
9401 tkit.Advance(); 9401 tkit.Advance();
9402 } 9402 }
9403 line_starts_array = Array::MakeArray(line_starts_list); 9403 line_starts_array = Array::MakeFixedLength(line_starts_list);
9404 set_line_starts(line_starts_array); 9404 set_line_starts(line_starts_array);
9405 } 9405 }
9406 9406
9407 ASSERT(line_starts_array.Length() > 0); 9407 ASSERT(line_starts_array.Length() > 0);
9408 intptr_t offset = target_token_pos.Pos(); 9408 intptr_t offset = target_token_pos.Pos();
9409 intptr_t min = 0; 9409 intptr_t min = 0;
9410 intptr_t max = line_starts_array.Length() - 1; 9410 intptr_t max = line_starts_array.Length() - 1;
9411 9411
9412 // Binary search to find the line containing this offset. 9412 // Binary search to find the line containing this offset.
9413 while (min < max) { 9413 while (min < max) {
(...skipping 1227 matching lines...) Expand 10 before | Expand all | Expand 10 after
10641 for (intptr_t j = 0; j < functions.Length(); j++) { 10641 for (intptr_t j = 0; j < functions.Length(); j++) {
10642 func ^= functions.At(j); 10642 func ^= functions.At(j);
10643 if (func.is_external()) { 10643 if (func.is_external()) {
10644 owner_script = func.script(); 10644 owner_script = func.script();
10645 AddScriptIfUnique(scripts, owner_script); 10645 AddScriptIfUnique(scripts, owner_script);
10646 } 10646 }
10647 } 10647 }
10648 } 10648 }
10649 10649
10650 // Create the array of scripts and cache it in loaded_scripts_. 10650 // Create the array of scripts and cache it in loaded_scripts_.
10651 const Array& scripts_array = Array::Handle(Array::MakeArray(scripts)); 10651 const Array& scripts_array = Array::Handle(Array::MakeFixedLength(scripts));
10652 StorePointer(&raw_ptr()->loaded_scripts_, scripts_array.raw()); 10652 StorePointer(&raw_ptr()->loaded_scripts_, scripts_array.raw());
10653 } 10653 }
10654 return loaded_scripts(); 10654 return loaded_scripts();
10655 } 10655 }
10656 10656
10657 10657
10658 // TODO(hausner): we might want to add a script dictionary to the 10658 // TODO(hausner): we might want to add a script dictionary to the
10659 // library class to make this lookup faster. 10659 // library class to make this lookup faster.
10660 RawScript* Library::LookupScript(const String& url) const { 10660 RawScript* Library::LookupScript(const String& url) const {
10661 const intptr_t url_length = url.Length(); 10661 const intptr_t url_length = url.Length();
(...skipping 11397 matching lines...) Expand 10 before | Expand all | Expand 10 after
22059 ASSERT(new_length != len); // Unnecessary copying of array. 22059 ASSERT(new_length != len); // Unnecessary copying of array.
22060 PassiveObject& obj = PassiveObject::Handle(zone); 22060 PassiveObject& obj = PassiveObject::Handle(zone);
22061 for (int i = 0; i < len; i++) { 22061 for (int i = 0; i < len; i++) {
22062 obj = source.At(i); 22062 obj = source.At(i);
22063 result.SetAt(i, obj); 22063 result.SetAt(i, obj);
22064 } 22064 }
22065 return result.raw(); 22065 return result.raw();
22066 } 22066 }
22067 22067
22068 22068
22069 RawArray* Array::MakeArray(const GrowableObjectArray& growable_array) { 22069 RawArray* Array::MakeFixedLength(const GrowableObjectArray& growable_array,
22070 bool unique) {
22070 ASSERT(!growable_array.IsNull()); 22071 ASSERT(!growable_array.IsNull());
22072 Thread* thread = Thread::Current();
22073 Zone* zone = thread->zone();
22071 intptr_t used_len = growable_array.Length(); 22074 intptr_t used_len = growable_array.Length();
22072 // Get the type arguments and prepare to copy them. 22075 // Get the type arguments and prepare to copy them.
22073 const TypeArguments& type_arguments = 22076 const TypeArguments& type_arguments =
22074 TypeArguments::Handle(growable_array.GetTypeArguments()); 22077 TypeArguments::Handle(growable_array.GetTypeArguments());
22075 if ((used_len == 0) && (type_arguments.IsNull())) { 22078 if (used_len == 0) {
22076 // This is a raw List (as in no type arguments), so we can return the 22079 if (type_arguments.IsNull() && !unique) {
22077 // simple empty array. 22080 // This is a raw List (as in no type arguments), so we can return the
22078 return Object::empty_array().raw(); 22081 // simple empty array.
22082 return Object::empty_array().raw();
22083 }
22084
22085 // The backing array may be a shared instance, or may not have correct
22086 // type parameters. Create a new empty array.
22087 Heap::Space space = thread->IsMutatorThread() ? Heap::kNew : Heap::kOld;
22088 Array& array = Array::Handle(zone, Array::New(0, space));
22089 array.SetTypeArguments(type_arguments);
22090 return array.raw();
22079 } 22091 }
22080 intptr_t capacity_len = growable_array.Capacity(); 22092 intptr_t capacity_len = growable_array.Capacity();
22081 Zone* zone = Thread::Current()->zone();
22082 const Array& array = Array::Handle(zone, growable_array.data()); 22093 const Array& array = Array::Handle(zone, growable_array.data());
22083 array.SetTypeArguments(type_arguments); 22094 array.SetTypeArguments(type_arguments);
22084 intptr_t capacity_size = Array::InstanceSize(capacity_len); 22095 intptr_t capacity_size = Array::InstanceSize(capacity_len);
22085 intptr_t used_size = Array::InstanceSize(used_len); 22096 intptr_t used_size = Array::InstanceSize(used_len);
22086 NoSafepointScope no_safepoint; 22097 NoSafepointScope no_safepoint;
22087 22098
22088 // If there is any left over space fill it with either an Array object or 22099 // If there is any left over space fill it with either an Array object or
22089 // just a plain object (depending on the amount of left over space) so 22100 // just a plain object (depending on the amount of left over space) so
22090 // that it can be traversed over successfully during garbage collection. 22101 // that it can be traversed over successfully during garbage collection.
22091 Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size); 22102 Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
22150 RawImmutableArray* ImmutableArray::New(intptr_t len, Heap::Space space) { 22161 RawImmutableArray* ImmutableArray::New(intptr_t len, Heap::Space space) {
22151 ASSERT(Isolate::Current()->object_store()->immutable_array_class() != 22162 ASSERT(Isolate::Current()->object_store()->immutable_array_class() !=
22152 Class::null()); 22163 Class::null());
22153 return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space)); 22164 return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space));
22154 } 22165 }
22155 22166
22156 22167
22157 void GrowableObjectArray::Add(const Object& value, Heap::Space space) const { 22168 void GrowableObjectArray::Add(const Object& value, Heap::Space space) const {
22158 ASSERT(!IsNull()); 22169 ASSERT(!IsNull());
22159 if (Length() == Capacity()) { 22170 if (Length() == Capacity()) {
22160 // TODO(Issue 2500): Need a better growth strategy. 22171 // Grow from 0 to 3, and then double + 1.
22161 intptr_t new_capacity = (Capacity() == 0) ? 4 : Capacity() * 2; 22172 intptr_t new_capacity = (Capacity() * 2) | 3;
22162 if (new_capacity <= Capacity()) { 22173 if (new_capacity <= Capacity()) {
22163 Exceptions::ThrowOOM(); 22174 Exceptions::ThrowOOM();
22164 UNREACHABLE(); 22175 UNREACHABLE();
22165 } 22176 }
22166 Grow(new_capacity, space); 22177 Grow(new_capacity, space);
22167 } 22178 }
22168 ASSERT(Length() < Capacity()); 22179 ASSERT(Length() < Capacity());
22169 intptr_t index = Length(); 22180 intptr_t index = Length();
22170 SetLength(index + 1); 22181 SetLength(index + 1);
22171 SetAt(index, value); 22182 SetAt(index, value);
(...skipping 16 matching lines...) Expand all
22188 const Array& contents = Array::Handle(data()); 22199 const Array& contents = Array::Handle(data());
22189 const PassiveObject& obj = PassiveObject::Handle(contents.At(index)); 22200 const PassiveObject& obj = PassiveObject::Handle(contents.At(index));
22190 contents.SetAt(index, Object::null_object()); 22201 contents.SetAt(index, Object::null_object());
22191 SetLength(index); 22202 SetLength(index);
22192 return obj.raw(); 22203 return obj.raw();
22193 } 22204 }
22194 22205
22195 22206
22196 RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity, 22207 RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity,
22197 Heap::Space space) { 22208 Heap::Space space) {
22198 const Array& data = Array::Handle(Array::New(capacity, space)); 22209 RawArray* raw_data = (capacity == 0) ? Object::empty_array().raw()
22210 : Array::New(capacity, space);
22211 const Array& data = Array::Handle(raw_data);
22199 return New(data, space); 22212 return New(data, space);
22200 } 22213 }
22201 22214
22202 22215
22203 RawGrowableObjectArray* GrowableObjectArray::New(const Array& array, 22216 RawGrowableObjectArray* GrowableObjectArray::New(const Array& array,
22204 Heap::Space space) { 22217 Heap::Space space) {
22205 ASSERT(Isolate::Current()->object_store()->growable_object_array_class() != 22218 ASSERT(Isolate::Current()->object_store()->growable_object_array_class() !=
22206 Class::null()); 22219 Class::null());
22207 GrowableObjectArray& result = GrowableObjectArray::Handle(); 22220 GrowableObjectArray& result = GrowableObjectArray::Handle();
22208 { 22221 {
(...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after
23419 return UserTag::null(); 23432 return UserTag::null();
23420 } 23433 }
23421 23434
23422 23435
23423 const char* UserTag::ToCString() const { 23436 const char* UserTag::ToCString() const {
23424 const String& tag_label = String::Handle(label()); 23437 const String& tag_label = String::Handle(label());
23425 return tag_label.ToCString(); 23438 return tag_label.ToCString();
23426 } 23439 }
23427 23440
23428 } // namespace dart 23441 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698