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/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 // Initialization from Class::New<Class>. | 266 // Initialization from Class::New<Class>. |
267 // Directly set raw_ to break a circular dependency: SetRaw will attempt | 267 // Directly set raw_ to break a circular dependency: SetRaw will attempt |
268 // to lookup class class in the class table where it is not registered yet. | 268 // to lookup class class in the class table where it is not registered yet. |
269 cls.raw_ = class_class_; | 269 cls.raw_ = class_class_; |
270 cls.set_handle_vtable(fake.vtable()); | 270 cls.set_handle_vtable(fake.vtable()); |
271 cls.set_instance_size(Class::InstanceSize()); | 271 cls.set_instance_size(Class::InstanceSize()); |
272 cls.set_next_field_offset(Class::InstanceSize()); | 272 cls.set_next_field_offset(Class::InstanceSize()); |
273 cls.set_id(Class::kClassId); | 273 cls.set_id(Class::kClassId); |
274 cls.raw_ptr()->state_bits_ = 0; | 274 cls.raw_ptr()->state_bits_ = 0; |
275 cls.set_is_finalized(); | 275 cls.set_is_finalized(); |
276 cls.raw_ptr()->type_arguments_instance_field_offset_ = | 276 cls.raw_ptr()->type_arguments_field_offset_ = Class::kNoTypeArguments; |
277 Class::kNoTypeArguments; | |
278 cls.raw_ptr()->num_native_fields_ = 0; | 277 cls.raw_ptr()->num_native_fields_ = 0; |
279 cls.InitEmptyFields(); | 278 cls.InitEmptyFields(); |
280 isolate->class_table()->Register(cls); | 279 isolate->class_table()->Register(cls); |
281 } | 280 } |
282 | 281 |
283 // Allocate and initialize the null class. | 282 // Allocate and initialize the null class. |
284 cls = Class::New<Instance>(kNullCid); | 283 cls = Class::New<Instance>(kNullCid); |
285 cls.set_is_finalized(); | 284 cls.set_is_finalized(); |
286 null_class_ = cls.raw(); | 285 null_class_ = cls.raw(); |
287 | 286 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 | 549 |
551 // All RawArray fields will be initialized to an empty array, therefore | 550 // All RawArray fields will be initialized to an empty array, therefore |
552 // initialize array class first. | 551 // initialize array class first. |
553 cls = Class::New<Array>(); | 552 cls = Class::New<Array>(); |
554 object_store->set_array_class(cls); | 553 object_store->set_array_class(cls); |
555 | 554 |
556 // Array and ImmutableArray are the only VM classes that are parameterized. | 555 // Array and ImmutableArray are the only VM classes that are parameterized. |
557 // Since they are pre-finalized, CalculateFieldOffsets() is not called, so we | 556 // Since they are pre-finalized, CalculateFieldOffsets() is not called, so we |
558 // need to set the offset of their type_arguments_ field, which is explicitly | 557 // need to set the offset of their type_arguments_ field, which is explicitly |
559 // declared in RawArray. | 558 // declared in RawArray. |
560 cls.set_type_arguments_instance_field_offset(Array::type_arguments_offset()); | 559 cls.set_type_arguments_field_offset(Array::type_arguments_offset()); |
561 | 560 |
562 // Set up the growable object array class (Has to be done after the array | 561 // Set up the growable object array class (Has to be done after the array |
563 // class is setup as one of its field is an array object). | 562 // class is setup as one of its field is an array object). |
564 cls = Class::New<GrowableObjectArray>(); | 563 cls = Class::New<GrowableObjectArray>(); |
565 object_store->set_growable_object_array_class(cls); | 564 object_store->set_growable_object_array_class(cls); |
566 cls.set_type_arguments_instance_field_offset( | 565 cls.set_type_arguments_field_offset( |
567 GrowableObjectArray::type_arguments_offset()); | 566 GrowableObjectArray::type_arguments_offset()); |
568 | 567 |
569 // canonical_type_arguments_ are NULL terminated. | 568 // canonical_type_arguments_ are NULL terminated. |
570 array = Array::New(4); | 569 array = Array::New(4); |
571 object_store->set_canonical_type_arguments(array); | 570 object_store->set_canonical_type_arguments(array); |
572 | 571 |
573 // Setup type class early in the process. | 572 // Setup type class early in the process. |
574 cls = Class::New<Type>(); | 573 cls = Class::New<Type>(); |
575 object_store->set_type_class(cls); | 574 object_store->set_type_class(cls); |
576 | 575 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 type ^= type.Canonicalize(); | 626 type ^= type.Canonicalize(); |
628 object_store->set_array_type(type); | 627 object_store->set_array_type(type); |
629 | 628 |
630 cls = object_store->growable_object_array_class(); // Was allocated above. | 629 cls = object_store->growable_object_array_class(); // Was allocated above. |
631 name = Symbols::GrowableObjectArray(); | 630 name = Symbols::GrowableObjectArray(); |
632 RegisterPrivateClass(cls, name, core_lib); | 631 RegisterPrivateClass(cls, name, core_lib); |
633 pending_classes.Add(cls, Heap::kOld); | 632 pending_classes.Add(cls, Heap::kOld); |
634 | 633 |
635 cls = Class::New<ImmutableArray>(); | 634 cls = Class::New<ImmutableArray>(); |
636 object_store->set_immutable_array_class(cls); | 635 object_store->set_immutable_array_class(cls); |
637 cls.set_type_arguments_instance_field_offset(Array::type_arguments_offset()); | 636 cls.set_type_arguments_field_offset(Array::type_arguments_offset()); |
638 ASSERT(object_store->immutable_array_class() != object_store->array_class()); | 637 ASSERT(object_store->immutable_array_class() != object_store->array_class()); |
639 name = Symbols::ImmutableArray(); | 638 name = Symbols::ImmutableArray(); |
640 RegisterPrivateClass(cls, name, core_lib); | 639 RegisterPrivateClass(cls, name, core_lib); |
641 pending_classes.Add(cls, Heap::kOld); | 640 pending_classes.Add(cls, Heap::kOld); |
642 | 641 |
643 cls = object_store->one_byte_string_class(); // Was allocated above. | 642 cls = object_store->one_byte_string_class(); // Was allocated above. |
644 name = Symbols::OneByteString(); | 643 name = Symbols::OneByteString(); |
645 RegisterPrivateClass(cls, name, core_lib); | 644 RegisterPrivateClass(cls, name, core_lib); |
646 pending_classes.Add(cls, Heap::kOld); | 645 pending_classes.Add(cls, Heap::kOld); |
647 | 646 |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 FakeObject fake; | 1363 FakeObject fake; |
1365 result.set_handle_vtable(fake.vtable()); | 1364 result.set_handle_vtable(fake.vtable()); |
1366 result.set_instance_size(FakeObject::InstanceSize()); | 1365 result.set_instance_size(FakeObject::InstanceSize()); |
1367 result.set_next_field_offset(FakeObject::InstanceSize()); | 1366 result.set_next_field_offset(FakeObject::InstanceSize()); |
1368 ASSERT((FakeObject::kClassId != kInstanceCid)); | 1367 ASSERT((FakeObject::kClassId != kInstanceCid)); |
1369 result.set_id(FakeObject::kClassId); | 1368 result.set_id(FakeObject::kClassId); |
1370 result.raw_ptr()->state_bits_ = 0; | 1369 result.raw_ptr()->state_bits_ = 0; |
1371 // VM backed classes are almost ready: run checks and resolve class | 1370 // VM backed classes are almost ready: run checks and resolve class |
1372 // references, but do not recompute size. | 1371 // references, but do not recompute size. |
1373 result.set_is_prefinalized(); | 1372 result.set_is_prefinalized(); |
1374 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 1373 result.raw_ptr()->type_arguments_field_offset_ = kNoTypeArguments; |
1375 result.raw_ptr()->num_native_fields_ = 0; | 1374 result.raw_ptr()->num_native_fields_ = 0; |
1376 result.raw_ptr()->token_pos_ = Scanner::kDummyTokenIndex; | 1375 result.raw_ptr()->token_pos_ = Scanner::kDummyTokenIndex; |
1377 result.InitEmptyFields(); | 1376 result.InitEmptyFields(); |
1378 Isolate::Current()->class_table()->Register(result); | 1377 Isolate::Current()->class_table()->Register(result); |
1379 return result.raw(); | 1378 return result.raw(); |
1380 } | 1379 } |
1381 | 1380 |
1382 | 1381 |
1383 // Initialize class fields of type Array with empty array. | 1382 // Initialize class fields of type Array with empty array. |
1384 void Class::InitEmptyFields() { | 1383 void Class::InitEmptyFields() { |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1518 if (!superclass.IsNull() && (superclass.raw() != raw())) { | 1517 if (!superclass.IsNull() && (superclass.raw() != raw())) { |
1519 num_type_args += superclass.NumTypeArguments(); | 1518 num_type_args += superclass.NumTypeArguments(); |
1520 } | 1519 } |
1521 return num_type_args; | 1520 return num_type_args; |
1522 } | 1521 } |
1523 | 1522 |
1524 | 1523 |
1525 bool Class::HasTypeArguments() const { | 1524 bool Class::HasTypeArguments() const { |
1526 if (!IsSignatureClass() && (is_finalized() || is_prefinalized())) { | 1525 if (!IsSignatureClass() && (is_finalized() || is_prefinalized())) { |
1527 // More efficient than calling NumTypeArguments(). | 1526 // More efficient than calling NumTypeArguments(). |
1528 return type_arguments_instance_field_offset() != kNoTypeArguments; | 1527 return type_arguments_field_offset() != kNoTypeArguments; |
1529 } else { | 1528 } else { |
1530 // No need to check NumTypeArguments() if class has type parameters. | 1529 // No need to check NumTypeArguments() if class has type parameters. |
1531 return (NumTypeParameters() > 0) || (NumTypeArguments() > 0); | 1530 return (NumTypeParameters() > 0) || (NumTypeArguments() > 0); |
1532 } | 1531 } |
1533 } | 1532 } |
1534 | 1533 |
1535 | 1534 |
1536 RawClass* Class::SuperClass() const { | 1535 RawClass* Class::SuperClass() const { |
1537 const Type& sup_type = Type::Handle(super_type()); | 1536 const Type& sup_type = Type::Handle(super_type()); |
1538 if (sup_type.IsNull()) { | 1537 if (sup_type.IsNull()) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1617 | 1616 |
1618 | 1617 |
1619 void Class::CalculateFieldOffsets() const { | 1618 void Class::CalculateFieldOffsets() const { |
1620 Array& flds = Array::Handle(fields()); | 1619 Array& flds = Array::Handle(fields()); |
1621 const Class& super = Class::Handle(SuperClass()); | 1620 const Class& super = Class::Handle(SuperClass()); |
1622 intptr_t offset = 0; | 1621 intptr_t offset = 0; |
1623 intptr_t type_args_field_offset = kNoTypeArguments; | 1622 intptr_t type_args_field_offset = kNoTypeArguments; |
1624 if (super.IsNull()) { | 1623 if (super.IsNull()) { |
1625 offset = sizeof(RawObject); | 1624 offset = sizeof(RawObject); |
1626 } else { | 1625 } else { |
1627 type_args_field_offset = super.type_arguments_instance_field_offset(); | 1626 type_args_field_offset = super.type_arguments_field_offset(); |
1628 offset = super.next_field_offset(); | 1627 offset = super.next_field_offset(); |
1629 ASSERT(offset > 0); | 1628 ASSERT(offset > 0); |
1630 // We should never call CalculateFieldOffsets for native wrapper | 1629 // We should never call CalculateFieldOffsets for native wrapper |
1631 // classes, assert this. | 1630 // classes, assert this. |
1632 ASSERT(num_native_fields() == 0); | 1631 ASSERT(num_native_fields() == 0); |
1633 set_num_native_fields(super.num_native_fields()); | 1632 set_num_native_fields(super.num_native_fields()); |
1634 } | 1633 } |
1635 // If the super class is parameterized, use the same type_arguments field. | 1634 // If the super class is parameterized, use the same type_arguments field. |
1636 if (type_args_field_offset == kNoTypeArguments) { | 1635 if (type_args_field_offset == kNoTypeArguments) { |
1637 const TypeArguments& type_params = TypeArguments::Handle(type_parameters()); | 1636 const TypeArguments& type_params = TypeArguments::Handle(type_parameters()); |
1638 if (!type_params.IsNull()) { | 1637 if (!type_params.IsNull()) { |
1639 ASSERT(type_params.Length() > 0); | 1638 ASSERT(type_params.Length() > 0); |
1640 // The instance needs a type_arguments field. | 1639 // The instance needs a type_arguments field. |
1641 type_args_field_offset = offset; | 1640 type_args_field_offset = offset; |
1642 offset += kWordSize; | 1641 offset += kWordSize; |
1643 } | 1642 } |
1644 } | 1643 } |
1645 set_type_arguments_instance_field_offset(type_args_field_offset); | 1644 set_type_arguments_field_offset(type_args_field_offset); |
1646 ASSERT(offset != 0); | 1645 ASSERT(offset != 0); |
1647 Field& field = Field::Handle(); | 1646 Field& field = Field::Handle(); |
1648 intptr_t len = flds.Length(); | 1647 intptr_t len = flds.Length(); |
1649 for (intptr_t i = 0; i < len; i++) { | 1648 for (intptr_t i = 0; i < len; i++) { |
1650 field ^= flds.At(i); | 1649 field ^= flds.At(i); |
1651 // Offset is computed only for instance fields. | 1650 // Offset is computed only for instance fields. |
1652 if (!field.is_static()) { | 1651 if (!field.is_static()) { |
1653 ASSERT(field.Offset() == 0); | 1652 ASSERT(field.Offset() == 0); |
1654 field.SetOffset(offset); | 1653 field.SetOffset(offset); |
1655 offset += kWordSize; | 1654 offset += kWordSize; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1784 NoGCScope no_gc; | 1783 NoGCScope no_gc; |
1785 result ^= raw; | 1784 result ^= raw; |
1786 } | 1785 } |
1787 FakeInstance fake; | 1786 FakeInstance fake; |
1788 ASSERT(fake.IsInstance()); | 1787 ASSERT(fake.IsInstance()); |
1789 result.set_handle_vtable(fake.vtable()); | 1788 result.set_handle_vtable(fake.vtable()); |
1790 result.set_instance_size(FakeInstance::InstanceSize()); | 1789 result.set_instance_size(FakeInstance::InstanceSize()); |
1791 result.set_next_field_offset(FakeInstance::InstanceSize()); | 1790 result.set_next_field_offset(FakeInstance::InstanceSize()); |
1792 result.set_id(index); | 1791 result.set_id(index); |
1793 result.raw_ptr()->state_bits_ = 0; | 1792 result.raw_ptr()->state_bits_ = 0; |
1794 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 1793 result.raw_ptr()->type_arguments_field_offset_ = kNoTypeArguments; |
1795 result.raw_ptr()->num_native_fields_ = 0; | 1794 result.raw_ptr()->num_native_fields_ = 0; |
1796 result.raw_ptr()->token_pos_ = Scanner::kDummyTokenIndex; | 1795 result.raw_ptr()->token_pos_ = Scanner::kDummyTokenIndex; |
1797 result.InitEmptyFields(); | 1796 result.InitEmptyFields(); |
1798 Isolate::Current()->class_table()->Register(result); | 1797 Isolate::Current()->class_table()->Register(result); |
1799 return result.raw(); | 1798 return result.raw(); |
1800 } | 1799 } |
1801 | 1800 |
1802 | 1801 |
1803 template <class FakeInstance> | 1802 template <class FakeInstance> |
1804 RawClass* Class::New(const String& name, | 1803 RawClass* Class::New(const String& name, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1849 const Type& super_type = Type::Handle(Type::ObjectType()); | 1848 const Type& super_type = Type::Handle(Type::ObjectType()); |
1850 const Array& empty_array = Array::Handle(Object::empty_array()); | 1849 const Array& empty_array = Array::Handle(Object::empty_array()); |
1851 ASSERT(!super_type.IsNull()); | 1850 ASSERT(!super_type.IsNull()); |
1852 result.set_instance_size(Closure::InstanceSize()); | 1851 result.set_instance_size(Closure::InstanceSize()); |
1853 result.set_next_field_offset(Closure::InstanceSize()); | 1852 result.set_next_field_offset(Closure::InstanceSize()); |
1854 result.set_super_type(super_type); | 1853 result.set_super_type(super_type); |
1855 result.set_signature_function(signature_function); | 1854 result.set_signature_function(signature_function); |
1856 result.set_type_parameters(type_parameters); | 1855 result.set_type_parameters(type_parameters); |
1857 result.SetFields(empty_array); | 1856 result.SetFields(empty_array); |
1858 result.SetFunctions(empty_array); | 1857 result.SetFunctions(empty_array); |
1859 result.set_type_arguments_instance_field_offset( | 1858 result.set_type_arguments_field_offset( |
1860 Closure::type_arguments_offset()); | 1859 Closure::type_arguments_offset()); |
1861 // Implements interface "Function". | 1860 // Implements interface "Function". |
1862 const Type& function_type = Type::Handle(Type::Function()); | 1861 const Type& function_type = Type::Handle(Type::Function()); |
1863 const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld)); | 1862 const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld)); |
1864 interfaces.SetAt(0, function_type); | 1863 interfaces.SetAt(0, function_type); |
1865 result.set_interfaces(interfaces); | 1864 result.set_interfaces(interfaces); |
1866 // Unless the signature function already has a signature class, create a | 1865 // Unless the signature function already has a signature class, create a |
1867 // canonical signature class by having the signature function point back to | 1866 // canonical signature class by having the signature function point back to |
1868 // the signature class. | 1867 // the signature class. |
1869 if (signature_function.signature_class() == Object::null()) { | 1868 if (signature_function.signature_class() == Object::null()) { |
(...skipping 6346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8216 } | 8215 } |
8217 const Type& type = Type::Handle( | 8216 const Type& type = Type::Handle( |
8218 Type::New(cls, type_arguments, Scanner::kDummyTokenIndex)); | 8217 Type::New(cls, type_arguments, Scanner::kDummyTokenIndex)); |
8219 type.set_is_finalized_instantiated(); | 8218 type.set_is_finalized_instantiated(); |
8220 return type.raw(); | 8219 return type.raw(); |
8221 } | 8220 } |
8222 | 8221 |
8223 | 8222 |
8224 RawAbstractTypeArguments* Instance::GetTypeArguments() const { | 8223 RawAbstractTypeArguments* Instance::GetTypeArguments() const { |
8225 const Class& cls = Class::Handle(clazz()); | 8224 const Class& cls = Class::Handle(clazz()); |
8226 intptr_t field_offset = cls.type_arguments_instance_field_offset(); | 8225 intptr_t field_offset = cls.type_arguments_field_offset(); |
8227 ASSERT(field_offset != Class::kNoTypeArguments); | 8226 ASSERT(field_offset != Class::kNoTypeArguments); |
8228 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); | 8227 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); |
8229 type_arguments ^= *FieldAddrAtOffset(field_offset); | 8228 type_arguments ^= *FieldAddrAtOffset(field_offset); |
8230 return type_arguments.raw(); | 8229 return type_arguments.raw(); |
8231 } | 8230 } |
8232 | 8231 |
8233 | 8232 |
8234 void Instance::SetTypeArguments(const AbstractTypeArguments& value) const { | 8233 void Instance::SetTypeArguments(const AbstractTypeArguments& value) const { |
8235 const Class& cls = Class::Handle(clazz()); | 8234 const Class& cls = Class::Handle(clazz()); |
8236 intptr_t field_offset = cls.type_arguments_instance_field_offset(); | 8235 intptr_t field_offset = cls.type_arguments_field_offset(); |
8237 ASSERT(field_offset != Class::kNoTypeArguments); | 8236 ASSERT(field_offset != Class::kNoTypeArguments); |
8238 SetFieldAtOffset(field_offset, value); | 8237 SetFieldAtOffset(field_offset, value); |
8239 } | 8238 } |
8240 | 8239 |
8241 | 8240 |
8242 bool Instance::IsInstanceOf(const AbstractType& other, | 8241 bool Instance::IsInstanceOf(const AbstractType& other, |
8243 const AbstractTypeArguments& other_instantiator, | 8242 const AbstractTypeArguments& other_instantiator, |
8244 Error* malformed_error) const { | 8243 Error* malformed_error) const { |
8245 ASSERT(other.IsFinalized()); | 8244 ASSERT(other.IsFinalized()); |
8246 ASSERT(!other.IsDynamicType()); | 8245 ASSERT(!other.IsDynamicType()); |
(...skipping 3947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12194 } | 12193 } |
12195 return result.raw(); | 12194 return result.raw(); |
12196 } | 12195 } |
12197 | 12196 |
12198 | 12197 |
12199 const char* WeakProperty::ToCString() const { | 12198 const char* WeakProperty::ToCString() const { |
12200 return "_WeakProperty"; | 12199 return "_WeakProperty"; |
12201 } | 12200 } |
12202 | 12201 |
12203 } // namespace dart | 12202 } // namespace dart |
OLD | NEW |