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 |