| 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 Null class. | 312 // Allocate and initialize the sentinel values of Null class. |
| 295 { | 313 { |
| 296 cls = null_class_; | 314 cls = null_class_; |
| 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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 // Initialize the base interfaces used by the core VM classes. | 595 // Initialize the base interfaces used by the core VM classes. |
| 578 const Script& script = Script::Handle(Bootstrap::LoadScript()); | 596 const Script& script = Script::Handle(Bootstrap::LoadScript()); |
| 579 | 597 |
| 580 // Allocate and initialize the Object class and type. | 598 // Allocate and initialize the Object class and type. |
| 581 // The Object and ExternalByteArray classes are the only pre-allocated | 599 // The Object and ExternalByteArray classes are the only pre-allocated |
| 582 // non-interface classes in the core library. | 600 // non-interface classes in the core library. |
| 583 cls = Class::New<Instance>(); | 601 cls = Class::New<Instance>(); |
| 584 object_store->set_object_class(cls); | 602 object_store->set_object_class(cls); |
| 585 cls.set_name(String::Handle(String::NewSymbol("Object"))); | 603 cls.set_name(String::Handle(String::NewSymbol("Object"))); |
| 586 cls.set_script(script); | 604 cls.set_script(script); |
| 605 cls.set_class_state(RawClass::kPreFinalized); |
| 587 core_lib.AddClass(cls); | 606 core_lib.AddClass(cls); |
| 588 pending_classes.Add(cls, Heap::kOld); | 607 pending_classes.Add(cls, Heap::kOld); |
| 589 type = Type::NewNonParameterizedType(cls); | 608 type = Type::NewNonParameterizedType(cls); |
| 590 object_store->set_object_type(type); | 609 object_store->set_object_type(type); |
| 591 | 610 |
| 592 cls = Class::New<InternalByteArray>(); | 611 cls = Class::New<InternalByteArray>(); |
| 593 object_store->set_internal_byte_array_class(cls); | 612 object_store->set_internal_byte_array_class(cls); |
| 594 String& public_class_name = String::Handle(); | 613 String& public_class_name = String::Handle(); |
| 595 public_class_name = String::New("_InternalByteArray"); | 614 public_class_name = String::New("_InternalByteArray"); |
| 596 cls.set_name(String::Handle(core_lib.PrivateName(public_class_name))); | 615 cls.set_name(String::Handle(core_lib.PrivateName(public_class_name))); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 | 761 |
| 743 cls = Class::New<GrowableObjectArray>(); | 762 cls = Class::New<GrowableObjectArray>(); |
| 744 object_store->set_growable_object_array_class(cls); | 763 object_store->set_growable_object_array_class(cls); |
| 745 | 764 |
| 746 cls = Class::New<InternalByteArray>(); | 765 cls = Class::New<InternalByteArray>(); |
| 747 object_store->set_internal_byte_array_class(cls); | 766 object_store->set_internal_byte_array_class(cls); |
| 748 | 767 |
| 749 cls = Class::New<ExternalByteArray>(); | 768 cls = Class::New<ExternalByteArray>(); |
| 750 object_store->set_external_byte_array_class(cls); | 769 object_store->set_external_byte_array_class(cls); |
| 751 | 770 |
| 752 cls = Class::New<Instance>(); | |
| 753 object_store->set_object_class(cls); | |
| 754 | |
| 755 cls = Class::New<Smi>(); | 771 cls = Class::New<Smi>(); |
| 756 object_store->set_smi_class(cls); | 772 object_store->set_smi_class(cls); |
| 757 | 773 |
| 758 cls = Class::New<Mint>(); | 774 cls = Class::New<Mint>(); |
| 759 object_store->set_mint_class(cls); | 775 object_store->set_mint_class(cls); |
| 760 | 776 |
| 761 cls = Class::New<Double>(); | 777 cls = Class::New<Double>(); |
| 762 object_store->set_double_class(cls); | 778 object_store->set_double_class(cls); |
| 763 | 779 |
| 764 cls = Class::New<Bigint>(); | 780 cls = Class::New<Bigint>(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 bool_value = Bool::New(false); | 814 bool_value = Bool::New(false); |
| 799 object_store->set_false_value(bool_value); | 815 object_store->set_false_value(bool_value); |
| 800 } | 816 } |
| 801 | 817 |
| 802 | 818 |
| 803 void Object::Print() const { | 819 void Object::Print() const { |
| 804 OS::Print("%s\n", ToCString()); | 820 OS::Print("%s\n", ToCString()); |
| 805 } | 821 } |
| 806 | 822 |
| 807 | 823 |
| 808 void Object::InitializeObject(uword address, intptr_t size) { | 824 void Object::InitializeObject(uword address, intptr_t index, intptr_t size) { |
| 809 // TODO(iposva): Get a proper halt instruction from the assembler which | 825 // TODO(iposva): Get a proper halt instruction from the assembler which |
| 810 // would be needed here for code objects. | 826 // would be needed here for code objects. |
| 811 uword initial_value = reinterpret_cast<uword>(null_); | 827 uword initial_value = reinterpret_cast<uword>(null_); |
| 812 uword cur = address; | 828 uword cur = address; |
| 813 uword end = address + size; | 829 uword end = address + size; |
| 814 while (cur < end) { | 830 while (cur < end) { |
| 815 *reinterpret_cast<uword*>(cur) = initial_value; | 831 *reinterpret_cast<uword*>(cur) = initial_value; |
| 816 cur += kWordSize; | 832 cur += kWordSize; |
| 817 } | 833 } |
| 834 uword tags = 0; |
| 835 ASSERT(index != kIllegalObjectKind); |
| 836 tags = RawObject::ClassTag::update(index, tags); |
| 837 tags = RawObject::SizeTag::update(size, tags); |
| 838 reinterpret_cast<RawObject*>(address)->tags_ = tags; |
| 818 } | 839 } |
| 819 | 840 |
| 820 | 841 |
| 821 RawObject* Object::Allocate(const Class& cls, | 842 RawObject* Object::Allocate(const Class& cls, |
| 822 intptr_t size, | 843 intptr_t size, |
| 823 Heap::Space space) { | 844 Heap::Space space) { |
| 824 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 845 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 825 Isolate* isolate = Isolate::Current(); | 846 Isolate* isolate = Isolate::Current(); |
| 826 Heap* heap = isolate->heap(); | 847 Heap* heap = isolate->heap(); |
| 827 | 848 |
| 828 uword address = heap->Allocate(size, space); | 849 uword address = heap->Allocate(size, space); |
| 829 if (address == 0) { | 850 if (address == 0) { |
| 830 // Use the preallocated out of memory exception to avoid calling | 851 // Use the preallocated out of memory exception to avoid calling |
| 831 // into dart code or allocating any code. | 852 // into dart code or allocating any code. |
| 832 const Instance& exception = | 853 const Instance& exception = |
| 833 Instance::Handle(isolate->object_store()->out_of_memory()); | 854 Instance::Handle(isolate->object_store()->out_of_memory()); |
| 834 Exceptions::Throw(exception); | 855 Exceptions::Throw(exception); |
| 835 UNREACHABLE(); | 856 UNREACHABLE(); |
| 836 } | 857 } |
| 837 NoGCScope no_gc; | 858 NoGCScope no_gc; |
| 838 InitializeObject(address, size); | 859 InitializeObject(address, cls.index(), size); |
| 839 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); | 860 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); |
| 840 raw_obj->ptr()->class_ = cls.raw(); | 861 raw_obj->ptr()->class_ = cls.raw(); |
| 841 uword tags = 0; | 862 ASSERT(cls.index() == RawObject::ClassTag::decode(raw_obj->ptr()->tags_)); |
| 842 tags = RawObject::SizeTag::update(size, tags); | |
| 843 raw_obj->ptr()->tags_ = tags; | |
| 844 return raw_obj; | 863 return raw_obj; |
| 845 } | 864 } |
| 846 | 865 |
| 847 | 866 |
| 848 RawString* Class::Name() const { | 867 RawString* Class::Name() const { |
| 849 if (raw_ptr()->name_ != String::null()) { | 868 if (raw_ptr()->name_ != String::null()) { |
| 850 return raw_ptr()->name_; | 869 return raw_ptr()->name_; |
| 851 } | 870 } |
| 852 ASSERT(class_class() != Class::null()); // class_class_ should be set up. | 871 ASSERT(class_class() != Class::null()); // class_class_ should be set up. |
| 853 intptr_t index = GetSingletonClassIndex(raw()); | 872 intptr_t index = GetSingletonClassIndex(raw()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 | 906 |
| 888 template <class FakeObject> | 907 template <class FakeObject> |
| 889 RawClass* Class::New() { | 908 RawClass* Class::New() { |
| 890 Class& class_class = Class::Handle(Object::class_class()); | 909 Class& class_class = Class::Handle(Object::class_class()); |
| 891 Class& result = Class::Handle(); | 910 Class& result = Class::Handle(); |
| 892 { | 911 { |
| 893 RawObject* raw = Object::Allocate(class_class, | 912 RawObject* raw = Object::Allocate(class_class, |
| 894 Class::InstanceSize(), | 913 Class::InstanceSize(), |
| 895 Heap::kOld); | 914 Heap::kOld); |
| 896 NoGCScope no_gc; | 915 NoGCScope no_gc; |
| 897 if (class_class.IsNull()) { | 916 result ^= raw; |
| 898 // Allocating class_class, avoid using uninitialized class vtable. | |
| 899 result.raw_ = raw; | |
| 900 } else { | |
| 901 result ^= raw; | |
| 902 } | |
| 903 } | 917 } |
| 904 FakeObject fake; | 918 FakeObject fake; |
| 905 result.set_handle_vtable(fake.vtable()); | 919 result.set_handle_vtable(fake.vtable()); |
| 906 result.set_instance_size(FakeObject::InstanceSize()); | 920 result.set_instance_size(FakeObject::InstanceSize()); |
| 907 result.set_next_field_offset(FakeObject::InstanceSize()); | 921 result.set_next_field_offset(FakeObject::InstanceSize()); |
| 908 result.set_instance_kind(FakeObject::kInstanceKind); | 922 result.set_instance_kind(FakeObject::kInstanceKind); |
| 923 result.set_index((FakeObject::kInstanceKind != kInstance) ? |
| 924 FakeObject::kInstanceKind : kIllegalObjectKind); |
| 909 result.raw_ptr()->is_const_ = false; | 925 result.raw_ptr()->is_const_ = false; |
| 910 result.raw_ptr()->is_interface_ = false; | 926 result.raw_ptr()->is_interface_ = false; |
| 911 // VM backed classes are almost ready: run checks and resolve class | 927 // VM backed classes are almost ready: run checks and resolve class |
| 912 // references, but do not recompute size. | 928 // references, but do not recompute size. |
| 913 result.raw_ptr()->class_state_ = RawClass::kPreFinalized; | 929 result.raw_ptr()->class_state_ = RawClass::kPreFinalized; |
| 914 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 930 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; |
| 915 result.raw_ptr()->num_native_fields_ = 0; | 931 result.raw_ptr()->num_native_fields_ = 0; |
| 916 result.raw_ptr()->token_index_ = Scanner::kDummyTokenIndex; | 932 result.raw_ptr()->token_index_ = Scanner::kDummyTokenIndex; |
| 917 result.InitEmptyFields(); | 933 result.InitEmptyFields(); |
| 934 Isolate::Current()->class_table()->Register(result); |
| 918 return result.raw(); | 935 return result.raw(); |
| 919 } | 936 } |
| 920 | 937 |
| 921 | 938 |
| 922 // Initialize class fields of type Array with empty array. | 939 // Initialize class fields of type Array with empty array. |
| 923 void Class::InitEmptyFields() { | 940 void Class::InitEmptyFields() { |
| 924 const Array& empty_array = Array::Handle(Array::Empty()); | 941 const Array& empty_array = Array::Handle(Array::Empty()); |
| 925 if (empty_array.IsNull()) { | 942 if (empty_array.IsNull()) { |
| 926 // The empty array has not been initialized yet. | 943 // The empty array has not been initialized yet. |
| 927 return; | 944 return; |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 // Only static const fields may contain the Object::sentinel value. | 1223 // Only static const fields may contain the Object::sentinel value. |
| 1207 ASSERT(!(field.is_static() && field.is_final()) || | 1224 ASSERT(!(field.is_static() && field.is_final()) || |
| 1208 (field.value() == Object::sentinel())); | 1225 (field.value() == Object::sentinel())); |
| 1209 } | 1226 } |
| 1210 // The value of static fields is already initialized to null. | 1227 // The value of static fields is already initialized to null. |
| 1211 StorePointer(&raw_ptr()->fields_, value.raw()); | 1228 StorePointer(&raw_ptr()->fields_, value.raw()); |
| 1212 } | 1229 } |
| 1213 | 1230 |
| 1214 | 1231 |
| 1215 template <class FakeInstance> | 1232 template <class FakeInstance> |
| 1216 RawClass* Class::New(const String& name, | 1233 RawClass* Class::New(intptr_t index) { |
| 1217 const Script& script, | |
| 1218 intptr_t token_index) { | |
| 1219 ASSERT(token_index >= 0); | |
| 1220 Class& class_class = Class::Handle(Object::class_class()); | 1234 Class& class_class = Class::Handle(Object::class_class()); |
| 1221 Class& result = Class::Handle(); | 1235 Class& result = Class::Handle(); |
| 1222 { | 1236 { |
| 1223 RawObject* raw = Object::Allocate(class_class, | 1237 RawObject* raw = Object::Allocate(class_class, |
| 1224 Class::InstanceSize(), | 1238 Class::InstanceSize(), |
| 1225 Heap::kOld); | 1239 Heap::kOld); |
| 1226 NoGCScope no_gc; | 1240 NoGCScope no_gc; |
| 1227 result ^= raw; | 1241 result ^= raw; |
| 1228 } | 1242 } |
| 1229 FakeInstance fake; | 1243 FakeInstance fake; |
| 1230 ASSERT(fake.IsInstance()); | 1244 ASSERT(fake.IsInstance()); |
| 1231 result.set_handle_vtable(fake.vtable()); | 1245 result.set_handle_vtable(fake.vtable()); |
| 1232 result.set_instance_size(FakeInstance::InstanceSize()); | 1246 result.set_instance_size(FakeInstance::InstanceSize()); |
| 1233 result.set_next_field_offset(FakeInstance::InstanceSize()); | 1247 result.set_next_field_offset(FakeInstance::InstanceSize()); |
| 1234 result.set_instance_kind(FakeInstance::kInstanceKind); | 1248 result.set_instance_kind(FakeInstance::kInstanceKind); |
| 1235 result.set_name(name); | 1249 result.set_index(index); |
| 1236 result.set_script(script); | |
| 1237 result.set_token_index(token_index); | |
| 1238 result.raw_ptr()->is_const_ = false; | 1250 result.raw_ptr()->is_const_ = false; |
| 1239 result.raw_ptr()->is_interface_ = false; | 1251 result.raw_ptr()->is_interface_ = false; |
| 1240 result.raw_ptr()->class_state_ = RawClass::kAllocated; | 1252 result.raw_ptr()->class_state_ = RawClass::kAllocated; |
| 1241 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 1253 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; |
| 1242 result.raw_ptr()->num_native_fields_ = 0; | 1254 result.raw_ptr()->num_native_fields_ = 0; |
| 1243 result.InitEmptyFields(); | 1255 result.InitEmptyFields(); |
| 1256 Isolate::Current()->class_table()->Register(result); |
| 1257 return result.raw(); |
| 1258 } |
| 1259 |
| 1260 |
| 1261 template <class FakeInstance> |
| 1262 RawClass* Class::New(const String& name, |
| 1263 const Script& script, |
| 1264 intptr_t token_index) { |
| 1265 Class& result = Class::Handle(New<FakeInstance>(kIllegalObjectKind)); |
| 1266 result.set_name(name); |
| 1267 result.set_script(script); |
| 1268 result.set_token_index(token_index); |
| 1244 return result.raw(); | 1269 return result.raw(); |
| 1245 } | 1270 } |
| 1246 | 1271 |
| 1247 | 1272 |
| 1248 RawClass* Class::New(const String& name, | 1273 RawClass* Class::New(const String& name, |
| 1249 const Script& script, | 1274 const Script& script, |
| 1250 intptr_t token_index) { | 1275 intptr_t token_index) { |
| 1251 Class& result = Class::Handle(New<Instance>(name, script, token_index)); | 1276 Class& result = Class::Handle(New<Instance>(name, script, token_index)); |
| 1252 return result.raw(); | 1277 return result.raw(); |
| 1253 } | 1278 } |
| (...skipping 7316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8570 NoGCScope no_gc; | 8595 NoGCScope no_gc; |
| 8571 result ^= raw; | 8596 result ^= raw; |
| 8572 result.SetLength(len); | 8597 result.SetLength(len); |
| 8573 } | 8598 } |
| 8574 return result.raw(); | 8599 return result.raw(); |
| 8575 } | 8600 } |
| 8576 | 8601 |
| 8577 | 8602 |
| 8578 void Array::MakeImmutable() const { | 8603 void Array::MakeImmutable() const { |
| 8579 Isolate* isolate = Isolate::Current(); | 8604 Isolate* isolate = Isolate::Current(); |
| 8580 raw()->ptr()->class_ = isolate->object_store()->immutable_array_class(); | 8605 const Class& cls = Class::Handle( |
| 8606 isolate, isolate->object_store()->immutable_array_class()); |
| 8607 { |
| 8608 NoGCScope no_gc; |
| 8609 raw_ptr()->class_ = cls.raw(); |
| 8610 uword tags = raw_ptr()->tags_; |
| 8611 tags = RawObject::ClassTag::update(cls.index(), tags); |
| 8612 raw_ptr()->tags_ = tags; |
| 8613 } |
| 8581 } | 8614 } |
| 8582 | 8615 |
| 8583 | 8616 |
| 8584 const char* Array::ToCString() const { | 8617 const char* Array::ToCString() const { |
| 8585 return "Array"; | 8618 return "Array"; |
| 8586 } | 8619 } |
| 8587 | 8620 |
| 8588 | 8621 |
| 8589 RawArray* Array::Grow(const Array& source, int new_length, Heap::Space space) { | 8622 RawArray* Array::Grow(const Array& source, int new_length, Heap::Space space) { |
| 8590 intptr_t len = source.IsNull() ? 0 : source.Length(); | 8623 intptr_t len = source.IsNull() ? 0 : source.Length(); |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9239 const String& str = String::Handle(pattern()); | 9272 const String& str = String::Handle(pattern()); |
| 9240 const char* format = "JSRegExp: pattern=%s flags=%s"; | 9273 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 9241 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 9274 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 9242 char* chars = reinterpret_cast<char*>( | 9275 char* chars = reinterpret_cast<char*>( |
| 9243 Isolate::Current()->current_zone()->Allocate(len + 1)); | 9276 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 9244 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 9277 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 9245 return chars; | 9278 return chars; |
| 9246 } | 9279 } |
| 9247 | 9280 |
| 9248 } // namespace dart | 9281 } // namespace dart |
| OLD | NEW |