| 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/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 str_ ^= ReadObjectImpl(); | 230 str_ ^= ReadObjectImpl(); |
| 231 cls = library_.LookupClass(str_); | 231 cls = library_.LookupClass(str_); |
| 232 if (cls.IsNull()) { | 232 if (cls.IsNull()) { |
| 233 SetReadException("Invalid object found in message."); | 233 SetReadException("Invalid object found in message."); |
| 234 } | 234 } |
| 235 cls.EnsureIsFinalized(isolate()); | 235 cls.EnsureIsFinalized(isolate()); |
| 236 return cls.raw(); | 236 return cls.raw(); |
| 237 } | 237 } |
| 238 | 238 |
| 239 | 239 |
| 240 RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id, |
| 241 intptr_t class_header) { |
| 242 ASSERT(kind_ == Snapshot::kMessage); |
| 243 |
| 244 // First create a function object and associate it with the specified |
| 245 // 'object_id'. |
| 246 Function& func = Function::ZoneHandle(isolate(), Function::null()); |
| 247 AddBackRef(object_id, &func, kIsDeserialized); |
| 248 |
| 249 // Read the library/class/function information and lookup the function. |
| 250 str_ ^= ReadObjectImpl(); |
| 251 library_ = Library::LookupLibrary(str_); |
| 252 if (library_.IsNull() || !library_.Loaded()) { |
| 253 SetReadException("Invalid Library object found in message."); |
| 254 } |
| 255 str_ ^= ReadObjectImpl(); |
| 256 if (str_.Equals(Symbols::TopLevel())) { |
| 257 str_ ^= ReadObjectImpl(); |
| 258 func = library_.LookupFunctionAllowPrivate(str_); |
| 259 } else { |
| 260 cls_ = library_.LookupClassAllowPrivate(str_); |
| 261 if (cls_.IsNull()) { |
| 262 OS::Print("Name of class not found %s\n", str_.ToCString()); |
| 263 SetReadException("Invalid Class object found in message."); |
| 264 } |
| 265 cls_.EnsureIsFinalized(isolate()); |
| 266 str_ ^= ReadObjectImpl(); |
| 267 func = cls_.LookupFunctionAllowPrivate(str_); |
| 268 } |
| 269 if (func.IsNull()) { |
| 270 SetReadException("Invalid function object found in message."); |
| 271 } |
| 272 func = func.ImplicitClosureFunction(); |
| 273 ASSERT(!func.IsNull()); |
| 274 |
| 275 // Return the associated implicit static closure. |
| 276 return func.ImplicitStaticClosure(); |
| 277 } |
| 278 |
| 279 |
| 240 RawObject* SnapshotReader::ReadObjectImpl() { | 280 RawObject* SnapshotReader::ReadObjectImpl() { |
| 241 int64_t value = Read<int64_t>(); | 281 int64_t value = Read<int64_t>(); |
| 242 if ((value & kSmiTagMask) == kSmiTag) { | 282 if ((value & kSmiTagMask) == kSmiTag) { |
| 243 return NewInteger(value); | 283 return NewInteger(value); |
| 244 } | 284 } |
| 245 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | 285 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); |
| 246 return ReadObjectImpl(static_cast<intptr_t>(value)); | 286 return ReadObjectImpl(static_cast<intptr_t>(value)); |
| 247 } | 287 } |
| 248 | 288 |
| 249 | 289 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 object_id = NextAvailableObjectId(); | 345 object_id = NextAvailableObjectId(); |
| 306 } | 346 } |
| 307 ASSERT(GetBackRef(object_id) == NULL); | 347 ASSERT(GetBackRef(object_id) == NULL); |
| 308 | 348 |
| 309 // Read the class header information and lookup the class. | 349 // Read the class header information and lookup the class. |
| 310 intptr_t class_header = Read<int32_t>(); | 350 intptr_t class_header = Read<int32_t>(); |
| 311 | 351 |
| 312 // Since we are only reading an object reference, If it is an instance kind | 352 // Since we are only reading an object reference, If it is an instance kind |
| 313 // then we only need to figure out the class of the object and allocate an | 353 // then we only need to figure out the class of the object and allocate an |
| 314 // instance of it. The individual fields will be read later. | 354 // instance of it. The individual fields will be read later. |
| 315 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) { | 355 intptr_t header_id = SerializedHeaderData::decode(class_header); |
| 356 if (header_id == kInstanceObjectId) { |
| 316 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); | 357 Instance& result = Instance::ZoneHandle(isolate(), Instance::null()); |
| 317 AddBackRef(object_id, &result, kIsNotDeserialized); | 358 AddBackRef(object_id, &result, kIsNotDeserialized); |
| 318 | 359 |
| 319 cls_ ^= ReadObjectImpl(); // Read class information. | 360 cls_ ^= ReadObjectImpl(); // Read class information. |
| 320 ASSERT(!cls_.IsNull()); | 361 ASSERT(!cls_.IsNull()); |
| 321 intptr_t instance_size = cls_.instance_size(); | 362 intptr_t instance_size = cls_.instance_size(); |
| 322 ASSERT(instance_size > 0); | 363 ASSERT(instance_size > 0); |
| 323 if (kind_ == Snapshot::kFull) { | 364 if (kind_ == Snapshot::kFull) { |
| 324 result ^= AllocateUninitialized(cls_.id(), instance_size); | 365 result ^= AllocateUninitialized(cls_.id(), instance_size); |
| 325 } else { | 366 } else { |
| 326 result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); | 367 result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); |
| 327 } | 368 } |
| 328 return result.raw(); | 369 return result.raw(); |
| 370 } else if (header_id == kStaticImplicitClosureObjectId) { |
| 371 // We skip the tags that have been written as the implicit static |
| 372 // closure is going to be created in this isolate or the canonical |
| 373 // version already created in the isolate will be used. |
| 374 ReadTags(); |
| 375 return ReadStaticImplicitClosure(object_id, class_header); |
| 329 } | 376 } |
| 330 ASSERT((class_header & kSmiTagMask) != kSmiTag); | 377 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 331 | 378 |
| 332 // Similarly Array and ImmutableArray objects are also similarly only | 379 // Similarly Array and ImmutableArray objects are also similarly only |
| 333 // allocated here, the individual array elements are read later. | 380 // allocated here, the individual array elements are read later. |
| 334 intptr_t class_id = LookupInternalClass(class_header); | 381 intptr_t class_id = LookupInternalClass(class_header); |
| 335 if (class_id == kArrayCid) { | 382 if (class_id == kArrayCid) { |
| 336 // Read the length and allocate an object based on the len. | 383 // Read the length and allocate an object based on the len. |
| 337 intptr_t len = ReadSmiValue(); | 384 intptr_t len = ReadSmiValue(); |
| 338 Array& array = Array::ZoneHandle( | 385 Array& array = Array::ZoneHandle( |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 } | 977 } |
| 931 Object* object = GetBackRef(object_id); | 978 Object* object = GetBackRef(object_id); |
| 932 return object->raw(); | 979 return object->raw(); |
| 933 } | 980 } |
| 934 | 981 |
| 935 | 982 |
| 936 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) { | 983 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) { |
| 937 // Read the class header information and lookup the class. | 984 // Read the class header information and lookup the class. |
| 938 intptr_t class_header = Read<int32_t>(); | 985 intptr_t class_header = Read<int32_t>(); |
| 939 intptr_t tags = ReadTags(); | 986 intptr_t tags = ReadTags(); |
| 940 if (SerializedHeaderData::decode(class_header) == kInstanceObjectId) { | 987 intptr_t header_id = SerializedHeaderData::decode(class_header); |
| 988 if (header_id == kInstanceObjectId) { |
| 941 // Object is regular dart instance. | 989 // Object is regular dart instance. |
| 942 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); | 990 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); |
| 943 intptr_t instance_size = 0; | 991 intptr_t instance_size = 0; |
| 944 if (result == NULL) { | 992 if (result == NULL) { |
| 945 result = &(Instance::ZoneHandle(isolate(), Instance::null())); | 993 result = &(Instance::ZoneHandle(isolate(), Instance::null())); |
| 946 AddBackRef(object_id, result, kIsDeserialized); | 994 AddBackRef(object_id, result, kIsDeserialized); |
| 947 cls_ ^= ReadObjectImpl(); | 995 cls_ ^= ReadObjectImpl(); |
| 948 ASSERT(!cls_.IsNull()); | 996 ASSERT(!cls_.IsNull()); |
| 949 instance_size = cls_.instance_size(); | 997 instance_size = cls_.instance_size(); |
| 950 ASSERT(instance_size > 0); | 998 ASSERT(instance_size > 0); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 995 while (offset < instance_size) { | 1043 while (offset < instance_size) { |
| 996 result->SetFieldAtOffset(offset, Object::null_object()); | 1044 result->SetFieldAtOffset(offset, Object::null_object()); |
| 997 offset += kWordSize; | 1045 offset += kWordSize; |
| 998 } | 1046 } |
| 999 result->SetCreatedFromSnapshot(); | 1047 result->SetCreatedFromSnapshot(); |
| 1000 } else if (RawObject::IsCanonical(tags)) { | 1048 } else if (RawObject::IsCanonical(tags)) { |
| 1001 *result = result->CheckAndCanonicalize(NULL); | 1049 *result = result->CheckAndCanonicalize(NULL); |
| 1002 ASSERT(!result->IsNull()); | 1050 ASSERT(!result->IsNull()); |
| 1003 } | 1051 } |
| 1004 return result->raw(); | 1052 return result->raw(); |
| 1053 } else if (header_id == kStaticImplicitClosureObjectId) { |
| 1054 // We do not use the tags as the implicit static closure |
| 1055 // is going to be created in this isolate or the canonical |
| 1056 // version already created in the isolate will be used. |
| 1057 return ReadStaticImplicitClosure(object_id, class_header); |
| 1005 } | 1058 } |
| 1006 ASSERT((class_header & kSmiTagMask) != kSmiTag); | 1059 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 1007 intptr_t class_id = LookupInternalClass(class_header); | 1060 intptr_t class_id = LookupInternalClass(class_header); |
| 1008 switch (class_id) { | 1061 switch (class_id) { |
| 1009 #define SNAPSHOT_READ(clazz) \ | 1062 #define SNAPSHOT_READ(clazz) \ |
| 1010 case clazz::kClassId: { \ | 1063 case clazz::kClassId: { \ |
| 1011 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ | 1064 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ |
| 1012 break; \ | 1065 break; \ |
| 1013 } | 1066 } |
| 1014 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) | 1067 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 | 1261 |
| 1209 // Write out the length field. | 1262 // Write out the length field. |
| 1210 Write<RawObject*>(rawarray->ptr()->length_); | 1263 Write<RawObject*>(rawarray->ptr()->length_); |
| 1211 | 1264 |
| 1212 return; | 1265 return; |
| 1213 } | 1266 } |
| 1214 if (RawObject::IsImplicitFieldClassId(class_id)) { | 1267 if (RawObject::IsImplicitFieldClassId(class_id)) { |
| 1215 WriteInstanceRef(raw, cls); | 1268 WriteInstanceRef(raw, cls); |
| 1216 return; | 1269 return; |
| 1217 } | 1270 } |
| 1218 // Object is being referenced, add it to the forward ref list and mark | 1271 // Add object to the forward ref list and mark it so that future references |
| 1219 // it so that future references to this object in the snapshot will use | 1272 // to this object in the snapshot will use this object id. Mark it as having |
| 1220 // this object id. Mark it as not having been serialized yet so that we | 1273 // been serialized so that we do not serialize the object when we go through |
| 1221 // will serialize the object when we go through the forward list. | 1274 // the forward list. |
| 1222 forward_list_.MarkAndAddObject(raw, kIsSerialized); | 1275 forward_list_.MarkAndAddObject(raw, kIsSerialized); |
| 1223 switch (class_id) { | 1276 switch (class_id) { |
| 1224 #define SNAPSHOT_WRITE(clazz) \ | 1277 #define SNAPSHOT_WRITE(clazz) \ |
| 1225 case clazz::kClassId: { \ | 1278 case clazz::kClassId: { \ |
| 1226 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ | 1279 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ |
| 1227 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ | 1280 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ |
| 1228 return; \ | 1281 return; \ |
| 1229 } \ | 1282 } \ |
| 1230 | 1283 |
| 1231 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) | 1284 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 WriteTags(GetObjectTags(cls)); | 1638 WriteTags(GetObjectTags(cls)); |
| 1586 | 1639 |
| 1587 // Write out the library url and class name. | 1640 // Write out the library url and class name. |
| 1588 RawLibrary* library = cls->ptr()->library_; | 1641 RawLibrary* library = cls->ptr()->library_; |
| 1589 ASSERT(library != Library::null()); | 1642 ASSERT(library != Library::null()); |
| 1590 WriteObjectImpl(library->ptr()->url_); | 1643 WriteObjectImpl(library->ptr()->url_); |
| 1591 WriteObjectImpl(cls->ptr()->name_); | 1644 WriteObjectImpl(cls->ptr()->name_); |
| 1592 } | 1645 } |
| 1593 | 1646 |
| 1594 | 1647 |
| 1648 void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id, |
| 1649 RawFunction* func, |
| 1650 intptr_t tags) { |
| 1651 // Write out the serialization header value for this object. |
| 1652 WriteInlinedObjectHeader(object_id); |
| 1653 |
| 1654 // Indicate this is a static implicit closure object. |
| 1655 Write<int32_t>(SerializedHeaderData::encode(kStaticImplicitClosureObjectId)); |
| 1656 |
| 1657 // Write out the tags. |
| 1658 WriteTags(tags); |
| 1659 |
| 1660 // Write out the library url, class name and signature function name. |
| 1661 RawClass* cls = GetFunctionOwner(func); |
| 1662 ASSERT(cls != Class::null()); |
| 1663 RawLibrary* library = cls->ptr()->library_; |
| 1664 ASSERT(library != Library::null()); |
| 1665 WriteObjectImpl(library->ptr()->url_); |
| 1666 WriteObjectImpl(cls->ptr()->name_); |
| 1667 WriteObjectImpl(func->ptr()->name_); |
| 1668 } |
| 1669 |
| 1670 |
| 1595 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, | 1671 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, |
| 1596 intptr_t array_kind, | 1672 intptr_t array_kind, |
| 1597 intptr_t tags, | 1673 intptr_t tags, |
| 1598 RawSmi* length, | 1674 RawSmi* length, |
| 1599 RawTypeArguments* type_arguments, | 1675 RawTypeArguments* type_arguments, |
| 1600 RawObject* data[]) { | 1676 RawObject* data[]) { |
| 1601 intptr_t len = Smi::Value(length); | 1677 intptr_t len = Smi::Value(length); |
| 1602 | 1678 |
| 1603 // Write out the serialization header value for this object. | 1679 // Write out the serialization header value for this object. |
| 1604 WriteInlinedObjectHeader(object_id); | 1680 WriteInlinedObjectHeader(object_id); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1618 for (intptr_t i = 0; i < len; i++) { | 1694 for (intptr_t i = 0; i < len; i++) { |
| 1619 if (is_canonical) { | 1695 if (is_canonical) { |
| 1620 WriteObjectImpl(data[i]); | 1696 WriteObjectImpl(data[i]); |
| 1621 } else { | 1697 } else { |
| 1622 WriteObjectRef(data[i]); | 1698 WriteObjectRef(data[i]); |
| 1623 } | 1699 } |
| 1624 } | 1700 } |
| 1625 } | 1701 } |
| 1626 | 1702 |
| 1627 | 1703 |
| 1628 void SnapshotWriter::CheckIfSerializable(RawClass* cls) { | 1704 RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls, |
| 1705 RawObject* obj) { |
| 1629 if (Class::IsSignatureClass(cls)) { | 1706 if (Class::IsSignatureClass(cls)) { |
| 1630 // We do not allow closure objects in an isolate message. | 1707 // 'obj' is a closure as its class is a signature class, extract |
| 1631 Isolate* isolate = Isolate::Current(); | 1708 // the function object to check if this closure can be sent in an |
| 1632 HANDLESCOPE(isolate); | 1709 // isolate message. |
| 1710 RawFunction* func = Closure::GetFunction(obj); |
| 1711 // We only allow closure of top level methods or static functions in a |
| 1712 // class to be sent in isolate messages. |
| 1713 if (can_send_any_object() && |
| 1714 Function::IsImplicitStaticClosureFunction(func)) { |
| 1715 return func; |
| 1716 } |
| 1717 // Not a closure of a top level method or static function, throw an |
| 1718 // exception as we do not allow these objects to be serialized. |
| 1719 HANDLESCOPE(isolate()); |
| 1720 |
| 1721 const Class& clazz = Class::Handle(isolate(), cls); |
| 1722 const Function& errorFunc = Function::Handle(isolate(), func); |
| 1723 ASSERT(!errorFunc.IsNull()); |
| 1724 |
| 1725 // All other closures are errors. |
| 1633 const char* format = "Illegal argument in isolate message" | 1726 const char* format = "Illegal argument in isolate message" |
| 1634 " : (object is a closure - %s %s)"; | 1727 " : (object is a closure - %s %s)"; |
| 1635 UnmarkAll(); // Unmark objects now as we are about to print stuff. | 1728 UnmarkAll(); // Unmark objects now as we are about to print stuff. |
| 1636 const Class& clazz = Class::Handle(isolate, cls); | |
| 1637 const Function& func = Function::Handle(isolate, | |
| 1638 clazz.signature_function()); | |
| 1639 ASSERT(!func.IsNull()); | |
| 1640 intptr_t len = OS::SNPrint(NULL, 0, format, | 1729 intptr_t len = OS::SNPrint(NULL, 0, format, |
| 1641 clazz.ToCString(), func.ToCString()) + 1; | 1730 clazz.ToCString(), errorFunc.ToCString()) + 1; |
| 1642 char* chars = isolate->current_zone()->Alloc<char>(len); | 1731 char* chars = isolate()->current_zone()->Alloc<char>(len); |
| 1643 OS::SNPrint(chars, len, format, clazz.ToCString(), func.ToCString()); | 1732 OS::SNPrint(chars, len, format, clazz.ToCString(), errorFunc.ToCString()); |
| 1644 SetWriteException(Exceptions::kArgument, chars); | 1733 SetWriteException(Exceptions::kArgument, chars); |
| 1645 } | 1734 } |
| 1735 return Function::null(); |
| 1736 } |
| 1737 |
| 1738 |
| 1739 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { |
| 1740 RawObject* owner = func->ptr()->owner_; |
| 1741 uword tags = GetObjectTags(owner); |
| 1742 intptr_t class_id = RawObject::ClassIdTag::decode(tags); |
| 1743 if (class_id == kClassCid) { |
| 1744 return reinterpret_cast<RawClass*>(owner); |
| 1745 } |
| 1746 ASSERT(class_id == kPatchClassCid); |
| 1747 return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_; |
| 1748 } |
| 1749 |
| 1750 |
| 1751 void SnapshotWriter::CheckForNativeFields(RawClass* cls) { |
| 1646 if (cls->ptr()->num_native_fields_ != 0) { | 1752 if (cls->ptr()->num_native_fields_ != 0) { |
| 1647 // We do not allow objects with native fields in an isolate message. | 1753 // We do not allow objects with native fields in an isolate message. |
| 1648 Isolate* isolate = Isolate::Current(); | 1754 HANDLESCOPE(isolate()); |
| 1649 HANDLESCOPE(Isolate::Current()); | |
| 1650 const char* format = "Illegal argument in isolate message" | 1755 const char* format = "Illegal argument in isolate message" |
| 1651 " : (object extends NativeWrapper - %s)"; | 1756 " : (object extends NativeWrapper - %s)"; |
| 1652 UnmarkAll(); // Unmark objects now as we are about to print stuff. | 1757 UnmarkAll(); // Unmark objects now as we are about to print stuff. |
| 1653 const Class& clazz = Class::Handle(isolate, cls); | 1758 const Class& clazz = Class::Handle(isolate(), cls); |
| 1654 intptr_t len = OS::SNPrint(NULL, 0, format, clazz.ToCString()) + 1; | 1759 intptr_t len = OS::SNPrint(NULL, 0, format, clazz.ToCString()) + 1; |
| 1655 char* chars = isolate->current_zone()->Alloc<char>(len); | 1760 char* chars = isolate()->current_zone()->Alloc<char>(len); |
| 1656 OS::SNPrint(chars, len, format, clazz.ToCString()); | 1761 OS::SNPrint(chars, len, format, clazz.ToCString()); |
| 1657 SetWriteException(Exceptions::kArgument, chars); | 1762 SetWriteException(Exceptions::kArgument, chars); |
| 1658 } | 1763 } |
| 1659 } | 1764 } |
| 1660 | 1765 |
| 1661 | 1766 |
| 1662 void SnapshotWriter::SetWriteException(Exceptions::ExceptionType type, | 1767 void SnapshotWriter::SetWriteException(Exceptions::ExceptionType type, |
| 1663 const char* msg) { | 1768 const char* msg) { |
| 1664 set_exception_type(type); | 1769 set_exception_type(type); |
| 1665 set_exception_msg(msg); | 1770 set_exception_msg(msg); |
| 1666 // The more specific error is set up in SnapshotWriter::ThrowException(). | 1771 // The more specific error is set up in SnapshotWriter::ThrowException(). |
| 1667 isolate()->long_jump_base()-> | 1772 isolate()->long_jump_base()-> |
| 1668 Jump(1, Object::snapshot_writer_error()); | 1773 Jump(1, Object::snapshot_writer_error()); |
| 1669 } | 1774 } |
| 1670 | 1775 |
| 1671 | 1776 |
| 1672 void SnapshotWriter::WriteInstance(intptr_t object_id, | 1777 void SnapshotWriter::WriteInstance(intptr_t object_id, |
| 1673 RawObject* raw, | 1778 RawObject* raw, |
| 1674 RawClass* cls, | 1779 RawClass* cls, |
| 1675 intptr_t tags) { | 1780 intptr_t tags) { |
| 1676 // First check if object is a closure or has native fields. | 1781 // Check if the instance has native fields and throw an exception if it does. |
| 1677 CheckIfSerializable(cls); | 1782 CheckForNativeFields(cls); |
| 1783 |
| 1784 // Check if object is a closure that is serializable, if the object is a |
| 1785 // closure that is not serializable this will throw an exception. |
| 1786 RawFunction* func = IsSerializableClosure(cls, raw); |
| 1787 if (func != Function::null()) { |
| 1788 WriteStaticImplicitClosure(object_id, func, tags); |
| 1789 return; |
| 1790 } |
| 1678 | 1791 |
| 1679 // Object is regular dart instance. | 1792 // Object is regular dart instance. |
| 1680 intptr_t next_field_offset = | 1793 intptr_t next_field_offset = Class::IsSignatureClass(cls) ? |
| 1794 Closure::InstanceSize() : |
| 1681 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; | 1795 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; |
| 1682 ASSERT(next_field_offset > 0); | 1796 ASSERT(next_field_offset > 0); |
| 1683 | 1797 |
| 1684 // Write out the serialization header value for this object. | 1798 // Write out the serialization header value for this object. |
| 1685 WriteInlinedObjectHeader(object_id); | 1799 WriteInlinedObjectHeader(object_id); |
| 1686 | 1800 |
| 1687 // Indicate this is an instance object. | 1801 // Indicate this is an instance object. |
| 1688 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 1802 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
| 1689 | 1803 |
| 1690 // Write out the tags. | 1804 // Write out the tags. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1706 } else { | 1820 } else { |
| 1707 WriteObjectRef(raw_obj); | 1821 WriteObjectRef(raw_obj); |
| 1708 } | 1822 } |
| 1709 offset += kWordSize; | 1823 offset += kWordSize; |
| 1710 } | 1824 } |
| 1711 return; | 1825 return; |
| 1712 } | 1826 } |
| 1713 | 1827 |
| 1714 | 1828 |
| 1715 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { | 1829 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { |
| 1716 // First check if object is a closure or has native fields. | 1830 // Check if the instance has native fields and throw an exception if it does. |
| 1717 CheckIfSerializable(cls); | 1831 CheckForNativeFields(cls); |
| 1832 |
| 1833 // Check if object is a closure that is serializable, if the object is a |
| 1834 // closure that is not serializable this will throw an exception. |
| 1835 RawFunction* func = IsSerializableClosure(cls, raw); |
| 1836 if (func != Function::null()) { |
| 1837 // Add object to the forward ref list and mark it so that future references |
| 1838 // to this object in the snapshot will use this object id. Mark it as having |
| 1839 // been serialized so that we do not serialize the object when we go through |
| 1840 // the forward list. |
| 1841 forward_list_.MarkAndAddObject(raw, kIsSerialized); |
| 1842 uword tags = raw->ptr()->tags_; |
| 1843 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
| 1844 intptr_t object_id = SerializedHeaderData::decode(tags); |
| 1845 tags = forward_list_.NodeForObjectId(object_id)->tags(); |
| 1846 WriteStaticImplicitClosure(object_id, func, tags); |
| 1847 return; |
| 1848 } |
| 1718 | 1849 |
| 1719 // Object is being referenced, add it to the forward ref list and mark | 1850 // Object is being referenced, add it to the forward ref list and mark |
| 1720 // it so that future references to this object in the snapshot will use | 1851 // it so that future references to this object in the snapshot will use |
| 1721 // this object id. Mark it as not having been serialized yet so that we | 1852 // this object id. Mark it as not having been serialized yet so that we |
| 1722 // will serialize the object when we go through the forward list. | 1853 // will serialize the object when we go through the forward list. |
| 1723 forward_list_.MarkAndAddObject(raw, kIsNotSerialized); | 1854 forward_list_.MarkAndAddObject(raw, kIsNotSerialized); |
| 1724 | 1855 |
| 1725 // Write out the serialization header value for this object. | 1856 // Write out the serialization header value for this object. |
| 1726 WriteInlinedObjectHeader(kOmittedObjectId); | 1857 WriteInlinedObjectHeader(kOmittedObjectId); |
| 1727 | 1858 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1817 NoGCScope no_gc; | 1948 NoGCScope no_gc; |
| 1818 WriteObject(obj.raw()); | 1949 WriteObject(obj.raw()); |
| 1819 UnmarkAll(); | 1950 UnmarkAll(); |
| 1820 } else { | 1951 } else { |
| 1821 ThrowException(exception_type(), exception_msg()); | 1952 ThrowException(exception_type(), exception_msg()); |
| 1822 } | 1953 } |
| 1823 } | 1954 } |
| 1824 | 1955 |
| 1825 | 1956 |
| 1826 } // namespace dart | 1957 } // namespace dart |
| OLD | NEW |