OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |