| 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/snapshot.h" | 5 #include "vm/snapshot.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
| 9 #include "vm/exceptions.h" |
| 9 #include "vm/heap.h" | 10 #include "vm/heap.h" |
| 10 #include "vm/object.h" | 11 #include "vm/object.h" |
| 11 #include "vm/object_store.h" | 12 #include "vm/object_store.h" |
| 12 | 13 |
| 13 namespace dart { | 14 namespace dart { |
| 14 | 15 |
| 15 enum { | 16 enum { |
| 16 kInstanceId = ObjectStore::kMaxId, | 17 kInstanceId = ObjectStore::kMaxId, |
| 17 kMaxPredefinedObjectIds, | 18 kMaxPredefinedObjectIds, |
| 18 }; | 19 }; |
| 20 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; |
| 21 static const int kNumInitialReferences = 4; |
| 19 | 22 |
| 20 | 23 |
| 21 static bool IsSingletonClassId(intptr_t index) { | 24 static bool IsSingletonClassId(intptr_t index) { |
| 22 // Check if this is a singleton object class which is shared by all isolates. | 25 // Check if this is a singleton object class which is shared by all isolates. |
| 23 return (index >= Object::kClassClass && index < Object::kMaxId); | 26 return (index >= Object::kClassClass && index < Object::kMaxId); |
| 24 } | 27 } |
| 25 | 28 |
| 26 | 29 |
| 27 static bool IsObjectStoreClassId(intptr_t index) { | 30 static bool IsObjectStoreClassId(intptr_t index) { |
| 28 // Check if this is a class which is stored in the object store. | 31 // Check if this is a class which is stored in the object store. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 55 SnapshotReader::SnapshotReader(const Snapshot* snapshot, Isolate* isolate) | 58 SnapshotReader::SnapshotReader(const Snapshot* snapshot, Isolate* isolate) |
| 56 : stream_(snapshot->content(), snapshot->length()), | 59 : stream_(snapshot->content(), snapshot->length()), |
| 57 kind_(snapshot->kind()), | 60 kind_(snapshot->kind()), |
| 58 isolate_(isolate), | 61 isolate_(isolate), |
| 59 cls_(Class::Handle()), | 62 cls_(Class::Handle()), |
| 60 obj_(Object::Handle()), | 63 obj_(Object::Handle()), |
| 61 str_(String::Handle()), | 64 str_(String::Handle()), |
| 62 library_(Library::Handle()), | 65 library_(Library::Handle()), |
| 63 type_(AbstractType::Handle()), | 66 type_(AbstractType::Handle()), |
| 64 type_arguments_(AbstractTypeArguments::Handle()), | 67 type_arguments_(AbstractTypeArguments::Handle()), |
| 65 backward_references_() { | 68 backward_references_((snapshot->kind() == Snapshot::kFull) ? |
| 69 kNumInitialReferencesInFullSnapshot : |
| 70 kNumInitialReferences) { |
| 66 } | 71 } |
| 67 | 72 |
| 68 | 73 |
| 69 RawObject* SnapshotReader::ReadObject() { | 74 RawObject* SnapshotReader::ReadObject() { |
| 70 int64_t value = Read<int64_t>(); | 75 int64_t value = Read<int64_t>(); |
| 71 if ((value & kSmiTagMask) == 0) { | 76 if ((value & kSmiTagMask) == 0) { |
| 72 return Integer::New((value >> kSmiTagShift)); | 77 return Integer::New((value >> kSmiTagShift)); |
| 73 } | 78 } |
| 74 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | 79 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); |
| 75 return ReadObjectImpl(value); | 80 return ReadObjectImpl(value); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 102 backward_references_.Add(obj); | 107 backward_references_.Add(obj); |
| 103 } | 108 } |
| 104 | 109 |
| 105 | 110 |
| 106 void SnapshotReader::ReadFullSnapshot() { | 111 void SnapshotReader::ReadFullSnapshot() { |
| 107 ASSERT(kind_ == Snapshot::kFull); | 112 ASSERT(kind_ == Snapshot::kFull); |
| 108 Isolate* isolate = Isolate::Current(); | 113 Isolate* isolate = Isolate::Current(); |
| 109 ASSERT(isolate != NULL); | 114 ASSERT(isolate != NULL); |
| 110 ObjectStore* object_store = isolate->object_store(); | 115 ObjectStore* object_store = isolate->object_store(); |
| 111 ASSERT(object_store != NULL); | 116 ASSERT(object_store != NULL); |
| 117 NoGCScope no_gc; |
| 118 |
| 119 // TODO(asiva): Add a check here to ensure we have the right heap |
| 120 // size for the full snapshot being read. |
| 112 | 121 |
| 113 // Read in all the objects stored in the object store. | 122 // Read in all the objects stored in the object store. |
| 114 intptr_t num_flds = (object_store->to() - object_store->from()); | 123 intptr_t num_flds = (object_store->to() - object_store->from()); |
| 115 for (intptr_t i = 0; i <= num_flds; i++) { | 124 for (intptr_t i = 0; i <= num_flds; i++) { |
| 116 *(object_store->from() + i) = ReadObject(); | 125 *(object_store->from() + i) = ReadObject(); |
| 117 } | 126 } |
| 118 | 127 |
| 119 // Setup native resolver for bootstrap impl. | 128 // Setup native resolver for bootstrap impl. |
| 120 Bootstrap::SetupNativeResolver(); | 129 Bootstrap::SetupNativeResolver(); |
| 121 } | 130 } |
| 122 | 131 |
| 123 | 132 |
| 133 #define ALLOC_NEW_OBJECT_WITH_LEN(type, class_obj, length) \ |
| 134 ASSERT(kind_ == Snapshot::kFull); \ |
| 135 ASSERT(isolate()->no_gc_scope_depth() != 0); \ |
| 136 cls_ = class_obj; \ |
| 137 Raw##type* obj = reinterpret_cast<Raw##type*>( \ |
| 138 AllocateUninitialized(cls_, type::InstanceSize(length))); \ |
| 139 obj->ptr()->length_ = Smi::New(length); \ |
| 140 return obj; \ |
| 141 |
| 142 |
| 143 RawArray* SnapshotReader::NewArray(intptr_t len) { |
| 144 ALLOC_NEW_OBJECT_WITH_LEN(Array, object_store()->array_class(), len); |
| 145 } |
| 146 |
| 147 |
| 148 RawImmutableArray* SnapshotReader::NewImmutableArray(intptr_t len) { |
| 149 ALLOC_NEW_OBJECT_WITH_LEN(ImmutableArray, |
| 150 object_store()->immutable_array_class(), |
| 151 len); |
| 152 } |
| 153 |
| 154 |
| 155 RawOneByteString* SnapshotReader::NewOneByteString(intptr_t len) { |
| 156 ALLOC_NEW_OBJECT_WITH_LEN(OneByteString, |
| 157 object_store()->one_byte_string_class(), |
| 158 len); |
| 159 } |
| 160 |
| 161 |
| 162 RawTwoByteString* SnapshotReader::NewTwoByteString(intptr_t len) { |
| 163 ALLOC_NEW_OBJECT_WITH_LEN(TwoByteString, |
| 164 object_store()->two_byte_string_class(), |
| 165 len); |
| 166 } |
| 167 |
| 168 |
| 169 RawFourByteString* SnapshotReader::NewFourByteString(intptr_t len) { |
| 170 ALLOC_NEW_OBJECT_WITH_LEN(FourByteString, |
| 171 object_store()->four_byte_string_class(), |
| 172 len); |
| 173 } |
| 174 |
| 175 |
| 176 RawTypeArguments* SnapshotReader::NewTypeArguments(intptr_t len) { |
| 177 ALLOC_NEW_OBJECT_WITH_LEN(TypeArguments, |
| 178 Object::type_arguments_class(), |
| 179 len); |
| 180 } |
| 181 |
| 182 |
| 183 RawTokenStream* SnapshotReader::NewTokenStream(intptr_t len) { |
| 184 ALLOC_NEW_OBJECT_WITH_LEN(TokenStream, |
| 185 Object::token_stream_class(), |
| 186 len); |
| 187 } |
| 188 |
| 189 |
| 190 RawContext* SnapshotReader::NewContext(intptr_t num_variables) { |
| 191 ASSERT(kind_ == Snapshot::kFull); |
| 192 ASSERT(isolate()->no_gc_scope_depth() != 0); |
| 193 cls_ = Object::context_class(); |
| 194 RawContext* obj = reinterpret_cast<RawContext*>( |
| 195 AllocateUninitialized(cls_, Context::InstanceSize(num_variables))); |
| 196 obj->ptr()->num_variables_ = num_variables; |
| 197 return obj; |
| 198 } |
| 199 |
| 200 |
| 201 RawClass* SnapshotReader::NewClass(int value) { |
| 202 ASSERT(kind_ == Snapshot::kFull); |
| 203 ASSERT(isolate()->no_gc_scope_depth() != 0); |
| 204 ObjectKind object_kind = static_cast<ObjectKind>(value); |
| 205 if ((object_kind == kInstance || object_kind == kClosure)) { |
| 206 cls_ = Object::class_class(); |
| 207 RawClass* obj = reinterpret_cast<RawClass*>( |
| 208 AllocateUninitialized(cls_, Class::InstanceSize())); |
| 209 obj->ptr()->instance_kind_ = object_kind; |
| 210 if (object_kind == kInstance) { |
| 211 Instance fake; |
| 212 obj->ptr()->handle_vtable_ = fake.vtable(); |
| 213 } else { |
| 214 Closure fake; |
| 215 obj->ptr()->handle_vtable_ = fake.vtable(); |
| 216 } |
| 217 return obj; |
| 218 } |
| 219 return Class::GetClass(object_kind); |
| 220 } |
| 221 |
| 222 |
| 223 RawMint* SnapshotReader::NewMint(int64_t value) { |
| 224 ASSERT(kind_ == Snapshot::kFull); |
| 225 ASSERT(isolate()->no_gc_scope_depth() != 0); |
| 226 cls_ = object_store()->mint_class(); |
| 227 RawMint* obj = reinterpret_cast<RawMint*>( |
| 228 AllocateUninitialized(cls_, Mint::InstanceSize())); |
| 229 obj->ptr()->value_ = value; |
| 230 return obj; |
| 231 } |
| 232 |
| 233 |
| 234 RawDouble* SnapshotReader::NewDouble(double value) { |
| 235 ASSERT(kind_ == Snapshot::kFull); |
| 236 ASSERT(isolate()->no_gc_scope_depth() != 0); |
| 237 cls_ = object_store()->double_class(); |
| 238 RawDouble* obj = reinterpret_cast<RawDouble*>( |
| 239 AllocateUninitialized(cls_, Double::InstanceSize())); |
| 240 obj->ptr()->value_ = value; |
| 241 return obj; |
| 242 } |
| 243 |
| 244 |
| 245 #define ALLOC_NEW_OBJECT(type, class_obj) \ |
| 246 ASSERT(kind_ == Snapshot::kFull); \ |
| 247 ASSERT(isolate()->no_gc_scope_depth() != 0); \ |
| 248 cls_ = class_obj; \ |
| 249 return reinterpret_cast<Raw##type*>( \ |
| 250 AllocateUninitialized(cls_, type::InstanceSize())); \ |
| 251 |
| 252 |
| 253 RawUnresolvedClass* SnapshotReader::NewUnresolvedClass() { |
| 254 ALLOC_NEW_OBJECT(UnresolvedClass, Object::unresolved_class_class()); |
| 255 } |
| 256 |
| 257 |
| 258 RawType* SnapshotReader::NewType() { |
| 259 ALLOC_NEW_OBJECT(Type, Object::type_class()); |
| 260 } |
| 261 |
| 262 |
| 263 RawTypeParameter* SnapshotReader::NewTypeParameter() { |
| 264 ALLOC_NEW_OBJECT(TypeParameter, Object::type_parameter_class()); |
| 265 } |
| 266 |
| 267 |
| 268 RawFunction* SnapshotReader::NewFunction() { |
| 269 ALLOC_NEW_OBJECT(Function, Object::function_class()); |
| 270 } |
| 271 |
| 272 |
| 273 RawField* SnapshotReader::NewField() { |
| 274 ALLOC_NEW_OBJECT(Field, Object::field_class()); |
| 275 } |
| 276 |
| 277 |
| 278 RawLibrary* SnapshotReader::NewLibrary() { |
| 279 ALLOC_NEW_OBJECT(Library, Object::library_class()); |
| 280 } |
| 281 |
| 282 |
| 283 RawLibraryPrefix* SnapshotReader::NewLibraryPrefix() { |
| 284 ALLOC_NEW_OBJECT(LibraryPrefix, Object::library_prefix_class()); |
| 285 } |
| 286 |
| 287 |
| 288 RawScript* SnapshotReader::NewScript() { |
| 289 ALLOC_NEW_OBJECT(Script, Object::script_class()); |
| 290 } |
| 291 |
| 292 |
| 124 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { | 293 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { |
| 125 SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); | 294 SerializedHeaderType header_type = SerializedHeaderTag::decode(class_header); |
| 126 | 295 |
| 127 // If the header is an object Id, lookup singleton VM classes or classes | 296 // If the header is an object Id, lookup singleton VM classes or classes |
| 128 // stored in the object store. | 297 // stored in the object store. |
| 129 if (header_type == kObjectId) { | 298 if (header_type == kObjectId) { |
| 130 intptr_t header_value = SerializedHeaderData::decode(class_header); | 299 intptr_t header_value = SerializedHeaderData::decode(class_header); |
| 131 if (IsSingletonClassId(header_value)) { | 300 if (IsObjectStoreClassId(header_value)) { |
| 301 return object_store()->GetClass(header_value); |
| 302 } else if (IsSingletonClassId(header_value)) { |
| 132 return Object::GetSingletonClass(header_value); // return the singleton. | 303 return Object::GetSingletonClass(header_value); // return the singleton. |
| 133 } else if (IsObjectStoreClassId(header_value)) { | |
| 134 return object_store()->GetClass(header_value); | |
| 135 } | 304 } |
| 136 } | 305 } |
| 137 return Class::null(); | 306 return Class::null(); |
| 138 } | 307 } |
| 139 | 308 |
| 140 | 309 |
| 310 RawObject* SnapshotReader::AllocateUninitialized(const Class& cls, |
| 311 intptr_t size) { |
| 312 ASSERT(isolate()->no_gc_scope_depth() != 0); |
| 313 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| 314 Heap* heap = isolate()->heap(); |
| 315 |
| 316 uword address = heap->TryAllocate(size, Heap::kOld); |
| 317 if (address == 0) { |
| 318 // Use the preallocated out of memory exception to avoid calling |
| 319 // into dart code or allocating any code. |
| 320 const Instance& exception = |
| 321 Instance::Handle(object_store()->out_of_memory()); |
| 322 Exceptions::Throw(exception); |
| 323 UNREACHABLE(); |
| 324 } |
| 325 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); |
| 326 raw_obj->ptr()->class_ = cls.raw(); |
| 327 uword tags = 0; |
| 328 tags = RawObject::SizeTag::update(size, tags); |
| 329 raw_obj->ptr()->tags_ = tags; |
| 330 return raw_obj; |
| 331 } |
| 332 |
| 333 |
| 141 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header) { | 334 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header) { |
| 142 SerializedHeaderType header_type = SerializedHeaderTag::decode(header); | 335 SerializedHeaderType header_type = SerializedHeaderTag::decode(header); |
| 143 intptr_t header_value = SerializedHeaderData::decode(header); | 336 intptr_t header_value = SerializedHeaderData::decode(header); |
| 144 | 337 |
| 145 if (header_type == kObjectId) { | 338 if (header_type == kObjectId) { |
| 146 return ReadIndexedObject(header_value); | 339 return ReadIndexedObject(header_value); |
| 147 } | 340 } |
| 148 ASSERT(header_type == kInlined); | 341 ASSERT(header_type == kInlined); |
| 149 return ReadInlinedObject(header_value); | 342 return ReadInlinedObject(header_value); |
| 150 } | 343 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 if (SerializedHeaderData::decode(class_header) == kInstanceId) { | 379 if (SerializedHeaderData::decode(class_header) == kInstanceId) { |
| 187 // Object is regular dart instance. | 380 // Object is regular dart instance. |
| 188 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); | 381 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); |
| 189 AddBackwardReference(object_id, &result); | 382 AddBackwardReference(object_id, &result); |
| 190 | 383 |
| 191 cls_ ^= ReadObject(); | 384 cls_ ^= ReadObject(); |
| 192 ASSERT(!cls_.IsNull()); | 385 ASSERT(!cls_.IsNull()); |
| 193 intptr_t instance_size = cls_.instance_size(); | 386 intptr_t instance_size = cls_.instance_size(); |
| 194 ASSERT(instance_size > 0); | 387 ASSERT(instance_size > 0); |
| 195 // Allocate the instance and read in all the fields for the object. | 388 // Allocate the instance and read in all the fields for the object. |
| 196 RawObject* raw = Instance::New(cls_, Heap::kNew); | 389 if (kind_ == Snapshot::kFull) { |
| 197 result ^= raw; | 390 result ^= AllocateUninitialized(cls_, instance_size); |
| 391 } else { |
| 392 result ^= Object::Allocate(cls_, instance_size, Heap::kNew); |
| 393 } |
| 198 intptr_t offset = Object::InstanceSize(); | 394 intptr_t offset = Object::InstanceSize(); |
| 199 while (offset < instance_size) { | 395 while (offset < instance_size) { |
| 200 obj_ = ReadObject(); | 396 obj_ = ReadObject(); |
| 201 result.SetFieldAtOffset(offset, obj_); | 397 result.SetFieldAtOffset(offset, obj_); |
| 202 offset += kWordSize; | 398 offset += kWordSize; |
| 203 } | 399 } |
| 204 if (kind_ == Snapshot::kFull) { | 400 if (kind_ == Snapshot::kFull) { |
| 205 result.SetCreatedFromSnapshot(); | 401 result.SetCreatedFromSnapshot(); |
| 206 } else if (result.IsCanonical()) { | 402 } else if (result.IsCanonical()) { |
| 207 result = result.Canonicalize(); | 403 result = result.Canonicalize(); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 | 650 |
| 455 | 651 |
| 456 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 652 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 457 for (RawObject** current = first; current <= last; current++) { | 653 for (RawObject** current = first; current <= last; current++) { |
| 458 RawObject* raw_obj = *current; | 654 RawObject* raw_obj = *current; |
| 459 writer_->WriteObject(raw_obj); | 655 writer_->WriteObject(raw_obj); |
| 460 } | 656 } |
| 461 } | 657 } |
| 462 | 658 |
| 463 } // namespace dart | 659 } // namespace dart |
| OLD | NEW |