| 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 "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 case kVoidClass: return "void"; | 212 case kVoidClass: return "void"; |
| 213 case kUnresolvedClassClass: return "UnresolvedClass"; | 213 case kUnresolvedClassClass: return "UnresolvedClass"; |
| 214 case kTypeClass: return "Type"; | 214 case kTypeClass: return "Type"; |
| 215 case kTypeParameterClass: return "TypeParameter"; | 215 case kTypeParameterClass: return "TypeParameter"; |
| 216 case kInstantiatedTypeClass: return "InstantiatedType"; | 216 case kInstantiatedTypeClass: return "InstantiatedType"; |
| 217 case kAbstractTypeArgumentsClass: return "AbstractTypeArguments"; | 217 case kAbstractTypeArgumentsClass: return "AbstractTypeArguments"; |
| 218 case kTypeArgumentsClass: return "TypeArguments"; | 218 case kTypeArgumentsClass: return "TypeArguments"; |
| 219 case kInstantiatedTypeArgumentsClass: return "InstantiatedTypeArguments"; | 219 case kInstantiatedTypeArgumentsClass: return "InstantiatedTypeArguments"; |
| 220 case kFunctionClass: return "Function"; | 220 case kFunctionClass: return "Function"; |
| 221 case kFieldClass: return "Field"; | 221 case kFieldClass: return "Field"; |
| 222 case kLiteralTokenClass: return "LiteralToken"; |
| 222 case kTokenStreamClass: return "TokenStream"; | 223 case kTokenStreamClass: return "TokenStream"; |
| 223 case kScriptClass: return "Script"; | 224 case kScriptClass: return "Script"; |
| 224 case kLibraryClass: return "Library"; | 225 case kLibraryClass: return "Library"; |
| 225 case kLibraryPrefixClass: return "LibraryPrefix"; | 226 case kLibraryPrefixClass: return "LibraryPrefix"; |
| 226 case kCodeClass: return "Code"; | 227 case kCodeClass: return "Code"; |
| 227 case kInstructionsClass: return "Instructions"; | 228 case kInstructionsClass: return "Instructions"; |
| 228 case kPcDescriptorsClass: return "PcDescriptors"; | 229 case kPcDescriptorsClass: return "PcDescriptors"; |
| 229 case kStackmapClass: return "Stackmap"; | 230 case kStackmapClass: return "Stackmap"; |
| 230 case kLocalVarDescriptorsClass: return "LocalVarDescriptors"; | 231 case kLocalVarDescriptorsClass: return "LocalVarDescriptors"; |
| 231 case kExceptionHandlersClass: return "ExceptionHandlers"; | 232 case kExceptionHandlersClass: return "ExceptionHandlers"; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 254 Smi::handle_vtable_ = fake_smi.vtable(); | 255 Smi::handle_vtable_ = fake_smi.vtable(); |
| 255 } | 256 } |
| 256 | 257 |
| 257 Heap* heap = Isolate::Current()->heap(); | 258 Heap* heap = Isolate::Current()->heap(); |
| 258 // Allocate and initialize the null instance, except its class_ field. | 259 // Allocate and initialize the null instance, except its class_ field. |
| 259 // 'null_' must be the first object allocated as it is used in allocation to | 260 // 'null_' must be the first object allocated as it is used in allocation to |
| 260 // clear the object. | 261 // clear the object. |
| 261 { | 262 { |
| 262 uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld); | 263 uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld); |
| 263 null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag); | 264 null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag); |
| 264 InitializeObject(address, Instance::InstanceSize()); // Using 'null_'. | 265 InitializeObject(address, |
| 265 null_->ptr()->tags_ = 0; | 266 kNullClassIndex, |
| 267 Instance::InstanceSize()); // Using 'null_'. |
| 266 } | 268 } |
| 267 | 269 |
| 268 // Initialize object_store empty array to null_ in order to be able to check | 270 // Initialize object_store empty array to null_ in order to be able to check |
| 269 // if the empty array was allocated (RAW_NULL is not available). | 271 // if the empty array was allocated (RAW_NULL is not available). |
| 270 Isolate::Current()->object_store()->set_empty_array(Array::Handle()); | 272 Isolate::Current()->object_store()->set_empty_array(Array::Handle()); |
| 271 | 273 |
| 272 Class& cls = Class::Handle(); | 274 Class& cls = Class::Handle(); |
| 273 | 275 |
| 274 // Allocate and initialize the class class. | 276 // Allocate and initialize the class class. |
| 275 // At this point, class_class_ is still RAW_NULL, i.e. different from 'null_', | 277 { |
| 276 // since 'null_' is not RAW_NULL anymore. However, class_class_ == null_ must | 278 intptr_t size = Class::InstanceSize(); |
| 277 // be true before calling Class::New<Class>(), or it will fail. | 279 uword address = heap->Allocate(size, Heap::kOld); |
| 278 class_class_ = Class::Handle().raw(); // Set 'class_class_' to 'null_'. | 280 class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag); |
| 279 cls = Class::New<Class>(); | 281 InitializeObject(address, Class::kInstanceKind, size); |
| 280 cls.set_is_finalized(); | 282 // Make the class_ field point to itself. |
| 281 class_class_ = cls.raw(); | 283 class_class_->ptr()->class_ = class_class_; |
| 282 // Make the class_ field point to itself. | 284 |
| 283 class_class_->ptr()->class_ = class_class_; | 285 Class fake; |
| 286 // Initialization from Class::New<Class>. |
| 287 cls = class_class_; |
| 288 cls.set_handle_vtable(fake.vtable()); |
| 289 cls.set_instance_size(Class::InstanceSize()); |
| 290 cls.set_next_field_offset(Class::InstanceSize()); |
| 291 cls.set_instance_kind(Class::kInstanceKind); |
| 292 cls.set_index(Class::kInstanceKind); |
| 293 cls.raw_ptr()->is_const_ = false; |
| 294 cls.raw_ptr()->is_interface_ = false; |
| 295 cls.set_is_finalized(); |
| 296 cls.raw_ptr()->type_arguments_instance_field_offset_ = |
| 297 Class::kNoTypeArguments; |
| 298 cls.raw_ptr()->num_native_fields_ = 0; |
| 299 cls.InitEmptyFields(); |
| 300 Isolate::Current()->class_table()->Register(cls); |
| 301 } |
| 284 | 302 |
| 285 // Allocate and initialize the null class. | 303 // Allocate and initialize the null class. |
| 286 cls = Class::New<Instance>(); | 304 cls = Class::New<Instance>(kNullClassIndex); |
| 287 cls.set_is_finalized(); | 305 cls.set_is_finalized(); |
| 288 null_class_ = cls.raw(); | 306 null_class_ = cls.raw(); |
| 289 | 307 |
| 290 // Complete initialization of null_ instance, i.e. initialize its class_ | 308 // Complete initialization of null_ instance, i.e. initialize its class_ |
| 291 // field. | 309 // field. |
| 292 null_->ptr()->class_ = null_class_; | 310 null_->ptr()->class_ = null_class_; |
| 293 | 311 |
| 294 // Allocate and initialize the sentinel values of an instance class. | 312 // Allocate and initialize the sentinel values. |
| 295 { | 313 { |
| 296 cls = Class::New<Instance>(); | 314 cls = Class::New<Instance>(kSentinelClassIndex); |
| 297 Instance& sentinel = Instance::Handle(); | 315 Instance& sentinel = Instance::Handle(); |
| 298 sentinel ^= Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); | 316 sentinel ^= Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); |
| 299 sentinel_ = sentinel.raw(); | 317 sentinel_ = sentinel.raw(); |
| 300 | 318 |
| 301 Instance& transition_sentinel = Instance::Handle(); | 319 Instance& transition_sentinel = Instance::Handle(); |
| 302 transition_sentinel ^= | 320 transition_sentinel ^= |
| 303 Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); | 321 Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); |
| 304 transition_sentinel_ = transition_sentinel.raw(); | 322 transition_sentinel_ = transition_sentinel.raw(); |
| 305 } | 323 } |
| 306 | 324 |
| 307 // The interface "Dynamic" is not a VM internal class. It is the type class of | 325 // The interface "Dynamic" is not a VM internal class. It is the type class of |
| 308 // the "unknown type". For efficiency, we allocate it in the VM isolate. | 326 // the "unknown type". For efficiency, we allocate it in the VM isolate. |
| 309 // Therefore, it cannot have a heap allocated name (the name is hard coded, | 327 // Therefore, it cannot have a heap allocated name (the name is hard coded, |
| 310 // see GetSingletonClassIndex) and its array fields cannot be set to the empty | 328 // see GetSingletonClassIndex) and its array fields cannot be set to the empty |
| 311 // array, but remain null. | 329 // array, but remain null. |
| 312 cls = Class::New<Instance>(); | 330 cls = Class::New<Instance>(kDynamicClassIndex); |
| 313 cls.set_is_finalized(); | 331 cls.set_is_finalized(); |
| 314 cls.set_is_interface(); | 332 cls.set_is_interface(); |
| 315 dynamic_class_ = cls.raw(); | 333 dynamic_class_ = cls.raw(); |
| 316 | 334 |
| 317 // Allocate the remaining VM internal classes. | 335 // Allocate the remaining VM internal classes. |
| 318 cls = Class::New<UnresolvedClass>(); | 336 cls = Class::New<UnresolvedClass>(); |
| 319 unresolved_class_class_ = cls.raw(); | 337 unresolved_class_class_ = cls.raw(); |
| 320 | 338 |
| 321 cls = Class::New<Instance>(); | 339 cls = Class::New<Instance>(kVoidClassIndex); |
| 322 cls.set_is_finalized(); | 340 cls.set_is_finalized(); |
| 323 void_class_ = cls.raw(); | 341 void_class_ = cls.raw(); |
| 324 | 342 |
| 325 cls = Class::New<Type>(); | 343 cls = Class::New<Type>(); |
| 326 type_class_ = cls.raw(); | 344 type_class_ = cls.raw(); |
| 327 | 345 |
| 328 cls = Class::New<TypeParameter>(); | 346 cls = Class::New<TypeParameter>(); |
| 329 type_parameter_class_ = cls.raw(); | 347 type_parameter_class_ = cls.raw(); |
| 330 | 348 |
| 331 cls = Class::New<InstantiatedType>(); | 349 cls = Class::New<InstantiatedType>(); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 RegisterClass(cls, "ObjectArray", impl_script, core_impl_lib); | 539 RegisterClass(cls, "ObjectArray", impl_script, core_impl_lib); |
| 522 pending_classes.Add(cls, Heap::kOld); | 540 pending_classes.Add(cls, Heap::kOld); |
| 523 | 541 |
| 524 cls = Class::New<ImmutableArray>(); | 542 cls = Class::New<ImmutableArray>(); |
| 525 object_store->set_immutable_array_class(cls); | 543 object_store->set_immutable_array_class(cls); |
| 526 cls.set_type_arguments_instance_field_offset(Array::type_arguments_offset()); | 544 cls.set_type_arguments_instance_field_offset(Array::type_arguments_offset()); |
| 527 ASSERT(object_store->immutable_array_class() != object_store->array_class()); | 545 ASSERT(object_store->immutable_array_class() != object_store->array_class()); |
| 528 RegisterClass(cls, "ImmutableArray", impl_script, core_impl_lib); | 546 RegisterClass(cls, "ImmutableArray", impl_script, core_impl_lib); |
| 529 pending_classes.Add(cls, Heap::kOld); | 547 pending_classes.Add(cls, Heap::kOld); |
| 530 | 548 |
| 549 cls = object_store->growable_object_array_class(); // Was allocated above. |
| 550 RegisterClass(cls, "Siva's GrowableObjectArray", impl_script, core_impl_lib); |
| 551 pending_classes.Add(cls, Heap::kOld); |
| 552 |
| 531 cls = object_store->one_byte_string_class(); // Was allocated above. | 553 cls = object_store->one_byte_string_class(); // Was allocated above. |
| 532 RegisterClass(cls, "OneByteString", impl_script, core_impl_lib); | 554 RegisterClass(cls, "OneByteString", impl_script, core_impl_lib); |
| 533 pending_classes.Add(cls, Heap::kOld); | 555 pending_classes.Add(cls, Heap::kOld); |
| 534 | 556 |
| 535 cls = Class::New<TwoByteString>(); | 557 cls = Class::New<TwoByteString>(); |
| 536 object_store->set_two_byte_string_class(cls); | 558 object_store->set_two_byte_string_class(cls); |
| 537 RegisterClass(cls, "TwoByteString", impl_script, core_impl_lib); | 559 RegisterClass(cls, "TwoByteString", impl_script, core_impl_lib); |
| 538 pending_classes.Add(cls, Heap::kOld); | 560 pending_classes.Add(cls, Heap::kOld); |
| 539 | 561 |
| 540 cls = Class::New<FourByteString>(); | 562 cls = Class::New<FourByteString>(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 571 // Initialize the base interfaces used by the core VM classes. | 593 // Initialize the base interfaces used by the core VM classes. |
| 572 const Script& script = Script::Handle(Bootstrap::LoadScript()); | 594 const Script& script = Script::Handle(Bootstrap::LoadScript()); |
| 573 | 595 |
| 574 // Allocate and initialize the Object class and type. | 596 // Allocate and initialize the Object class and type. |
| 575 // The Object and ExternalByteArray classes are the only pre-allocated | 597 // The Object and ExternalByteArray classes are the only pre-allocated |
| 576 // non-interface classes in the core library. | 598 // non-interface classes in the core library. |
| 577 cls = Class::New<Instance>(); | 599 cls = Class::New<Instance>(); |
| 578 object_store->set_object_class(cls); | 600 object_store->set_object_class(cls); |
| 579 cls.set_name(String::Handle(String::NewSymbol("Object"))); | 601 cls.set_name(String::Handle(String::NewSymbol("Object"))); |
| 580 cls.set_script(script); | 602 cls.set_script(script); |
| 603 cls.set_class_state(RawClass::kPreFinalized); |
| 581 core_lib.AddClass(cls); | 604 core_lib.AddClass(cls); |
| 582 pending_classes.Add(cls, Heap::kOld); | 605 pending_classes.Add(cls, Heap::kOld); |
| 583 type = Type::NewNonParameterizedType(cls); | 606 type = Type::NewNonParameterizedType(cls); |
| 584 object_store->set_object_type(type); | 607 object_store->set_object_type(type); |
| 585 | 608 |
| 586 cls = Class::New<InternalByteArray>(); | 609 cls = Class::New<InternalByteArray>(); |
| 587 object_store->set_internal_byte_array_class(cls); | 610 object_store->set_internal_byte_array_class(cls); |
| 588 String& public_class_name = String::Handle(); | 611 String& public_class_name = String::Handle(); |
| 589 public_class_name = String::New("_InternalByteArray"); | 612 public_class_name = String::New("_InternalByteArray"); |
| 590 cls.set_name(String::Handle(core_lib.PrivateName(public_class_name))); | 613 cls.set_name(String::Handle(core_lib.PrivateName(public_class_name))); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 | 759 |
| 737 cls = Class::New<GrowableObjectArray>(); | 760 cls = Class::New<GrowableObjectArray>(); |
| 738 object_store->set_growable_object_array_class(cls); | 761 object_store->set_growable_object_array_class(cls); |
| 739 | 762 |
| 740 cls = Class::New<InternalByteArray>(); | 763 cls = Class::New<InternalByteArray>(); |
| 741 object_store->set_internal_byte_array_class(cls); | 764 object_store->set_internal_byte_array_class(cls); |
| 742 | 765 |
| 743 cls = Class::New<ExternalByteArray>(); | 766 cls = Class::New<ExternalByteArray>(); |
| 744 object_store->set_external_byte_array_class(cls); | 767 object_store->set_external_byte_array_class(cls); |
| 745 | 768 |
| 746 cls = Class::New<Instance>(); | |
| 747 object_store->set_object_class(cls); | |
| 748 | |
| 749 cls = Class::New<Smi>(); | 769 cls = Class::New<Smi>(); |
| 750 object_store->set_smi_class(cls); | 770 object_store->set_smi_class(cls); |
| 751 | 771 |
| 752 cls = Class::New<Mint>(); | 772 cls = Class::New<Mint>(); |
| 753 object_store->set_mint_class(cls); | 773 object_store->set_mint_class(cls); |
| 754 | 774 |
| 755 cls = Class::New<Double>(); | 775 cls = Class::New<Double>(); |
| 756 object_store->set_double_class(cls); | 776 object_store->set_double_class(cls); |
| 757 | 777 |
| 758 cls = Class::New<Bigint>(); | 778 cls = Class::New<Bigint>(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 bool_value = Bool::New(false); | 812 bool_value = Bool::New(false); |
| 793 object_store->set_false_value(bool_value); | 813 object_store->set_false_value(bool_value); |
| 794 } | 814 } |
| 795 | 815 |
| 796 | 816 |
| 797 void Object::Print() const { | 817 void Object::Print() const { |
| 798 OS::Print("%s\n", ToCString()); | 818 OS::Print("%s\n", ToCString()); |
| 799 } | 819 } |
| 800 | 820 |
| 801 | 821 |
| 802 void Object::InitializeObject(uword address, intptr_t size) { | 822 void Object::InitializeObject(uword address, intptr_t index, intptr_t size) { |
| 803 // TODO(iposva): Get a proper halt instruction from the assembler which | 823 // TODO(iposva): Get a proper halt instruction from the assembler which |
| 804 // would be needed here for code objects. | 824 // would be needed here for code objects. |
| 805 uword initial_value = reinterpret_cast<uword>(null_); | 825 uword initial_value = reinterpret_cast<uword>(null_); |
| 806 uword cur = address; | 826 uword cur = address; |
| 807 uword end = address + size; | 827 uword end = address + size; |
| 808 while (cur < end) { | 828 while (cur < end) { |
| 809 *reinterpret_cast<uword*>(cur) = initial_value; | 829 *reinterpret_cast<uword*>(cur) = initial_value; |
| 810 cur += kWordSize; | 830 cur += kWordSize; |
| 811 } | 831 } |
| 832 uword tags = 0; |
| 833 ASSERT(index != kIllegalObjectKind); |
| 834 tags = RawObject::ClassTag::update(index, tags); |
| 835 tags = RawObject::SizeTag::update(size, tags); |
| 836 reinterpret_cast<RawObject*>(address)->tags_ = tags; |
| 812 } | 837 } |
| 813 | 838 |
| 814 | 839 |
| 815 RawObject* Object::Allocate(const Class& cls, | 840 RawObject* Object::Allocate(const Class& cls, |
| 816 intptr_t size, | 841 intptr_t size, |
| 817 Heap::Space space) { | 842 Heap::Space space) { |
| 818 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 843 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 819 Isolate* isolate = Isolate::Current(); | 844 Isolate* isolate = Isolate::Current(); |
| 820 Heap* heap = isolate->heap(); | 845 Heap* heap = isolate->heap(); |
| 821 | 846 |
| 822 uword address = heap->Allocate(size, space); | 847 uword address = heap->Allocate(size, space); |
| 823 if (address == 0) { | 848 if (address == 0) { |
| 824 // Use the preallocated out of memory exception to avoid calling | 849 // Use the preallocated out of memory exception to avoid calling |
| 825 // into dart code or allocating any code. | 850 // into dart code or allocating any code. |
| 826 const Instance& exception = | 851 const Instance& exception = |
| 827 Instance::Handle(isolate->object_store()->out_of_memory()); | 852 Instance::Handle(isolate->object_store()->out_of_memory()); |
| 828 Exceptions::Throw(exception); | 853 Exceptions::Throw(exception); |
| 829 UNREACHABLE(); | 854 UNREACHABLE(); |
| 830 } | 855 } |
| 831 NoGCScope no_gc; | 856 NoGCScope no_gc; |
| 832 InitializeObject(address, size); | 857 InitializeObject(address, cls.index(), size); |
| 833 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); | 858 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); |
| 834 raw_obj->ptr()->class_ = cls.raw(); | 859 raw_obj->ptr()->class_ = cls.raw(); |
| 835 uword tags = 0; | 860 ASSERT(cls.index() == RawObject::ClassTag::decode(raw_obj->ptr()->tags_)); |
| 836 tags = RawObject::SizeTag::update(size, tags); | |
| 837 raw_obj->ptr()->tags_ = tags; | |
| 838 return raw_obj; | 861 return raw_obj; |
| 839 } | 862 } |
| 840 | 863 |
| 841 | 864 |
| 842 RawString* Class::Name() const { | 865 RawString* Class::Name() const { |
| 843 if (raw_ptr()->name_ != String::null()) { | 866 if (raw_ptr()->name_ != String::null()) { |
| 844 return raw_ptr()->name_; | 867 return raw_ptr()->name_; |
| 845 } | 868 } |
| 846 ASSERT(class_class() != Class::null()); // class_class_ should be set up. | 869 ASSERT(class_class() != Class::null()); // class_class_ should be set up. |
| 847 intptr_t index = GetSingletonClassIndex(raw()); | 870 intptr_t index = GetSingletonClassIndex(raw()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 | 904 |
| 882 template <class FakeObject> | 905 template <class FakeObject> |
| 883 RawClass* Class::New() { | 906 RawClass* Class::New() { |
| 884 Class& class_class = Class::Handle(Object::class_class()); | 907 Class& class_class = Class::Handle(Object::class_class()); |
| 885 Class& result = Class::Handle(); | 908 Class& result = Class::Handle(); |
| 886 { | 909 { |
| 887 RawObject* raw = Object::Allocate(class_class, | 910 RawObject* raw = Object::Allocate(class_class, |
| 888 Class::InstanceSize(), | 911 Class::InstanceSize(), |
| 889 Heap::kOld); | 912 Heap::kOld); |
| 890 NoGCScope no_gc; | 913 NoGCScope no_gc; |
| 891 if (class_class.IsNull()) { | 914 result ^= raw; |
| 892 // Allocating class_class, avoid using uninitialized class vtable. | |
| 893 result.raw_ = raw; | |
| 894 } else { | |
| 895 result ^= raw; | |
| 896 } | |
| 897 } | 915 } |
| 898 FakeObject fake; | 916 FakeObject fake; |
| 899 result.set_handle_vtable(fake.vtable()); | 917 result.set_handle_vtable(fake.vtable()); |
| 900 result.set_instance_size(FakeObject::InstanceSize()); | 918 result.set_instance_size(FakeObject::InstanceSize()); |
| 901 result.set_next_field_offset(FakeObject::InstanceSize()); | 919 result.set_next_field_offset(FakeObject::InstanceSize()); |
| 902 result.set_instance_kind(FakeObject::kInstanceKind); | 920 result.set_instance_kind(FakeObject::kInstanceKind); |
| 921 result.set_index((FakeObject::kInstanceKind != kInstance) ? |
| 922 FakeObject::kInstanceKind : kIllegalObjectKind); |
| 903 result.raw_ptr()->is_const_ = false; | 923 result.raw_ptr()->is_const_ = false; |
| 904 result.raw_ptr()->is_interface_ = false; | 924 result.raw_ptr()->is_interface_ = false; |
| 905 // VM backed classes are almost ready: run checks and resolve class | 925 // VM backed classes are almost ready: run checks and resolve class |
| 906 // references, but do not recompute size. | 926 // references, but do not recompute size. |
| 907 result.raw_ptr()->class_state_ = RawClass::kPreFinalized; | 927 result.raw_ptr()->class_state_ = RawClass::kPreFinalized; |
| 908 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 928 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; |
| 909 result.raw_ptr()->num_native_fields_ = 0; | 929 result.raw_ptr()->num_native_fields_ = 0; |
| 910 result.raw_ptr()->token_index_ = Scanner::kDummyTokenIndex; | 930 result.raw_ptr()->token_index_ = Scanner::kDummyTokenIndex; |
| 911 result.InitEmptyFields(); | 931 result.InitEmptyFields(); |
| 932 Isolate::Current()->class_table()->Register(result); |
| 912 return result.raw(); | 933 return result.raw(); |
| 913 } | 934 } |
| 914 | 935 |
| 915 | 936 |
| 916 // Initialize class fields of type Array with empty array. | 937 // Initialize class fields of type Array with empty array. |
| 917 void Class::InitEmptyFields() { | 938 void Class::InitEmptyFields() { |
| 918 const Array& empty_array = Array::Handle(Array::Empty()); | 939 const Array& empty_array = Array::Handle(Array::Empty()); |
| 919 if (empty_array.IsNull()) { | 940 if (empty_array.IsNull()) { |
| 920 // The empty array has not been initialized yet. | 941 // The empty array has not been initialized yet. |
| 921 return; | 942 return; |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 // Only static const fields may contain the Object::sentinel value. | 1215 // Only static const fields may contain the Object::sentinel value. |
| 1195 ASSERT(!(field.is_static() && field.is_final()) || | 1216 ASSERT(!(field.is_static() && field.is_final()) || |
| 1196 (field.value() == Object::sentinel())); | 1217 (field.value() == Object::sentinel())); |
| 1197 } | 1218 } |
| 1198 // The value of static fields is already initialized to null. | 1219 // The value of static fields is already initialized to null. |
| 1199 StorePointer(&raw_ptr()->fields_, value.raw()); | 1220 StorePointer(&raw_ptr()->fields_, value.raw()); |
| 1200 } | 1221 } |
| 1201 | 1222 |
| 1202 | 1223 |
| 1203 template <class FakeInstance> | 1224 template <class FakeInstance> |
| 1204 RawClass* Class::New(const String& name, | 1225 RawClass* Class::New(intptr_t index) { |
| 1205 const Script& script, | |
| 1206 intptr_t token_index) { | |
| 1207 ASSERT(token_index >= 0); | |
| 1208 Class& class_class = Class::Handle(Object::class_class()); | 1226 Class& class_class = Class::Handle(Object::class_class()); |
| 1209 Class& result = Class::Handle(); | 1227 Class& result = Class::Handle(); |
| 1210 { | 1228 { |
| 1211 RawObject* raw = Object::Allocate(class_class, | 1229 RawObject* raw = Object::Allocate(class_class, |
| 1212 Class::InstanceSize(), | 1230 Class::InstanceSize(), |
| 1213 Heap::kOld); | 1231 Heap::kOld); |
| 1214 NoGCScope no_gc; | 1232 NoGCScope no_gc; |
| 1215 result ^= raw; | 1233 result ^= raw; |
| 1216 } | 1234 } |
| 1217 FakeInstance fake; | 1235 FakeInstance fake; |
| 1218 ASSERT(fake.IsInstance()); | 1236 ASSERT(fake.IsInstance()); |
| 1219 result.set_handle_vtable(fake.vtable()); | 1237 result.set_handle_vtable(fake.vtable()); |
| 1220 result.set_instance_size(FakeInstance::InstanceSize()); | 1238 result.set_instance_size(FakeInstance::InstanceSize()); |
| 1221 result.set_next_field_offset(FakeInstance::InstanceSize()); | 1239 result.set_next_field_offset(FakeInstance::InstanceSize()); |
| 1222 result.set_instance_kind(FakeInstance::kInstanceKind); | 1240 result.set_instance_kind(FakeInstance::kInstanceKind); |
| 1223 result.set_name(name); | 1241 result.set_index(index); |
| 1224 result.set_script(script); | |
| 1225 result.set_token_index(token_index); | |
| 1226 result.raw_ptr()->is_const_ = false; | 1242 result.raw_ptr()->is_const_ = false; |
| 1227 result.raw_ptr()->is_interface_ = false; | 1243 result.raw_ptr()->is_interface_ = false; |
| 1228 result.raw_ptr()->class_state_ = RawClass::kAllocated; | 1244 result.raw_ptr()->class_state_ = RawClass::kAllocated; |
| 1229 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 1245 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; |
| 1230 result.raw_ptr()->num_native_fields_ = 0; | 1246 result.raw_ptr()->num_native_fields_ = 0; |
| 1231 result.InitEmptyFields(); | 1247 result.InitEmptyFields(); |
| 1248 Isolate::Current()->class_table()->Register(result); |
| 1249 return result.raw(); |
| 1250 } |
| 1251 |
| 1252 |
| 1253 template <class FakeInstance> |
| 1254 RawClass* Class::New(const String& name, |
| 1255 const Script& script, |
| 1256 intptr_t token_index) { |
| 1257 Class& result = Class::Handle(New<FakeInstance>(kIllegalObjectKind)); |
| 1258 result.set_name(name); |
| 1259 result.set_script(script); |
| 1260 result.set_token_index(token_index); |
| 1232 return result.raw(); | 1261 return result.raw(); |
| 1233 } | 1262 } |
| 1234 | 1263 |
| 1235 | 1264 |
| 1236 RawClass* Class::New(const String& name, | 1265 RawClass* Class::New(const String& name, |
| 1237 const Script& script, | 1266 const Script& script, |
| 1238 intptr_t token_index) { | 1267 intptr_t token_index) { |
| 1239 Class& result = Class::Handle(New<Instance>(name, script, token_index)); | 1268 Class& result = Class::Handle(New<Instance>(name, script, token_index)); |
| 1240 return result.raw(); | 1269 return result.raw(); |
| 1241 } | 1270 } |
| (...skipping 7084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8326 NoGCScope no_gc; | 8355 NoGCScope no_gc; |
| 8327 result ^= raw; | 8356 result ^= raw; |
| 8328 result.SetLength(len); | 8357 result.SetLength(len); |
| 8329 } | 8358 } |
| 8330 return result.raw(); | 8359 return result.raw(); |
| 8331 } | 8360 } |
| 8332 | 8361 |
| 8333 | 8362 |
| 8334 void Array::MakeImmutable() const { | 8363 void Array::MakeImmutable() const { |
| 8335 Isolate* isolate = Isolate::Current(); | 8364 Isolate* isolate = Isolate::Current(); |
| 8336 raw()->ptr()->class_ = isolate->object_store()->immutable_array_class(); | 8365 const Class& cls = Class::Handle( |
| 8366 isolate, isolate->object_store()->immutable_array_class()); |
| 8367 { |
| 8368 NoGCScope no_gc; |
| 8369 raw_ptr()->class_ = cls.raw(); |
| 8370 uword tags = raw_ptr()->tags_; |
| 8371 tags = RawObject::ClassTag::update(cls.index(), tags); |
| 8372 raw_ptr()->tags_ = tags; |
| 8373 } |
| 8337 } | 8374 } |
| 8338 | 8375 |
| 8339 | 8376 |
| 8340 const char* Array::ToCString() const { | 8377 const char* Array::ToCString() const { |
| 8341 return "Array"; | 8378 return "Array"; |
| 8342 } | 8379 } |
| 8343 | 8380 |
| 8344 | 8381 |
| 8345 RawArray* Array::Grow(const Array& source, int new_length, Heap::Space space) { | 8382 RawArray* Array::Grow(const Array& source, int new_length, Heap::Space space) { |
| 8346 intptr_t len = source.IsNull() ? 0 : source.Length(); | 8383 intptr_t len = source.IsNull() ? 0 : source.Length(); |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8969 const String& str = String::Handle(pattern()); | 9006 const String& str = String::Handle(pattern()); |
| 8970 const char* format = "JSRegExp: pattern=%s flags=%s"; | 9007 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 8971 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 9008 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 8972 char* chars = reinterpret_cast<char*>( | 9009 char* chars = reinterpret_cast<char*>( |
| 8973 Isolate::Current()->current_zone()->Allocate(len + 1)); | 9010 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 8974 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 9011 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 8975 return chars; | 9012 return chars; |
| 8976 } | 9013 } |
| 8977 | 9014 |
| 8978 } // namespace dart | 9015 } // namespace dart |
| OLD | NEW |