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.h" | 10 #include "vm/dart.h" |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 result = reinterpret_cast<Instance*>(GetBackRef(object_id)); | 473 result = reinterpret_cast<Instance*>(GetBackRef(object_id)); |
474 state = kIsDeserialized; | 474 state = kIsDeserialized; |
475 } else { | 475 } else { |
476 state = kIsNotDeserialized; | 476 state = kIsNotDeserialized; |
477 } | 477 } |
478 if (result == NULL) { | 478 if (result == NULL) { |
479 result = &(Instance::ZoneHandle(zone(), Instance::null())); | 479 result = &(Instance::ZoneHandle(zone(), Instance::null())); |
480 AddBackRef(object_id, result, state); | 480 AddBackRef(object_id, result, state); |
481 cls_ ^= ReadObjectImpl(kAsInlinedObject); | 481 cls_ ^= ReadObjectImpl(kAsInlinedObject); |
482 ASSERT(!cls_.IsNull()); | 482 ASSERT(!cls_.IsNull()); |
| 483 // Closure instances are handled by Closure::ReadFrom(). |
| 484 ASSERT(!cls_.IsClosureClass()); |
483 instance_size = cls_.instance_size(); | 485 instance_size = cls_.instance_size(); |
484 ASSERT(instance_size > 0); | 486 ASSERT(instance_size > 0); |
485 // Allocate the instance and read in all the fields for the object. | 487 // Allocate the instance and read in all the fields for the object. |
486 if (kind_ == Snapshot::kFull) { | 488 if (kind_ == Snapshot::kFull) { |
487 *result ^= AllocateUninitialized(cls_.id(), instance_size); | 489 *result ^= AllocateUninitialized(cls_.id(), instance_size); |
488 } else { | 490 } else { |
489 *result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); | 491 *result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); |
490 } | 492 } |
491 } else { | 493 } else { |
492 cls_ ^= ReadObjectImpl(kAsInlinedObject); | 494 cls_ ^= ReadObjectImpl(kAsInlinedObject); |
493 ASSERT(!cls_.IsNull()); | 495 ASSERT(!cls_.IsNull()); |
494 instance_size = cls_.instance_size(); | 496 instance_size = cls_.instance_size(); |
495 } | 497 } |
496 if (!as_reference) { | 498 if (!as_reference) { |
497 // Read all the individual fields for inlined objects. | 499 // Read all the individual fields for inlined objects. |
498 intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw()) | 500 intptr_t next_field_offset = cls_.next_field_offset(); |
499 ? Closure::InstanceSize() : cls_.next_field_offset(); | |
500 | 501 |
501 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); | 502 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
502 ASSERT(next_field_offset > 0); | 503 ASSERT(next_field_offset > 0); |
503 // Instance::NextFieldOffset() returns the offset of the first field in | 504 // Instance::NextFieldOffset() returns the offset of the first field in |
504 // a Dart object. | 505 // a Dart object. |
505 bool read_as_reference = RawObject::IsCanonical(tags) ? false : true; | 506 bool read_as_reference = RawObject::IsCanonical(tags) ? false : true; |
506 intptr_t offset = Instance::NextFieldOffset(); | 507 intptr_t offset = Instance::NextFieldOffset(); |
507 intptr_t result_cid = result->GetClassId(); | 508 intptr_t result_cid = result->GetClassId(); |
508 while (offset < next_field_offset) { | 509 while (offset < next_field_offset) { |
509 pobj_ = ReadObjectImpl(read_as_reference); | 510 pobj_ = ReadObjectImpl(read_as_reference); |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 RawUnresolvedClass* SnapshotReader::NewUnresolvedClass() { | 915 RawUnresolvedClass* SnapshotReader::NewUnresolvedClass() { |
915 ALLOC_NEW_OBJECT(UnresolvedClass); | 916 ALLOC_NEW_OBJECT(UnresolvedClass); |
916 } | 917 } |
917 | 918 |
918 | 919 |
919 RawType* SnapshotReader::NewType() { | 920 RawType* SnapshotReader::NewType() { |
920 ALLOC_NEW_OBJECT(Type); | 921 ALLOC_NEW_OBJECT(Type); |
921 } | 922 } |
922 | 923 |
923 | 924 |
| 925 RawFunctionType* SnapshotReader::NewFunctionType() { |
| 926 ALLOC_NEW_OBJECT(FunctionType); |
| 927 } |
| 928 |
| 929 |
924 RawTypeRef* SnapshotReader::NewTypeRef() { | 930 RawTypeRef* SnapshotReader::NewTypeRef() { |
925 ALLOC_NEW_OBJECT(TypeRef); | 931 ALLOC_NEW_OBJECT(TypeRef); |
926 } | 932 } |
927 | 933 |
928 | 934 |
929 RawTypeParameter* SnapshotReader::NewTypeParameter() { | 935 RawTypeParameter* SnapshotReader::NewTypeParameter() { |
930 ALLOC_NEW_OBJECT(TypeParameter); | 936 ALLOC_NEW_OBJECT(TypeParameter); |
931 } | 937 } |
932 | 938 |
933 | 939 |
934 RawBoundedType* SnapshotReader::NewBoundedType() { | 940 RawBoundedType* SnapshotReader::NewBoundedType() { |
935 ALLOC_NEW_OBJECT(BoundedType); | 941 ALLOC_NEW_OBJECT(BoundedType); |
936 } | 942 } |
937 | 943 |
938 | 944 |
939 RawMixinAppType* SnapshotReader::NewMixinAppType() { | 945 RawMixinAppType* SnapshotReader::NewMixinAppType() { |
940 ALLOC_NEW_OBJECT(MixinAppType); | 946 ALLOC_NEW_OBJECT(MixinAppType); |
941 } | 947 } |
942 | 948 |
943 | 949 |
944 RawPatchClass* SnapshotReader::NewPatchClass() { | 950 RawPatchClass* SnapshotReader::NewPatchClass() { |
945 ALLOC_NEW_OBJECT(PatchClass); | 951 ALLOC_NEW_OBJECT(PatchClass); |
946 } | 952 } |
947 | 953 |
948 | 954 |
| 955 RawClosure* SnapshotReader::NewClosure() { |
| 956 ALLOC_NEW_OBJECT(Closure); |
| 957 } |
| 958 |
| 959 |
949 RawClosureData* SnapshotReader::NewClosureData() { | 960 RawClosureData* SnapshotReader::NewClosureData() { |
950 ALLOC_NEW_OBJECT(ClosureData); | 961 ALLOC_NEW_OBJECT(ClosureData); |
951 } | 962 } |
952 | 963 |
953 | 964 |
954 RawRedirectionData* SnapshotReader::NewRedirectionData() { | 965 RawRedirectionData* SnapshotReader::NewRedirectionData() { |
955 ALLOC_NEW_OBJECT(RedirectionData); | 966 ALLOC_NEW_OBJECT(RedirectionData); |
956 } | 967 } |
957 | 968 |
958 | 969 |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 index -= max_vm_isolate_object_id_; | 1393 index -= max_vm_isolate_object_id_; |
1383 ASSERT(index < backward_references_->length()); | 1394 ASSERT(index < backward_references_->length()); |
1384 BackRefNode& ref = (*backward_references_)[index]; | 1395 BackRefNode& ref = (*backward_references_)[index]; |
1385 ref.AddPatchRecord(patch_object_id, patch_offset); | 1396 ref.AddPatchRecord(patch_object_id, patch_offset); |
1386 } | 1397 } |
1387 } | 1398 } |
1388 | 1399 |
1389 | 1400 |
1390 void SnapshotReader::ProcessDeferredCanonicalizations() { | 1401 void SnapshotReader::ProcessDeferredCanonicalizations() { |
1391 Type& typeobj = Type::Handle(); | 1402 Type& typeobj = Type::Handle(); |
| 1403 FunctionType& funtypeobj = FunctionType::Handle(); |
1392 TypeArguments& typeargs = TypeArguments::Handle(); | 1404 TypeArguments& typeargs = TypeArguments::Handle(); |
1393 Object& newobj = Object::Handle(); | 1405 Object& newobj = Object::Handle(); |
1394 for (intptr_t i = 0; i < backward_references_->length(); i++) { | 1406 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
1395 BackRefNode& backref = (*backward_references_)[i]; | 1407 BackRefNode& backref = (*backward_references_)[i]; |
1396 if (backref.defer_canonicalization()) { | 1408 if (backref.defer_canonicalization()) { |
1397 Object* objref = backref.reference(); | 1409 Object* objref = backref.reference(); |
1398 // Object should either be an abstract type or a type argument. | 1410 // Object should either be a type, a function type, or a type argument. |
1399 if (objref->IsType()) { | 1411 if (objref->IsType()) { |
1400 typeobj ^= objref->raw(); | 1412 typeobj ^= objref->raw(); |
1401 newobj = typeobj.Canonicalize(); | 1413 newobj = typeobj.Canonicalize(); |
| 1414 } else if (objref->IsFunctionType()) { |
| 1415 funtypeobj ^= objref->raw(); |
| 1416 newobj = funtypeobj.Canonicalize(); |
1402 } else { | 1417 } else { |
1403 ASSERT(objref->IsTypeArguments()); | 1418 ASSERT(objref->IsTypeArguments()); |
1404 typeargs ^= objref->raw(); | 1419 typeargs ^= objref->raw(); |
1405 newobj = typeargs.Canonicalize(); | 1420 newobj = typeargs.Canonicalize(); |
1406 } | 1421 } |
1407 if (newobj.raw() != objref->raw()) { | 1422 if (newobj.raw() != objref->raw()) { |
1408 ZoneGrowableArray<intptr_t>* patches = backref.patch_records(); | 1423 ZoneGrowableArray<intptr_t>* patches = backref.patch_records(); |
1409 ASSERT(newobj.IsCanonical()); | 1424 ASSERT(newobj.IsCanonical()); |
1410 ASSERT(patches != NULL); | 1425 ASSERT(patches != NULL); |
1411 // First we replace the back ref table with the canonical object. | 1426 // First we replace the back ref table with the canonical object. |
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2314 | 2329 |
2315 // Write out the individual object ids. | 2330 // Write out the individual object ids. |
2316 bool write_as_reference = RawObject::IsCanonical(tags) ? false : true; | 2331 bool write_as_reference = RawObject::IsCanonical(tags) ? false : true; |
2317 for (intptr_t i = 0; i < len; i++) { | 2332 for (intptr_t i = 0; i < len; i++) { |
2318 WriteObjectImpl(data[i], write_as_reference); | 2333 WriteObjectImpl(data[i], write_as_reference); |
2319 } | 2334 } |
2320 } | 2335 } |
2321 } | 2336 } |
2322 | 2337 |
2323 | 2338 |
2324 RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls, | 2339 RawFunction* SnapshotWriter::IsSerializableClosure(RawClosure* closure) { |
2325 RawObject* obj) { | 2340 // Extract the function object to check if this closure |
2326 if (Class::IsSignatureClass(cls)) { | 2341 // can be sent in an isolate message. |
2327 // 'obj' is a closure as its class is a signature class, extract | 2342 RawFunction* func = closure->ptr()->function_; |
2328 // the function object to check if this closure can be sent in an | 2343 // We only allow closure of top level methods or static functions in a |
2329 // isolate message. | 2344 // class to be sent in isolate messages. |
2330 RawFunction* func = Closure::GetFunction(obj); | 2345 if (can_send_any_object() && |
2331 // We only allow closure of top level methods or static functions in a | 2346 Function::IsImplicitStaticClosureFunction(func)) { |
2332 // class to be sent in isolate messages. | 2347 return func; |
2333 if (can_send_any_object() && | 2348 } |
2334 Function::IsImplicitStaticClosureFunction(func)) { | 2349 // Not a closure of a top level method or static function, throw an |
2335 return func; | 2350 // exception as we do not allow these objects to be serialized. |
2336 } | 2351 HANDLESCOPE(thread()); |
2337 // Not a closure of a top level method or static function, throw an | |
2338 // exception as we do not allow these objects to be serialized. | |
2339 HANDLESCOPE(thread()); | |
2340 | 2352 |
2341 const Class& clazz = Class::Handle(zone(), cls); | 2353 const Function& errorFunc = Function::Handle(zone(), func); |
2342 const Function& errorFunc = Function::Handle(zone(), func); | 2354 ASSERT(!errorFunc.IsNull()); |
2343 ASSERT(!errorFunc.IsNull()); | |
2344 | 2355 |
2345 // All other closures are errors. | 2356 // All other closures are errors. |
2346 char* chars = OS::SCreate(thread()->zone(), | 2357 char* chars = OS::SCreate(thread()->zone(), |
2347 "Illegal argument in isolate message : (object is a closure - %s %s)", | 2358 "Illegal argument in isolate message : (object is a closure - %s)", |
2348 clazz.ToCString(), errorFunc.ToCString()); | 2359 errorFunc.ToCString()); |
2349 SetWriteException(Exceptions::kArgument, chars); | 2360 SetWriteException(Exceptions::kArgument, chars); |
2350 } | |
2351 return Function::null(); | 2361 return Function::null(); |
2352 } | 2362 } |
2353 | 2363 |
2354 | 2364 |
2355 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { | 2365 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { |
2356 RawObject* owner = func->ptr()->owner_; | 2366 RawObject* owner = func->ptr()->owner_; |
2357 uword tags = GetObjectTags(owner); | 2367 uword tags = GetObjectTags(owner); |
2358 intptr_t class_id = RawObject::ClassIdTag::decode(tags); | 2368 intptr_t class_id = RawObject::ClassIdTag::decode(tags); |
2359 if (class_id == kClassCid) { | 2369 if (class_id == kClassCid) { |
2360 return reinterpret_cast<RawClass*>(owner); | 2370 return reinterpret_cast<RawClass*>(owner); |
(...skipping 25 matching lines...) Expand all Loading... |
2386 thread()->long_jump_base()-> | 2396 thread()->long_jump_base()-> |
2387 Jump(1, Object::snapshot_writer_error()); | 2397 Jump(1, Object::snapshot_writer_error()); |
2388 } | 2398 } |
2389 | 2399 |
2390 | 2400 |
2391 void SnapshotWriter::WriteInstance(RawObject* raw, | 2401 void SnapshotWriter::WriteInstance(RawObject* raw, |
2392 RawClass* cls, | 2402 RawClass* cls, |
2393 intptr_t tags, | 2403 intptr_t tags, |
2394 intptr_t object_id, | 2404 intptr_t object_id, |
2395 bool as_reference) { | 2405 bool as_reference) { |
| 2406 // Closure instances are handled by RawClosure::WriteTo(). |
| 2407 ASSERT(!Class::IsClosureClass(cls)); |
| 2408 |
2396 // Check if the instance has native fields and throw an exception if it does. | 2409 // Check if the instance has native fields and throw an exception if it does. |
2397 CheckForNativeFields(cls); | 2410 CheckForNativeFields(cls); |
2398 | 2411 |
2399 if ((kind() == Snapshot::kMessage) || (kind() == Snapshot::kScript)) { | |
2400 // Check if object is a closure that is serializable, if the object is a | |
2401 // closure that is not serializable this will throw an exception. | |
2402 RawFunction* func = IsSerializableClosure(cls, raw); | |
2403 if (func != Function::null()) { | |
2404 forward_list_->SetState(object_id, kIsSerialized); | |
2405 WriteStaticImplicitClosure(object_id, func, tags); | |
2406 return; | |
2407 } | |
2408 } | |
2409 | |
2410 // Object is regular dart instance. | 2412 // Object is regular dart instance. |
2411 if (as_reference) { | 2413 if (as_reference) { |
2412 // Write out the serialization header value for this object. | 2414 // Write out the serialization header value for this object. |
2413 WriteInlinedObjectHeader(kOmittedObjectId); | 2415 WriteInlinedObjectHeader(kOmittedObjectId); |
2414 | 2416 |
2415 // Indicate this is an instance object. | 2417 // Indicate this is an instance object. |
2416 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 2418 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
2417 WriteTags(tags); | 2419 WriteTags(tags); |
2418 | 2420 |
2419 // Write out the class information for this object. | 2421 // Write out the class information for this object. |
2420 WriteObjectImpl(cls, kAsInlinedObject); | 2422 WriteObjectImpl(cls, kAsInlinedObject); |
2421 } else { | 2423 } else { |
2422 intptr_t next_field_offset = Class::IsSignatureClass(cls) ? | 2424 intptr_t next_field_offset = |
2423 Closure::InstanceSize() : | |
2424 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; | 2425 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; |
2425 ASSERT(next_field_offset > 0); | 2426 ASSERT(next_field_offset > 0); |
2426 | 2427 |
2427 // Write out the serialization header value for this object. | 2428 // Write out the serialization header value for this object. |
2428 WriteInlinedObjectHeader(object_id); | 2429 WriteInlinedObjectHeader(object_id); |
2429 | 2430 |
2430 // Indicate this is an instance object. | 2431 // Indicate this is an instance object. |
2431 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 2432 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
2432 | 2433 |
2433 // Write out the tags. | 2434 // Write out the tags. |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2585 if (setjmp(*jump.Set()) == 0) { | 2586 if (setjmp(*jump.Set()) == 0) { |
2586 NoSafepointScope no_safepoint; | 2587 NoSafepointScope no_safepoint; |
2587 WriteObject(obj.raw()); | 2588 WriteObject(obj.raw()); |
2588 } else { | 2589 } else { |
2589 ThrowException(exception_type(), exception_msg()); | 2590 ThrowException(exception_type(), exception_msg()); |
2590 } | 2591 } |
2591 } | 2592 } |
2592 | 2593 |
2593 | 2594 |
2594 } // namespace dart | 2595 } // namespace dart |
OLD | NEW |