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

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

Issue 167683002: Simplify type argument instantiation cache lookup by introducing an array (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 #if defined(RAW_NULL) 86 #if defined(RAW_NULL)
87 #error RAW_NULL should not be defined. 87 #error RAW_NULL should not be defined.
88 #endif 88 #endif
89 #define RAW_NULL kHeapObjectTag 89 #define RAW_NULL kHeapObjectTag
90 Object* Object::null_object_ = NULL; 90 Object* Object::null_object_ = NULL;
91 Array* Object::null_array_ = NULL; 91 Array* Object::null_array_ = NULL;
92 String* Object::null_string_ = NULL; 92 String* Object::null_string_ = NULL;
93 Instance* Object::null_instance_ = NULL; 93 Instance* Object::null_instance_ = NULL;
94 TypeArguments* Object::null_type_arguments_ = NULL; 94 TypeArguments* Object::null_type_arguments_ = NULL;
95 Array* Object::empty_array_ = NULL; 95 Array* Object::empty_array_ = NULL;
96 Array* Object::zero_array_ = NULL;
96 PcDescriptors* Object::empty_descriptors_ = NULL; 97 PcDescriptors* Object::empty_descriptors_ = NULL;
97 Instance* Object::sentinel_ = NULL; 98 Instance* Object::sentinel_ = NULL;
98 Instance* Object::transition_sentinel_ = NULL; 99 Instance* Object::transition_sentinel_ = NULL;
99 Instance* Object::unknown_constant_ = NULL; 100 Instance* Object::unknown_constant_ = NULL;
100 Instance* Object::non_constant_ = NULL; 101 Instance* Object::non_constant_ = NULL;
101 Bool* Object::bool_true_ = NULL; 102 Bool* Object::bool_true_ = NULL;
102 Bool* Object::bool_false_ = NULL; 103 Bool* Object::bool_false_ = NULL;
103 Smi* Object::smi_illegal_cid_ = NULL; 104 Smi* Object::smi_illegal_cid_ = NULL;
104 LanguageError* Object::snapshot_writer_error_ = NULL; 105 LanguageError* Object::snapshot_writer_error_ = NULL;
105 LanguageError* Object::branch_offset_error_ = NULL; 106 LanguageError* Object::branch_offset_error_ = NULL;
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 Isolate* isolate = Isolate::Current(); 443 Isolate* isolate = Isolate::Current();
443 Heap* heap = isolate->heap(); 444 Heap* heap = isolate->heap();
444 445
445 // Allocate the read only object handles here. 446 // Allocate the read only object handles here.
446 null_object_ = Object::ReadOnlyHandle(); 447 null_object_ = Object::ReadOnlyHandle();
447 null_array_ = Array::ReadOnlyHandle(); 448 null_array_ = Array::ReadOnlyHandle();
448 null_string_ = String::ReadOnlyHandle(); 449 null_string_ = String::ReadOnlyHandle();
449 null_instance_ = Instance::ReadOnlyHandle(); 450 null_instance_ = Instance::ReadOnlyHandle();
450 null_type_arguments_ = TypeArguments::ReadOnlyHandle(); 451 null_type_arguments_ = TypeArguments::ReadOnlyHandle();
451 empty_array_ = Array::ReadOnlyHandle(); 452 empty_array_ = Array::ReadOnlyHandle();
453 zero_array_ = Array::ReadOnlyHandle();
452 empty_descriptors_ = PcDescriptors::ReadOnlyHandle(); 454 empty_descriptors_ = PcDescriptors::ReadOnlyHandle();
453 sentinel_ = Instance::ReadOnlyHandle(); 455 sentinel_ = Instance::ReadOnlyHandle();
454 transition_sentinel_ = Instance::ReadOnlyHandle(); 456 transition_sentinel_ = Instance::ReadOnlyHandle();
455 unknown_constant_ = Instance::ReadOnlyHandle(); 457 unknown_constant_ = Instance::ReadOnlyHandle();
456 non_constant_ = Instance::ReadOnlyHandle(); 458 non_constant_ = Instance::ReadOnlyHandle();
457 bool_true_ = Bool::ReadOnlyHandle(); 459 bool_true_ = Bool::ReadOnlyHandle();
458 bool_false_ = Bool::ReadOnlyHandle(); 460 bool_false_ = Bool::ReadOnlyHandle();
459 smi_illegal_cid_ = Smi::ReadOnlyHandle(); 461 smi_illegal_cid_ = Smi::ReadOnlyHandle();
460 snapshot_writer_error_ = LanguageError::ReadOnlyHandle(); 462 snapshot_writer_error_ = LanguageError::ReadOnlyHandle();
461 branch_offset_error_ = LanguageError::ReadOnlyHandle(); 463 branch_offset_error_ = LanguageError::ReadOnlyHandle();
462 464
463 465
464 // Allocate and initialize the null instance. 466 // Allocate and initialize the null instance.
465 // 'null_' must be the first object allocated as it is used in allocation to 467 // 'null_' must be the first object allocated as it is used in allocation to
466 // clear the object. 468 // clear the object.
467 { 469 {
468 uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld); 470 uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld);
469 null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag); 471 null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag);
470 // The call below is using 'null_' to initialize itself. 472 // The call below is using 'null_' to initialize itself.
471 InitializeObject(address, kNullCid, Instance::InstanceSize()); 473 InitializeObject(address, kNullCid, Instance::InstanceSize());
472 } 474 }
473 475
474 *null_object_ = Object::null(); 476 *null_object_ = Object::null();
475 *null_array_ = Array::null(); 477 *null_array_ = Array::null();
476 *null_string_ = String::null(); 478 *null_string_ = String::null();
477 *null_instance_ = Instance::null(); 479 *null_instance_ = Instance::null();
478 *null_type_arguments_ = TypeArguments::null(); 480 *null_type_arguments_ = TypeArguments::null();
479 481
480 // Initialize the empty array handle to null_ in order to be able to check 482 // Initialize the empty and zero array handles to null_ in order to be able to
481 // if the empty array was allocated (RAW_NULL is not available). 483 // check if the empty and zero arrays were allocated (RAW_NULL is not
484 // available).
482 *empty_array_ = Array::null(); 485 *empty_array_ = Array::null();
486 *zero_array_ = Array::null();
483 487
484 Class& cls = Class::Handle(); 488 Class& cls = Class::Handle();
485 489
486 // Allocate and initialize the class class. 490 // Allocate and initialize the class class.
487 { 491 {
488 intptr_t size = Class::InstanceSize(); 492 intptr_t size = Class::InstanceSize();
489 uword address = heap->Allocate(size, Heap::kOld); 493 uword address = heap->Allocate(size, Heap::kOld);
490 class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag); 494 class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag);
491 InitializeObject(address, Class::kClassId, size); 495 InitializeObject(address, Class::kClassId, size);
492 496
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 // Allocate and initialize the empty_array instance. 654 // Allocate and initialize the empty_array instance.
651 { 655 {
652 uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld); 656 uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld);
653 InitializeObject(address, kArrayCid, Array::InstanceSize(0)); 657 InitializeObject(address, kArrayCid, Array::InstanceSize(0));
654 Array::initializeHandle( 658 Array::initializeHandle(
655 empty_array_, 659 empty_array_,
656 reinterpret_cast<RawArray*>(address + kHeapObjectTag)); 660 reinterpret_cast<RawArray*>(address + kHeapObjectTag));
657 empty_array_->raw_ptr()->length_ = Smi::New(0); 661 empty_array_->raw_ptr()->length_ = Smi::New(0);
658 } 662 }
659 663
664 // Allocate and initialize the zero_array instance.
665 {
666 uword address = heap->Allocate(Array::InstanceSize(1), Heap::kOld);
667 InitializeObject(address, kArrayCid, Array::InstanceSize(1));
668 Array::initializeHandle(
669 zero_array_,
670 reinterpret_cast<RawArray*>(address + kHeapObjectTag));
671 zero_array_->raw_ptr()->length_ = Smi::New(1);
672 zero_array_->raw_ptr()->data()[0] = Smi::New(0);
673 }
674
660 // Allocate and initialize the empty_descriptors instance. 675 // Allocate and initialize the empty_descriptors instance.
661 { 676 {
662 uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld); 677 uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld);
663 InitializeObject(address, kPcDescriptorsCid, 678 InitializeObject(address, kPcDescriptorsCid,
664 PcDescriptors::InstanceSize(0)); 679 PcDescriptors::InstanceSize(0));
665 PcDescriptors::initializeHandle( 680 PcDescriptors::initializeHandle(
666 empty_descriptors_, 681 empty_descriptors_,
667 reinterpret_cast<RawPcDescriptors*>(address + kHeapObjectTag)); 682 reinterpret_cast<RawPcDescriptors*>(address + kHeapObjectTag));
668 empty_descriptors_->raw_ptr()->length_ = Smi::New(0); 683 empty_descriptors_->raw_ptr()->length_ = Smi::New(0);
669 } 684 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 ASSERT(!null_array_->IsSmi()); 728 ASSERT(!null_array_->IsSmi());
714 ASSERT(null_array_->IsArray()); 729 ASSERT(null_array_->IsArray());
715 ASSERT(!null_string_->IsSmi()); 730 ASSERT(!null_string_->IsSmi());
716 ASSERT(null_string_->IsString()); 731 ASSERT(null_string_->IsString());
717 ASSERT(!null_instance_->IsSmi()); 732 ASSERT(!null_instance_->IsSmi());
718 ASSERT(null_instance_->IsInstance()); 733 ASSERT(null_instance_->IsInstance());
719 ASSERT(!null_type_arguments_->IsSmi()); 734 ASSERT(!null_type_arguments_->IsSmi());
720 ASSERT(null_type_arguments_->IsTypeArguments()); 735 ASSERT(null_type_arguments_->IsTypeArguments());
721 ASSERT(!empty_array_->IsSmi()); 736 ASSERT(!empty_array_->IsSmi());
722 ASSERT(empty_array_->IsArray()); 737 ASSERT(empty_array_->IsArray());
738 ASSERT(!zero_array_->IsSmi());
739 ASSERT(zero_array_->IsArray());
723 ASSERT(!sentinel_->IsSmi()); 740 ASSERT(!sentinel_->IsSmi());
724 ASSERT(sentinel_->IsInstance()); 741 ASSERT(sentinel_->IsInstance());
725 ASSERT(!transition_sentinel_->IsSmi()); 742 ASSERT(!transition_sentinel_->IsSmi());
726 ASSERT(transition_sentinel_->IsInstance()); 743 ASSERT(transition_sentinel_->IsInstance());
727 ASSERT(!unknown_constant_->IsSmi()); 744 ASSERT(!unknown_constant_->IsSmi());
728 ASSERT(unknown_constant_->IsInstance()); 745 ASSERT(unknown_constant_->IsInstance());
729 ASSERT(!non_constant_->IsSmi()); 746 ASSERT(!non_constant_->IsSmi());
730 ASSERT(non_constant_->IsInstance()); 747 ASSERT(non_constant_->IsInstance());
731 ASSERT(!bool_true_->IsSmi()); 748 ASSERT(!bool_true_->IsSmi());
732 ASSERT(bool_true_->IsBool()); 749 ASSERT(bool_true_->IsBool());
(...skipping 3480 matching lines...) Expand 10 before | Expand all | Expand 10 after
4213 4230
4214 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom( 4231 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom(
4215 const TypeArguments& instantiator_type_arguments, 4232 const TypeArguments& instantiator_type_arguments,
4216 Error* bound_error) const { 4233 Error* bound_error) const {
4217 ASSERT(!IsInstantiated()); 4234 ASSERT(!IsInstantiated());
4218 ASSERT(instantiator_type_arguments.IsNull() || 4235 ASSERT(instantiator_type_arguments.IsNull() ||
4219 instantiator_type_arguments.IsCanonical()); 4236 instantiator_type_arguments.IsCanonical());
4220 // Lookup instantiator and, if found, return paired instantiated result. 4237 // Lookup instantiator and, if found, return paired instantiated result.
4221 Array& prior_instantiations = Array::Handle(instantiations()); 4238 Array& prior_instantiations = Array::Handle(instantiations());
4222 ASSERT(!prior_instantiations.IsNull() && prior_instantiations.IsArray()); 4239 ASSERT(!prior_instantiations.IsNull() && prior_instantiations.IsArray());
4223 intptr_t length = prior_instantiations.Length(); 4240 // The instantiations cache is initialized with Object::zero_array() and is
4241 // therefore guaranteed to contain kNoInstantiator. No length check needed.
4242 ASSERT(prior_instantiations.Length() > 0);
4224 intptr_t index = 0; 4243 intptr_t index = 0;
4225 while (index < length) { 4244 while (true) {
4226 if (prior_instantiations.At(index) == instantiator_type_arguments.raw()) { 4245 if (prior_instantiations.At(index) == instantiator_type_arguments.raw()) {
4227 return TypeArguments::RawCast(prior_instantiations.At(index + 1)); 4246 return TypeArguments::RawCast(prior_instantiations.At(index + 1));
4228 } 4247 }
4229 if (prior_instantiations.At(index) == Smi::New(StubCode::kNoInstantiator)) { 4248 if (prior_instantiations.At(index) == Smi::New(StubCode::kNoInstantiator)) {
4230 break; 4249 break;
4231 } 4250 }
4232 index += 2; 4251 index += 2;
4233 } 4252 }
4234 // Cache lookup failed. Instantiate the type arguments. 4253 // Cache lookup failed. Instantiate the type arguments.
4235 TypeArguments& result = TypeArguments::Handle(); 4254 TypeArguments& result = TypeArguments::Handle();
4236 result = InstantiateFrom(instantiator_type_arguments, bound_error); 4255 result = InstantiateFrom(instantiator_type_arguments, bound_error);
4237 if ((bound_error != NULL) && !bound_error->IsNull()) { 4256 if ((bound_error != NULL) && !bound_error->IsNull()) {
4238 return result.raw(); 4257 return result.raw();
4239 } 4258 }
4240 // Instantiation did not result in bound error. Canonicalize type arguments. 4259 // Instantiation did not result in bound error. Canonicalize type arguments.
4241 result = result.Canonicalize(); 4260 result = result.Canonicalize();
4242 // Add instantiator and result to instantiations array. 4261 // Add instantiator and result to instantiations array.
4243 if ((index + 2) > length) { 4262 intptr_t length = prior_instantiations.Length();
4263 if ((index + 2) >= length) {
4244 // Grow the instantiations array. 4264 // Grow the instantiations array.
4245 length = (length == 0) ? 2 : length + 4; 4265 // The initial array is Object::zero_array() of length 1.
4266 length = (length == 1) ? 3 : length + 4;
4246 prior_instantiations = 4267 prior_instantiations =
4247 Array::Grow(prior_instantiations, length, Heap::kOld); 4268 Array::Grow(prior_instantiations, length, Heap::kOld);
4248 set_instantiations(prior_instantiations); 4269 set_instantiations(prior_instantiations);
4270 ASSERT((index + 2) < length);
4249 } 4271 }
4250 prior_instantiations.SetAt(index, instantiator_type_arguments); 4272 prior_instantiations.SetAt(index, instantiator_type_arguments);
4251 prior_instantiations.SetAt(index + 1, result); 4273 prior_instantiations.SetAt(index + 1, result);
4252 if ((index + 2) < length) { 4274 prior_instantiations.SetAt(index + 2,
4253 prior_instantiations.SetAt(index + 2, 4275 Smi::Handle(Smi::New(StubCode::kNoInstantiator)));
4254 Smi::Handle(Smi::New(StubCode::kNoInstantiator)));
4255 }
4256 return result.raw(); 4276 return result.raw();
4257 } 4277 }
4258 4278
4259 4279
4260 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { 4280 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) {
4261 if (len < 0 || len > kMaxElements) { 4281 if (len < 0 || len > kMaxElements) {
4262 // This should be caught before we reach here. 4282 // This should be caught before we reach here.
4263 FATAL1("Fatal error in TypeArguments::New: invalid len %" Pd "\n", len); 4283 FATAL1("Fatal error in TypeArguments::New: invalid len %" Pd "\n", len);
4264 } 4284 }
4265 TypeArguments& result = TypeArguments::Handle(); 4285 TypeArguments& result = TypeArguments::Handle();
4266 { 4286 {
4267 RawObject* raw = Object::Allocate(TypeArguments::kClassId, 4287 RawObject* raw = Object::Allocate(TypeArguments::kClassId,
4268 TypeArguments::InstanceSize(len), 4288 TypeArguments::InstanceSize(len),
4269 space); 4289 space);
4270 NoGCScope no_gc; 4290 NoGCScope no_gc;
4271 result ^= raw; 4291 result ^= raw;
4272 // Length must be set before we start storing into the array. 4292 // Length must be set before we start storing into the array.
4273 result.SetLength(len); 4293 result.SetLength(len);
4274 } 4294 }
4275 result.set_instantiations(Object::empty_array()); 4295 // The zero array should have been initialized.
4296 ASSERT(Object::zero_array().raw() != Array::null());
4297 ASSERT(StubCode::kNoInstantiator == 0);
Florian Schneider 2014/02/17 10:09:59 That can be make a COMPILE_ASSERT.
regis 2014/02/18 19:29:29 I had never noticed this assert flavor before. Don
4298 result.set_instantiations(Object::zero_array());
4276 return result.raw(); 4299 return result.raw();
4277 } 4300 }
4278 4301
4279 4302
4280 4303
4281 RawAbstractType** TypeArguments::TypeAddr(intptr_t index) const { 4304 RawAbstractType** TypeArguments::TypeAddr(intptr_t index) const {
4282 // TODO(iposva): Determine if we should throw an exception here. 4305 // TODO(iposva): Determine if we should throw an exception here.
4283 ASSERT((index >= 0) && (index < Length())); 4306 ASSERT((index >= 0) && (index < Length()));
4284 return &raw_ptr()->types_[index]; 4307 return &raw_ptr()->types_[index];
4285 } 4308 }
(...skipping 13113 matching lines...) Expand 10 before | Expand all | Expand 10 after
17399 return "_MirrorReference"; 17422 return "_MirrorReference";
17400 } 17423 }
17401 17424
17402 17425
17403 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 17426 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
17404 Instance::PrintToJSONStream(stream, ref); 17427 Instance::PrintToJSONStream(stream, ref);
17405 } 17428 }
17406 17429
17407 17430
17408 } // namespace dart 17431 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698