| 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 |