| 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 |