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 #include "vm/object_store.h" | 6 #include "vm/object_store.h" |
7 #include "vm/snapshot.h" | 7 #include "vm/snapshot.h" |
8 #include "vm/stub_code.h" | 8 #include "vm/stub_code.h" |
9 #include "vm/symbols.h" | 9 #include "vm/symbols.h" |
10 #include "vm/visitor.h" | 10 #include "vm/visitor.h" |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 | 203 |
204 RawType* Type::ReadFrom(SnapshotReader* reader, | 204 RawType* Type::ReadFrom(SnapshotReader* reader, |
205 intptr_t object_id, | 205 intptr_t object_id, |
206 intptr_t tags, | 206 intptr_t tags, |
207 Snapshot::Kind kind) { | 207 Snapshot::Kind kind) { |
208 ASSERT(reader != NULL); | 208 ASSERT(reader != NULL); |
209 | 209 |
210 // Allocate type object. | 210 // Allocate type object. |
211 Type& type = Type::ZoneHandle(reader->zone(), NEW_OBJECT(Type)); | 211 Type& type = Type::ZoneHandle(reader->zone(), NEW_OBJECT(Type)); |
212 bool is_canonical = RawObject::IsCanonical(tags); | 212 bool is_canonical = RawObject::IsCanonical(tags); |
213 bool defer_canonicalization = is_canonical && | 213 bool defer_canonicalization = is_canonical && (kind != Snapshot::kFull); |
214 ((kind == Snapshot::kScript && RawObject::IsCreatedFromSnapshot(tags)) || | |
215 kind == Snapshot::kMessage); | |
216 reader->AddBackRef(object_id, &type, kIsDeserialized, defer_canonicalization); | 214 reader->AddBackRef(object_id, &type, kIsDeserialized, defer_canonicalization); |
217 | 215 |
218 // Set all non object fields. | 216 // Set all non object fields. |
219 type.set_token_pos(reader->Read<int32_t>()); | 217 type.set_token_pos(reader->Read<int32_t>()); |
220 type.set_type_state(reader->Read<int8_t>()); | 218 type.set_type_state(reader->Read<int8_t>()); |
221 | 219 |
222 // Set all the object fields. | 220 // Set all the object fields. |
223 // TODO(5411462): Need to assert No GC can happen here, even though | 221 // TODO(5411462): Need to assert No GC can happen here, even though |
224 // allocations may happen. | 222 // allocations may happen. |
225 intptr_t num_flds = (type.raw()->to() - type.raw()->from()); | 223 intptr_t num_flds = (type.raw()->to() - type.raw()->from()); |
226 intptr_t from_offset = OFFSET_OF_FROM(type); | 224 intptr_t from_offset = OFFSET_OF_FROM(type); |
227 for (intptr_t i = 0; i <= num_flds; i++) { | 225 for (intptr_t i = 0; i <= num_flds; i++) { |
228 (*reader->PassiveObjectHandle()) = | 226 (*reader->PassiveObjectHandle()) = |
229 reader->ReadObjectImpl(kAsInlinedObject, object_id, (i + from_offset)); | 227 reader->ReadObjectImpl(kAsReference, object_id, (i + from_offset)); |
230 type.StorePointer((type.raw()->from() + i), | 228 type.StorePointer((type.raw()->from() + i), |
231 reader->PassiveObjectHandle()->raw()); | 229 reader->PassiveObjectHandle()->raw()); |
232 } | 230 } |
233 | 231 |
234 // Set the object tags. | 232 // Set the object tags. |
235 type.set_tags(tags); | 233 type.set_tags(tags); |
| 234 if (defer_canonicalization) { |
| 235 // We are deferring canonicalization so mark object as not canonical. |
| 236 type.ClearCanonical(); |
| 237 } |
236 | 238 |
237 return type.raw(); | 239 return type.raw(); |
238 } | 240 } |
239 | 241 |
240 | 242 |
241 void RawType::WriteTo(SnapshotWriter* writer, | 243 void RawType::WriteTo(SnapshotWriter* writer, |
242 intptr_t object_id, | 244 intptr_t object_id, |
243 Snapshot::Kind kind) { | 245 Snapshot::Kind kind) { |
244 ASSERT(writer != NULL); | 246 ASSERT(writer != NULL); |
245 | 247 |
246 // Only resolved and finalized types should be written to a snapshot. | 248 // Only resolved and finalized types should be written to a snapshot. |
247 ASSERT((ptr()->type_state_ == RawType::kFinalizedInstantiated) || | 249 ASSERT((ptr()->type_state_ == RawType::kFinalizedInstantiated) || |
248 (ptr()->type_state_ == RawType::kFinalizedUninstantiated)); | 250 (ptr()->type_state_ == RawType::kFinalizedUninstantiated)); |
249 | 251 |
250 // Write out the serialization header value for this object. | 252 // Write out the serialization header value for this object. |
251 writer->WriteInlinedObjectHeader(object_id); | 253 writer->WriteInlinedObjectHeader(object_id); |
252 | 254 |
253 // Write out the class and tags information. | 255 // Write out the class and tags information. |
254 writer->WriteIndexedObject(kTypeCid); | 256 writer->WriteIndexedObject(kTypeCid); |
255 writer->WriteTags(writer->GetObjectTags(this)); | 257 writer->WriteTags(writer->GetObjectTags(this)); |
256 | 258 |
257 // Write out all the non object pointer fields. | 259 // Write out all the non object pointer fields. |
258 writer->Write<int32_t>(ptr()->token_pos_); | 260 writer->Write<int32_t>(ptr()->token_pos_); |
259 writer->Write<int8_t>(ptr()->type_state_); | 261 writer->Write<int8_t>(ptr()->type_state_); |
260 | 262 |
261 // Write out all the object pointer fields. Since we will be canonicalizing | 263 // Write out all the object pointer fields. Since we will be canonicalizing |
262 // the type object when reading it back we should write out all the fields | 264 // the type object when reading it back we should write out all the fields |
263 // inline and not as references. | 265 // inline and not as references. |
264 SnapshotWriterVisitor visitor(writer, false); | 266 SnapshotWriterVisitor visitor(writer); |
265 visitor.VisitPointers(from(), to()); | 267 visitor.VisitPointers(from(), to()); |
266 } | 268 } |
267 | 269 |
268 | 270 |
269 RawTypeRef* TypeRef::ReadFrom(SnapshotReader* reader, | 271 RawTypeRef* TypeRef::ReadFrom(SnapshotReader* reader, |
270 intptr_t object_id, | 272 intptr_t object_id, |
271 intptr_t tags, | 273 intptr_t tags, |
272 Snapshot::Kind kind) { | 274 Snapshot::Kind kind) { |
273 ASSERT(reader != NULL); | 275 ASSERT(reader != NULL); |
274 | 276 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 intptr_t tags, | 448 intptr_t tags, |
447 Snapshot::Kind kind) { | 449 Snapshot::Kind kind) { |
448 ASSERT(reader != NULL); | 450 ASSERT(reader != NULL); |
449 | 451 |
450 // Read the length so that we can determine instance size to allocate. | 452 // Read the length so that we can determine instance size to allocate. |
451 intptr_t len = reader->ReadSmiValue(); | 453 intptr_t len = reader->ReadSmiValue(); |
452 | 454 |
453 TypeArguments& type_arguments = TypeArguments::ZoneHandle( | 455 TypeArguments& type_arguments = TypeArguments::ZoneHandle( |
454 reader->zone(), NEW_OBJECT_WITH_LEN_SPACE(TypeArguments, len, kind)); | 456 reader->zone(), NEW_OBJECT_WITH_LEN_SPACE(TypeArguments, len, kind)); |
455 bool is_canonical = RawObject::IsCanonical(tags); | 457 bool is_canonical = RawObject::IsCanonical(tags); |
456 bool defer_canonicalization = is_canonical && | 458 bool defer_canonicalization = is_canonical && (kind != Snapshot::kFull); |
457 ((kind == Snapshot::kScript && RawObject::IsCreatedFromSnapshot(tags)) || | |
458 kind == Snapshot::kMessage); | |
459 reader->AddBackRef(object_id, | 459 reader->AddBackRef(object_id, |
460 &type_arguments, | 460 &type_arguments, |
461 kIsDeserialized, | 461 kIsDeserialized, |
462 defer_canonicalization); | 462 defer_canonicalization); |
463 | 463 |
464 // Set the instantiations field, which is only read from a full snapshot. | 464 // Set the instantiations field, which is only read from a full snapshot. |
465 if (kind == Snapshot::kFull) { | 465 if (kind == Snapshot::kFull) { |
466 *(reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject); | 466 *(reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject); |
467 type_arguments.set_instantiations(*(reader->ArrayHandle())); | 467 type_arguments.set_instantiations(*(reader->ArrayHandle())); |
468 } else { | 468 } else { |
469 type_arguments.set_instantiations(Object::zero_array()); | 469 type_arguments.set_instantiations(Object::zero_array()); |
470 } | 470 } |
471 | 471 |
472 // Now set all the type fields. | 472 // Now set all the type fields. |
473 intptr_t offset = type_arguments.TypeAddr(0) - | 473 intptr_t offset = type_arguments.TypeAddr(0) - |
474 reinterpret_cast<RawAbstractType**>(type_arguments.raw()->ptr()); | 474 reinterpret_cast<RawAbstractType**>(type_arguments.raw()->ptr()); |
475 for (intptr_t i = 0; i < len; i++) { | 475 for (intptr_t i = 0; i < len; i++) { |
476 *reader->TypeHandle() ^= | 476 *reader->TypeHandle() ^= |
477 reader->ReadObjectImpl(kAsInlinedObject, object_id, (i + offset)); | 477 reader->ReadObjectImpl(kAsReference, object_id, (i + offset)); |
478 type_arguments.SetTypeAt(i, *reader->TypeHandle()); | 478 type_arguments.SetTypeAt(i, *reader->TypeHandle()); |
479 } | 479 } |
480 | 480 |
481 // Set the object tags . | 481 // Set the object tags . |
482 type_arguments.set_tags(tags); | 482 type_arguments.set_tags(tags); |
| 483 if (defer_canonicalization) { |
| 484 // We are deferring canonicalization so mark object as not canonical. |
| 485 type_arguments.ClearCanonical(); |
| 486 } |
483 | 487 |
484 return type_arguments.raw(); | 488 return type_arguments.raw(); |
485 } | 489 } |
486 | 490 |
487 | 491 |
488 void RawTypeArguments::WriteTo(SnapshotWriter* writer, | 492 void RawTypeArguments::WriteTo(SnapshotWriter* writer, |
489 intptr_t object_id, | 493 intptr_t object_id, |
490 Snapshot::Kind kind) { | 494 Snapshot::Kind kind) { |
491 ASSERT(writer != NULL); | 495 ASSERT(writer != NULL); |
492 | 496 |
493 // Write out the serialization header value for this object. | 497 // Write out the serialization header value for this object. |
494 writer->WriteInlinedObjectHeader(object_id); | 498 writer->WriteInlinedObjectHeader(object_id); |
495 | 499 |
496 // Write out the class and tags information. | 500 // Write out the class and tags information. |
497 writer->WriteVMIsolateObject(kTypeArgumentsCid); | 501 writer->WriteVMIsolateObject(kTypeArgumentsCid); |
498 writer->WriteTags(writer->GetObjectTags(this)); | 502 writer->WriteTags(writer->GetObjectTags(this)); |
499 | 503 |
500 // Write out the length field. | 504 // Write out the length field. |
501 writer->Write<RawObject*>(ptr()->length_); | 505 writer->Write<RawObject*>(ptr()->length_); |
502 | 506 |
503 // Write out the instantiations field, but only in a full snapshot. | 507 // Write out the instantiations field, but only in a full snapshot. |
504 if (kind == Snapshot::kFull) { | 508 if (kind == Snapshot::kFull) { |
505 writer->WriteObjectImpl(ptr()->instantiations_, kAsInlinedObject); | 509 writer->WriteObjectImpl(ptr()->instantiations_, kAsInlinedObject); |
506 } | 510 } |
507 | 511 |
508 // Write out the individual types. | 512 // Write out the individual types. |
509 intptr_t len = Smi::Value(ptr()->length_); | 513 intptr_t len = Smi::Value(ptr()->length_); |
510 for (intptr_t i = 0; i < len; i++) { | 514 for (intptr_t i = 0; i < len; i++) { |
511 writer->WriteObjectImpl(ptr()->types()[i], kAsInlinedObject); | 515 writer->WriteObjectImpl(ptr()->types()[i], kAsReference); |
512 } | 516 } |
513 } | 517 } |
514 | 518 |
515 | 519 |
516 RawPatchClass* PatchClass::ReadFrom(SnapshotReader* reader, | 520 RawPatchClass* PatchClass::ReadFrom(SnapshotReader* reader, |
517 intptr_t object_id, | 521 intptr_t object_id, |
518 intptr_t tags, | 522 intptr_t tags, |
519 Snapshot::Kind kind) { | 523 Snapshot::Kind kind) { |
520 ASSERT(reader != NULL); | 524 ASSERT(reader != NULL); |
521 ASSERT(((kind == Snapshot::kScript) && | 525 ASSERT(((kind == Snapshot::kScript) && |
(...skipping 1803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2325 | 2329 |
2326 // Read the length so that we can determine instance size to allocate. | 2330 // Read the length so that we can determine instance size to allocate. |
2327 GrowableObjectArray& array = GrowableObjectArray::ZoneHandle( | 2331 GrowableObjectArray& array = GrowableObjectArray::ZoneHandle( |
2328 reader->zone(), GrowableObjectArray::null()); | 2332 reader->zone(), GrowableObjectArray::null()); |
2329 if (kind == Snapshot::kFull) { | 2333 if (kind == Snapshot::kFull) { |
2330 array = reader->NewGrowableObjectArray(); | 2334 array = reader->NewGrowableObjectArray(); |
2331 } else { | 2335 } else { |
2332 array = GrowableObjectArray::New(0, HEAP_SPACE(kind)); | 2336 array = GrowableObjectArray::New(0, HEAP_SPACE(kind)); |
2333 } | 2337 } |
2334 reader->AddBackRef(object_id, &array, kIsDeserialized); | 2338 reader->AddBackRef(object_id, &array, kIsDeserialized); |
2335 intptr_t length = reader->ReadSmiValue(); | 2339 |
2336 array.SetLength(length); | 2340 // Read type arguments of growable array object. |
| 2341 const intptr_t typeargs_offset = |
| 2342 GrowableObjectArray::type_arguments_offset() / kWordSize; |
| 2343 *reader->TypeArgumentsHandle() ^= |
| 2344 reader->ReadObjectImpl(kAsInlinedObject, object_id, typeargs_offset); |
| 2345 array.StorePointer(&array.raw_ptr()->type_arguments_, |
| 2346 reader->TypeArgumentsHandle()->raw()); |
| 2347 |
| 2348 // Read length of growable array object. |
| 2349 array.SetLength(reader->ReadSmiValue()); |
| 2350 |
| 2351 // Read the backing array of growable array object. |
2337 *(reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject); | 2352 *(reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject); |
2338 array.SetData(*(reader->ArrayHandle())); | 2353 array.SetData(*(reader->ArrayHandle())); |
2339 *(reader->TypeArgumentsHandle()) = reader->ArrayHandle()->GetTypeArguments(); | 2354 |
2340 array.SetTypeArguments(*(reader->TypeArgumentsHandle())); | |
2341 return array.raw(); | 2355 return array.raw(); |
2342 } | 2356 } |
2343 | 2357 |
2344 | 2358 |
2345 void RawGrowableObjectArray::WriteTo(SnapshotWriter* writer, | 2359 void RawGrowableObjectArray::WriteTo(SnapshotWriter* writer, |
2346 intptr_t object_id, | 2360 intptr_t object_id, |
2347 Snapshot::Kind kind) { | 2361 Snapshot::Kind kind) { |
2348 ASSERT(writer != NULL); | 2362 ASSERT(writer != NULL); |
2349 | 2363 |
2350 // Write out the serialization header value for this object. | 2364 // Write out the serialization header value for this object. |
2351 writer->WriteInlinedObjectHeader(object_id); | 2365 writer->WriteInlinedObjectHeader(object_id); |
2352 | 2366 |
2353 // Write out the class and tags information. | 2367 // Write out the class and tags information. |
2354 writer->WriteIndexedObject(kGrowableObjectArrayCid); | 2368 writer->WriteIndexedObject(kGrowableObjectArrayCid); |
2355 writer->WriteTags(writer->GetObjectTags(this)); | 2369 writer->WriteTags(writer->GetObjectTags(this)); |
2356 | 2370 |
| 2371 // Write out the type arguments field. |
| 2372 writer->WriteObjectImpl(ptr()->type_arguments_, kAsInlinedObject); |
| 2373 |
2357 // Write out the used length field. | 2374 // Write out the used length field. |
2358 writer->Write<RawObject*>(ptr()->length_); | 2375 writer->Write<RawObject*>(ptr()->length_); |
2359 | 2376 |
2360 // Write out the Array object. | 2377 // Write out the Array object. |
2361 writer->WriteObjectImpl(ptr()->data_, kAsInlinedObject); | 2378 writer->WriteObjectImpl(ptr()->data_, kAsInlinedObject); |
2362 } | 2379 } |
2363 | 2380 |
2364 | 2381 |
2365 RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader, | 2382 RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader, |
2366 intptr_t object_id, | 2383 intptr_t object_id, |
2367 intptr_t tags, | 2384 intptr_t tags, |
2368 Snapshot::Kind kind) { | 2385 Snapshot::Kind kind) { |
2369 ASSERT(reader != NULL); | 2386 ASSERT(reader != NULL); |
2370 | 2387 |
2371 LinkedHashMap& map = LinkedHashMap::ZoneHandle( | 2388 LinkedHashMap& map = LinkedHashMap::ZoneHandle( |
2372 reader->zone(), LinkedHashMap::null()); | 2389 reader->zone(), LinkedHashMap::null()); |
2373 if (kind == Snapshot::kFull || kind == Snapshot::kScript) { | 2390 if (kind == Snapshot::kFull || kind == Snapshot::kScript) { |
2374 // The immutable maps that seed map literals are not yet VM-internal, so | 2391 // The immutable maps that seed map literals are not yet VM-internal, so |
2375 // we don't reach this. | 2392 // we don't reach this. |
2376 UNREACHABLE(); | 2393 UNREACHABLE(); |
2377 } else { | 2394 } else { |
2378 // Since the map might contain itself as a key or value, allocate first. | 2395 // Since the map might contain itself as a key or value, allocate first. |
2379 map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind)); | 2396 map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind)); |
2380 } | 2397 } |
2381 reader->AddBackRef(object_id, &map, kIsDeserialized); | 2398 reader->AddBackRef(object_id, &map, kIsDeserialized); |
2382 // Set the object tags. | 2399 // Set the object tags. |
2383 map.set_tags(tags); | 2400 map.set_tags(tags); |
2384 | 2401 |
2385 // Read the type arguments. | 2402 // Read the type arguments. |
2386 intptr_t typeargs_offset = | 2403 const intptr_t typeargs_offset = |
2387 reinterpret_cast<RawObject**>(&map.raw()->ptr()->type_arguments_) - | 2404 GrowableObjectArray::type_arguments_offset() / kWordSize; |
2388 reinterpret_cast<RawObject**>(map.raw()->ptr()); | |
2389 *reader->TypeArgumentsHandle() ^= | 2405 *reader->TypeArgumentsHandle() ^= |
2390 reader->ReadObjectImpl(kAsInlinedObject, object_id, typeargs_offset); | 2406 reader->ReadObjectImpl(kAsInlinedObject, object_id, typeargs_offset); |
2391 map.SetTypeArguments(*reader->TypeArgumentsHandle()); | 2407 map.SetTypeArguments(*reader->TypeArgumentsHandle()); |
2392 | 2408 |
2393 // Read the number of key/value pairs. | 2409 // Read the number of key/value pairs. |
2394 intptr_t len = reader->ReadSmiValue(); | 2410 intptr_t len = reader->ReadSmiValue(); |
2395 intptr_t used_data = (len << 1); | 2411 intptr_t used_data = (len << 1); |
2396 map.SetUsedData(used_data); | 2412 map.SetUsedData(used_data); |
2397 | 2413 |
2398 // Allocate the data array. | 2414 // Allocate the data array. |
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3102 // We do not allow objects with native fields in an isolate message. | 3118 // We do not allow objects with native fields in an isolate message. |
3103 writer->SetWriteException(Exceptions::kArgument, | 3119 writer->SetWriteException(Exceptions::kArgument, |
3104 "Illegal argument in isolate message" | 3120 "Illegal argument in isolate message" |
3105 " : (object is a UserTag)"); | 3121 " : (object is a UserTag)"); |
3106 } else { | 3122 } else { |
3107 UNREACHABLE(); | 3123 UNREACHABLE(); |
3108 } | 3124 } |
3109 } | 3125 } |
3110 | 3126 |
3111 } // namespace dart | 3127 } // namespace dart |
OLD | NEW |