Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(810)

Side by Side Diff: runtime/vm/snapshot.cc

Issue 982723002: Fix for issue 20992 - Allow sending static/top-level functions to other isolates which are spawned … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_ids.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_ids.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698