| 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 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 Smi::handle_vtable_ = fake_smi.vtable(); | 249 Smi::handle_vtable_ = fake_smi.vtable(); |
| 250 } | 250 } |
| 251 | 251 |
| 252 Heap* heap = Isolate::Current()->heap(); | 252 Heap* heap = Isolate::Current()->heap(); |
| 253 // Allocate and initialize the null instance, except its class_ field. | 253 // Allocate and initialize the null instance, except its class_ field. |
| 254 // 'null_' must be the first object allocated as it is used in allocation to | 254 // 'null_' must be the first object allocated as it is used in allocation to |
| 255 // clear the object. | 255 // clear the object. |
| 256 { | 256 { |
| 257 uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld); | 257 uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld); |
| 258 null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag); | 258 null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag); |
| 259 InitializeObject(address, | 259 // The call below is using 'null_' to initialize itself. |
| 260 kNullClassIndex, | 260 InitializeObject(address, kNullClassId, Instance::InstanceSize()); |
| 261 Instance::InstanceSize()); // Using 'null_'. | |
| 262 } | 261 } |
| 263 | 262 |
| 264 // Initialize object_store empty array to null_ in order to be able to check | 263 // Initialize object_store empty array to null_ in order to be able to check |
| 265 // if the empty array was allocated (RAW_NULL is not available). | 264 // if the empty array was allocated (RAW_NULL is not available). |
| 266 Isolate::Current()->object_store()->set_empty_array(Array::Handle()); | 265 Isolate::Current()->object_store()->set_empty_array(Array::Handle()); |
| 267 | 266 |
| 268 Class& cls = Class::Handle(); | 267 Class& cls = Class::Handle(); |
| 269 | 268 |
| 270 // Allocate and initialize the class class. | 269 // Allocate and initialize the class class. |
| 271 { | 270 { |
| 272 intptr_t size = Class::InstanceSize(); | 271 intptr_t size = Class::InstanceSize(); |
| 273 uword address = heap->Allocate(size, Heap::kOld); | 272 uword address = heap->Allocate(size, Heap::kOld); |
| 274 class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag); | 273 class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag); |
| 275 InitializeObject(address, Class::kInstanceKind, size); | 274 InitializeObject(address, Class::kInstanceKind, size); |
| 276 // Make the class_ field point to itself. | 275 // Make the class_ field point to itself. |
| 277 class_class_->ptr()->class_ = class_class_; | 276 class_class_->ptr()->class_ = class_class_; |
| 278 | 277 |
| 279 Class fake; | 278 Class fake; |
| 280 // Initialization from Class::New<Class>. | 279 // Initialization from Class::New<Class>. |
| 281 cls = class_class_; | 280 cls = class_class_; |
| 282 cls.set_handle_vtable(fake.vtable()); | 281 cls.set_handle_vtable(fake.vtable()); |
| 283 cls.set_instance_size(Class::InstanceSize()); | 282 cls.set_instance_size(Class::InstanceSize()); |
| 284 cls.set_next_field_offset(Class::InstanceSize()); | 283 cls.set_next_field_offset(Class::InstanceSize()); |
| 285 cls.set_instance_kind(Class::kInstanceKind); | 284 cls.set_instance_kind(Class::kInstanceKind); |
| 286 cls.set_index(Class::kInstanceKind); | 285 cls.set_id(Class::kInstanceKind); |
| 287 cls.raw_ptr()->is_const_ = false; | 286 cls.raw_ptr()->is_const_ = false; |
| 288 cls.raw_ptr()->is_interface_ = false; | 287 cls.raw_ptr()->is_interface_ = false; |
| 289 cls.set_is_finalized(); | 288 cls.set_is_finalized(); |
| 290 cls.raw_ptr()->type_arguments_instance_field_offset_ = | 289 cls.raw_ptr()->type_arguments_instance_field_offset_ = |
| 291 Class::kNoTypeArguments; | 290 Class::kNoTypeArguments; |
| 292 cls.raw_ptr()->num_native_fields_ = 0; | 291 cls.raw_ptr()->num_native_fields_ = 0; |
| 293 cls.InitEmptyFields(); | 292 cls.InitEmptyFields(); |
| 294 Isolate::Current()->class_table()->Register(cls); | 293 Isolate::Current()->class_table()->Register(cls); |
| 295 } | 294 } |
| 296 | 295 |
| 297 // Allocate and initialize the null class. | 296 // Allocate and initialize the null class. |
| 298 cls = Class::New<Instance>(kNullClassIndex); | 297 cls = Class::New<Instance>(kNullClassId); |
| 299 cls.set_is_finalized(); | 298 cls.set_is_finalized(); |
| 300 null_class_ = cls.raw(); | 299 null_class_ = cls.raw(); |
| 301 | 300 |
| 302 // Complete initialization of null_ instance, i.e. initialize its class_ | 301 // Complete initialization of null_ instance, i.e. initialize its class_ |
| 303 // field. | 302 // field. |
| 304 null_->ptr()->class_ = null_class_; | 303 null_->ptr()->class_ = null_class_; |
| 305 | 304 |
| 306 // Allocate and initialize the sentinel values of Null class. | 305 // Allocate and initialize the sentinel values of Null class. |
| 307 { | 306 { |
| 308 cls = null_class_; | 307 cls = null_class_; |
| 309 Instance& sentinel = Instance::Handle(); | 308 Instance& sentinel = Instance::Handle(); |
| 310 sentinel ^= Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); | 309 sentinel ^= Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); |
| 311 sentinel_ = sentinel.raw(); | 310 sentinel_ = sentinel.raw(); |
| 312 | 311 |
| 313 Instance& transition_sentinel = Instance::Handle(); | 312 Instance& transition_sentinel = Instance::Handle(); |
| 314 transition_sentinel ^= | 313 transition_sentinel ^= |
| 315 Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); | 314 Object::Allocate(cls, Instance::InstanceSize(), Heap::kOld); |
| 316 transition_sentinel_ = transition_sentinel.raw(); | 315 transition_sentinel_ = transition_sentinel.raw(); |
| 317 } | 316 } |
| 318 | 317 |
| 319 // The interface "Dynamic" is not a VM internal class. It is the type class of | 318 // The interface "Dynamic" is not a VM internal class. It is the type class of |
| 320 // the "unknown type". For efficiency, we allocate it in the VM isolate. | 319 // the "unknown type". For efficiency, we allocate it in the VM isolate. |
| 321 // Therefore, it cannot have a heap allocated name (the name is hard coded, | 320 // Therefore, it cannot have a heap allocated name (the name is hard coded, |
| 322 // see GetSingletonClassIndex) and its array fields cannot be set to the empty | 321 // see GetSingletonClassIndex) and its array fields cannot be set to the empty |
| 323 // array, but remain null. | 322 // array, but remain null. |
| 324 cls = Class::New<Instance>(kDynamicClassIndex); | 323 cls = Class::New<Instance>(kDynamicClassId); |
| 325 cls.set_is_finalized(); | 324 cls.set_is_finalized(); |
| 326 cls.set_is_interface(); | 325 cls.set_is_interface(); |
| 327 dynamic_class_ = cls.raw(); | 326 dynamic_class_ = cls.raw(); |
| 328 | 327 |
| 329 // Allocate the remaining VM internal classes. | 328 // Allocate the remaining VM internal classes. |
| 330 cls = Class::New<UnresolvedClass>(); | 329 cls = Class::New<UnresolvedClass>(); |
| 331 unresolved_class_class_ = cls.raw(); | 330 unresolved_class_class_ = cls.raw(); |
| 332 | 331 |
| 333 cls = Class::New<Instance>(kVoidClassIndex); | 332 cls = Class::New<Instance>(kVoidClassId); |
| 334 cls.set_is_finalized(); | 333 cls.set_is_finalized(); |
| 335 void_class_ = cls.raw(); | 334 void_class_ = cls.raw(); |
| 336 | 335 |
| 337 cls = Class::New<Type>(); | 336 cls = Class::New<Type>(); |
| 338 type_class_ = cls.raw(); | 337 type_class_ = cls.raw(); |
| 339 | 338 |
| 340 cls = Class::New<TypeParameter>(); | 339 cls = Class::New<TypeParameter>(); |
| 341 type_parameter_class_ = cls.raw(); | 340 type_parameter_class_ = cls.raw(); |
| 342 | 341 |
| 343 cls = Class::New<TypeArguments>(); | 342 cls = Class::New<TypeArguments>(); |
| (...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 // would be needed here for code objects. | 961 // would be needed here for code objects. |
| 963 uword initial_value = reinterpret_cast<uword>(null_); | 962 uword initial_value = reinterpret_cast<uword>(null_); |
| 964 uword cur = address; | 963 uword cur = address; |
| 965 uword end = address + size; | 964 uword end = address + size; |
| 966 while (cur < end) { | 965 while (cur < end) { |
| 967 *reinterpret_cast<uword*>(cur) = initial_value; | 966 *reinterpret_cast<uword*>(cur) = initial_value; |
| 968 cur += kWordSize; | 967 cur += kWordSize; |
| 969 } | 968 } |
| 970 uword tags = 0; | 969 uword tags = 0; |
| 971 ASSERT(index != kIllegalObjectKind); | 970 ASSERT(index != kIllegalObjectKind); |
| 972 tags = RawObject::ClassTag::update(index, tags); | 971 tags = RawObject::ClassIdTag::update(index, tags); |
| 973 tags = RawObject::SizeTag::update(size, tags); | 972 tags = RawObject::SizeTag::update(size, tags); |
| 974 reinterpret_cast<RawObject*>(address)->tags_ = tags; | 973 reinterpret_cast<RawObject*>(address)->tags_ = tags; |
| 975 } | 974 } |
| 976 | 975 |
| 977 | 976 |
| 978 RawObject* Object::Allocate(const Class& cls, | 977 RawObject* Object::Allocate(const Class& cls, |
| 979 intptr_t size, | 978 intptr_t size, |
| 980 Heap::Space space) { | 979 Heap::Space space) { |
| 981 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 980 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 982 Isolate* isolate = Isolate::Current(); | 981 Isolate* isolate = Isolate::Current(); |
| 983 Heap* heap = isolate->heap(); | 982 Heap* heap = isolate->heap(); |
| 984 | 983 |
| 985 uword address = heap->Allocate(size, space); | 984 uword address = heap->Allocate(size, space); |
| 986 if (address == 0) { | 985 if (address == 0) { |
| 987 // Use the preallocated out of memory exception to avoid calling | 986 // Use the preallocated out of memory exception to avoid calling |
| 988 // into dart code or allocating any code. | 987 // into dart code or allocating any code. |
| 989 const Instance& exception = | 988 const Instance& exception = |
| 990 Instance::Handle(isolate->object_store()->out_of_memory()); | 989 Instance::Handle(isolate->object_store()->out_of_memory()); |
| 991 Exceptions::Throw(exception); | 990 Exceptions::Throw(exception); |
| 992 UNREACHABLE(); | 991 UNREACHABLE(); |
| 993 } | 992 } |
| 994 NoGCScope no_gc; | 993 NoGCScope no_gc; |
| 995 InitializeObject(address, cls.index(), size); | 994 InitializeObject(address, cls.id(), size); |
| 996 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); | 995 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); |
| 997 raw_obj->ptr()->class_ = cls.raw(); | 996 raw_obj->ptr()->class_ = cls.raw(); |
| 998 ASSERT(cls.index() == RawObject::ClassTag::decode(raw_obj->ptr()->tags_)); | 997 ASSERT(cls.id() == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_)); |
| 999 return raw_obj; | 998 return raw_obj; |
| 1000 } | 999 } |
| 1001 | 1000 |
| 1002 | 1001 |
| 1003 RawString* Class::Name() const { | 1002 RawString* Class::Name() const { |
| 1004 if (raw_ptr()->name_ != String::null()) { | 1003 if (raw_ptr()->name_ != String::null()) { |
| 1005 return raw_ptr()->name_; | 1004 return raw_ptr()->name_; |
| 1006 } | 1005 } |
| 1007 ASSERT(class_class() != Class::null()); // class_class_ should be set up. | 1006 ASSERT(class_class() != Class::null()); // class_class_ should be set up. |
| 1008 intptr_t index = GetSingletonClassIndex(raw()); | 1007 intptr_t index = GetSingletonClassIndex(raw()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1056 Class::InstanceSize(), | 1055 Class::InstanceSize(), |
| 1057 Heap::kOld); | 1056 Heap::kOld); |
| 1058 NoGCScope no_gc; | 1057 NoGCScope no_gc; |
| 1059 result ^= raw; | 1058 result ^= raw; |
| 1060 } | 1059 } |
| 1061 FakeObject fake; | 1060 FakeObject fake; |
| 1062 result.set_handle_vtable(fake.vtable()); | 1061 result.set_handle_vtable(fake.vtable()); |
| 1063 result.set_instance_size(FakeObject::InstanceSize()); | 1062 result.set_instance_size(FakeObject::InstanceSize()); |
| 1064 result.set_next_field_offset(FakeObject::InstanceSize()); | 1063 result.set_next_field_offset(FakeObject::InstanceSize()); |
| 1065 result.set_instance_kind(FakeObject::kInstanceKind); | 1064 result.set_instance_kind(FakeObject::kInstanceKind); |
| 1066 result.set_index((FakeObject::kInstanceKind != kInstance) ? | 1065 result.set_id((FakeObject::kInstanceKind != kInstance) ? |
| 1067 FakeObject::kInstanceKind : kIllegalObjectKind); | 1066 FakeObject::kInstanceKind : kIllegalObjectKind); |
| 1068 result.raw_ptr()->is_const_ = false; | 1067 result.raw_ptr()->is_const_ = false; |
| 1069 result.raw_ptr()->is_interface_ = false; | 1068 result.raw_ptr()->is_interface_ = false; |
| 1070 // VM backed classes are almost ready: run checks and resolve class | 1069 // VM backed classes are almost ready: run checks and resolve class |
| 1071 // references, but do not recompute size. | 1070 // references, but do not recompute size. |
| 1072 result.raw_ptr()->class_state_ = RawClass::kPreFinalized; | 1071 result.raw_ptr()->class_state_ = RawClass::kPreFinalized; |
| 1073 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 1072 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; |
| 1074 result.raw_ptr()->num_native_fields_ = 0; | 1073 result.raw_ptr()->num_native_fields_ = 0; |
| 1075 result.raw_ptr()->token_index_ = Scanner::kDummyTokenIndex; | 1074 result.raw_ptr()->token_index_ = Scanner::kDummyTokenIndex; |
| 1076 result.InitEmptyFields(); | 1075 result.InitEmptyFields(); |
| 1077 Isolate::Current()->class_table()->Register(result); | 1076 Isolate::Current()->class_table()->Register(result); |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 Heap::kOld); | 1394 Heap::kOld); |
| 1396 NoGCScope no_gc; | 1395 NoGCScope no_gc; |
| 1397 result ^= raw; | 1396 result ^= raw; |
| 1398 } | 1397 } |
| 1399 FakeInstance fake; | 1398 FakeInstance fake; |
| 1400 ASSERT(fake.IsInstance()); | 1399 ASSERT(fake.IsInstance()); |
| 1401 result.set_handle_vtable(fake.vtable()); | 1400 result.set_handle_vtable(fake.vtable()); |
| 1402 result.set_instance_size(FakeInstance::InstanceSize()); | 1401 result.set_instance_size(FakeInstance::InstanceSize()); |
| 1403 result.set_next_field_offset(FakeInstance::InstanceSize()); | 1402 result.set_next_field_offset(FakeInstance::InstanceSize()); |
| 1404 result.set_instance_kind(FakeInstance::kInstanceKind); | 1403 result.set_instance_kind(FakeInstance::kInstanceKind); |
| 1405 result.set_index(index); | 1404 result.set_id(index); |
| 1406 result.raw_ptr()->is_const_ = false; | 1405 result.raw_ptr()->is_const_ = false; |
| 1407 result.raw_ptr()->is_interface_ = false; | 1406 result.raw_ptr()->is_interface_ = false; |
| 1408 result.raw_ptr()->class_state_ = RawClass::kAllocated; | 1407 result.raw_ptr()->class_state_ = RawClass::kAllocated; |
| 1409 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 1408 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; |
| 1410 result.raw_ptr()->num_native_fields_ = 0; | 1409 result.raw_ptr()->num_native_fields_ = 0; |
| 1411 result.InitEmptyFields(); | 1410 result.InitEmptyFields(); |
| 1412 Isolate::Current()->class_table()->Register(result); | 1411 Isolate::Current()->class_table()->Register(result); |
| 1413 return result.raw(); | 1412 return result.raw(); |
| 1414 } | 1413 } |
| 1415 | 1414 |
| (...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2443 return IsTypeParameter() && other.IsTypeParameter() && | 2442 return IsTypeParameter() && other.IsTypeParameter() && |
| 2444 (Index() == other.Index()); | 2443 (Index() == other.Index()); |
| 2445 } | 2444 } |
| 2446 const Class& cls = Class::Handle(type_class()); | 2445 const Class& cls = Class::Handle(type_class()); |
| 2447 return cls.IsSubtypeOf(AbstractTypeArguments::Handle(arguments()), | 2446 return cls.IsSubtypeOf(AbstractTypeArguments::Handle(arguments()), |
| 2448 Class::Handle(other.type_class()), | 2447 Class::Handle(other.type_class()), |
| 2449 AbstractTypeArguments::Handle(other.arguments()), | 2448 AbstractTypeArguments::Handle(other.arguments()), |
| 2450 malformed_error); | 2449 malformed_error); |
| 2451 } | 2450 } |
| 2452 | 2451 |
| 2453 RawAbstractType* AbstractType::NewTypeParameter(const Class& clazz, | |
| 2454 intptr_t index, | |
| 2455 const String& name, | |
| 2456 intptr_t token_index) { | |
| 2457 return TypeParameter::New(clazz, index, name, token_index); | |
| 2458 } | |
| 2459 | |
| 2460 | 2452 |
| 2461 const char* AbstractType::ToCString() const { | 2453 const char* AbstractType::ToCString() const { |
| 2462 // AbstractType is an abstract class. | 2454 // AbstractType is an abstract class. |
| 2463 UNREACHABLE(); | 2455 UNREACHABLE(); |
| 2464 return "AbstractType"; | 2456 return "AbstractType"; |
| 2465 } | 2457 } |
| 2466 | 2458 |
| 2467 | 2459 |
| 2468 RawType* Type::NullType() { | 2460 RawType* Type::NullType() { |
| 2469 return Isolate::Current()->object_store()->null_type(); | 2461 return Isolate::Current()->object_store()->null_type(); |
| (...skipping 6563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9033 | 9025 |
| 9034 | 9026 |
| 9035 void Array::MakeImmutable() const { | 9027 void Array::MakeImmutable() const { |
| 9036 Isolate* isolate = Isolate::Current(); | 9028 Isolate* isolate = Isolate::Current(); |
| 9037 const Class& cls = Class::Handle( | 9029 const Class& cls = Class::Handle( |
| 9038 isolate, isolate->object_store()->immutable_array_class()); | 9030 isolate, isolate->object_store()->immutable_array_class()); |
| 9039 { | 9031 { |
| 9040 NoGCScope no_gc; | 9032 NoGCScope no_gc; |
| 9041 raw_ptr()->class_ = cls.raw(); | 9033 raw_ptr()->class_ = cls.raw(); |
| 9042 uword tags = raw_ptr()->tags_; | 9034 uword tags = raw_ptr()->tags_; |
| 9043 tags = RawObject::ClassTag::update(cls.index(), tags); | 9035 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 9044 raw_ptr()->tags_ = tags; | 9036 raw_ptr()->tags_ = tags; |
| 9045 } | 9037 } |
| 9046 } | 9038 } |
| 9047 | 9039 |
| 9048 | 9040 |
| 9049 const char* Array::ToCString() const { | 9041 const char* Array::ToCString() const { |
| 9050 return "Array"; | 9042 return "Array"; |
| 9051 } | 9043 } |
| 9052 | 9044 |
| 9053 | 9045 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 9080 intptr_t capacity_len = growable_array.Capacity(); | 9072 intptr_t capacity_len = growable_array.Capacity(); |
| 9081 Isolate* isolate = Isolate::Current(); | 9073 Isolate* isolate = Isolate::Current(); |
| 9082 const Array& array = Array::Handle(isolate, growable_array.data()); | 9074 const Array& array = Array::Handle(isolate, growable_array.data()); |
| 9083 const Array& new_array = Array::Handle(isolate, Array::Empty()); | 9075 const Array& new_array = Array::Handle(isolate, Array::Empty()); |
| 9084 intptr_t capacity_size = Array::InstanceSize(capacity_len); | 9076 intptr_t capacity_size = Array::InstanceSize(capacity_len); |
| 9085 intptr_t used_size = Array::InstanceSize(used_len); | 9077 intptr_t used_size = Array::InstanceSize(used_len); |
| 9086 NoGCScope no_gc; | 9078 NoGCScope no_gc; |
| 9087 | 9079 |
| 9088 // Update the size in the header field and length of the array object. | 9080 // Update the size in the header field and length of the array object. |
| 9089 uword tags = array.raw_ptr()->tags_; | 9081 uword tags = array.raw_ptr()->tags_; |
| 9090 ASSERT(kArray == RawObject::ClassTag::decode(tags)); | 9082 ASSERT(kArray == RawObject::ClassIdTag::decode(tags)); |
| 9091 tags = RawObject::SizeTag::update(used_size, tags); | 9083 tags = RawObject::SizeTag::update(used_size, tags); |
| 9092 array.raw_ptr()->tags_ = tags; | 9084 array.raw_ptr()->tags_ = tags; |
| 9093 array.SetLength(used_len); | 9085 array.SetLength(used_len); |
| 9094 | 9086 |
| 9095 // Null the GrowableObjectArray, we are removing it's backing array. | 9087 // Null the GrowableObjectArray, we are removing it's backing array. |
| 9096 growable_array.SetLength(0); | 9088 growable_array.SetLength(0); |
| 9097 growable_array.SetData(new_array); | 9089 growable_array.SetData(new_array); |
| 9098 | 9090 |
| 9099 // If there is any left over space fill it with either an Array object or | 9091 // If there is any left over space fill it with either an Array object or |
| 9100 // just a plain object (depending on the amount of left over space) so | 9092 // just a plain object (depending on the amount of left over space) so |
| 9101 // that it can be traversed over successfully during garbage collection. | 9093 // that it can be traversed over successfully during garbage collection. |
| 9102 if (capacity_size != used_size) { | 9094 if (capacity_size != used_size) { |
| 9103 ASSERT(capacity_len > used_len); | 9095 ASSERT(capacity_len > used_len); |
| 9104 intptr_t leftover_size = capacity_size - used_size; | 9096 intptr_t leftover_size = capacity_size - used_size; |
| 9105 | 9097 |
| 9106 uword addr = RawObject::ToAddr(array.raw()) + used_size; | 9098 uword addr = RawObject::ToAddr(array.raw()) + used_size; |
| 9107 if (leftover_size >= Array::InstanceSize(0)) { | 9099 if (leftover_size >= Array::InstanceSize(0)) { |
| 9108 // As we have enough space to use an array object, update the leftover | 9100 // As we have enough space to use an array object, update the leftover |
| 9109 // space as an Array object. | 9101 // space as an Array object. |
| 9110 RawArray* raw = reinterpret_cast<RawArray*>(RawObject::FromAddr(addr)); | 9102 RawArray* raw = reinterpret_cast<RawArray*>(RawObject::FromAddr(addr)); |
| 9111 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | 9103 const Class& cls = Class::Handle(isolate->object_store()->array_class()); |
| 9112 raw->ptr()->class_ = cls.raw(); | 9104 raw->ptr()->class_ = cls.raw(); |
| 9113 tags = 0; | 9105 tags = 0; |
| 9114 tags = RawObject::SizeTag::update(leftover_size, tags); | 9106 tags = RawObject::SizeTag::update(leftover_size, tags); |
| 9115 tags = RawObject::ClassTag::update(cls.index(), tags); | 9107 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 9116 raw->ptr()->tags_ = tags; | 9108 raw->ptr()->tags_ = tags; |
| 9117 intptr_t leftover_len = | 9109 intptr_t leftover_len = |
| 9118 ((leftover_size - Array::InstanceSize(0)) / kWordSize); | 9110 ((leftover_size - Array::InstanceSize(0)) / kWordSize); |
| 9119 raw->ptr()->tags_ = tags; | 9111 raw->ptr()->tags_ = tags; |
| 9120 raw->ptr()->length_ = Smi::New(leftover_len); | 9112 raw->ptr()->length_ = Smi::New(leftover_len); |
| 9121 } else { | 9113 } else { |
| 9122 // Update the leftover space as a basic object. | 9114 // Update the leftover space as a basic object. |
| 9123 ASSERT(leftover_size == Object::InstanceSize()); | 9115 ASSERT(leftover_size == Object::InstanceSize()); |
| 9124 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr)); | 9116 RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr)); |
| 9125 const Class& cls = Class::Handle(isolate->object_store()->object_class()); | 9117 const Class& cls = Class::Handle(isolate->object_store()->object_class()); |
| 9126 raw->ptr()->class_ = cls.raw(); | 9118 raw->ptr()->class_ = cls.raw(); |
| 9127 tags = 0; | 9119 tags = 0; |
| 9128 tags = RawObject::SizeTag::update(leftover_size, tags); | 9120 tags = RawObject::SizeTag::update(leftover_size, tags); |
| 9129 tags = RawObject::ClassTag::update(cls.index(), tags); | 9121 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 9130 raw->ptr()->tags_ = tags; | 9122 raw->ptr()->tags_ = tags; |
| 9131 } | 9123 } |
| 9132 } | 9124 } |
| 9133 return array.raw(); | 9125 return array.raw(); |
| 9134 } | 9126 } |
| 9135 | 9127 |
| 9136 | 9128 |
| 9137 RawImmutableArray* ImmutableArray::New(intptr_t len, | 9129 RawImmutableArray* ImmutableArray::New(intptr_t len, |
| 9138 Heap::Space space) { | 9130 Heap::Space space) { |
| 9139 ObjectStore* object_store = Isolate::Current()->object_store(); | 9131 ObjectStore* object_store = Isolate::Current()->object_store(); |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10115 const String& str = String::Handle(pattern()); | 10107 const String& str = String::Handle(pattern()); |
| 10116 const char* format = "JSRegExp: pattern=%s flags=%s"; | 10108 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 10117 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 10109 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 10118 char* chars = reinterpret_cast<char*>( | 10110 char* chars = reinterpret_cast<char*>( |
| 10119 Isolate::Current()->current_zone()->Allocate(len + 1)); | 10111 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 10120 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 10112 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 10121 return chars; | 10113 return chars; |
| 10122 } | 10114 } |
| 10123 | 10115 |
| 10124 } // namespace dart | 10116 } // namespace dart |
| OLD | NEW |