mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
1. Reclaim the CreatedFromSnapshot bit and use the bit to indicate VM heap object.
2. Cleanup calls to set_tags when reading objects from a snapshot. 3. Fixes issue 21816 R=regis@google.com Review URL: https://codereview.chromium.org//1221503004 .
This commit is contained in:
parent
2306fd2fcc
commit
e61f1dc8ce
|
@ -535,6 +535,7 @@ Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id,
|
|||
intptr_t object_id) {
|
||||
switch (class_id) {
|
||||
case kClassCid: {
|
||||
Read<bool>(); // Consume the is_in_fullsnapshot indicator.
|
||||
Dart_CObject_Internal* object = AllocateDartCObjectClass();
|
||||
AddBackRef(object_id, object, kIsDeserialized);
|
||||
object->internal.as_class.library_url = ReadObjectImpl();
|
||||
|
|
|
@ -399,7 +399,7 @@ void Object::InitNull(Isolate* isolate) {
|
|||
uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld);
|
||||
null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag);
|
||||
// The call below is using 'null_' to initialize itself.
|
||||
InitializeObject(address, kNullCid, Instance::InstanceSize());
|
||||
InitializeObject(address, kNullCid, Instance::InstanceSize(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,7 +462,7 @@ void Object::InitOnce(Isolate* isolate) {
|
|||
intptr_t size = Class::InstanceSize();
|
||||
uword address = heap->Allocate(size, Heap::kOld);
|
||||
class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag);
|
||||
InitializeObject(address, Class::kClassId, size);
|
||||
InitializeObject(address, Class::kClassId, size, true);
|
||||
|
||||
Class fake;
|
||||
// Initialization from Class::New<Class>.
|
||||
|
@ -635,7 +635,7 @@ void Object::InitOnce(Isolate* isolate) {
|
|||
// Allocate and initialize the empty_array instance.
|
||||
{
|
||||
uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld);
|
||||
InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0));
|
||||
InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0), true);
|
||||
Array::initializeHandle(
|
||||
empty_array_,
|
||||
reinterpret_cast<RawArray*>(address + kHeapObjectTag));
|
||||
|
@ -646,7 +646,7 @@ void Object::InitOnce(Isolate* isolate) {
|
|||
// Allocate and initialize the zero_array instance.
|
||||
{
|
||||
uword address = heap->Allocate(Array::InstanceSize(1), Heap::kOld);
|
||||
InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(1));
|
||||
InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(1), true);
|
||||
Array::initializeHandle(
|
||||
zero_array_,
|
||||
reinterpret_cast<RawArray*>(address + kHeapObjectTag));
|
||||
|
@ -661,7 +661,8 @@ void Object::InitOnce(Isolate* isolate) {
|
|||
heap->Allocate(ObjectPool::InstanceSize(0), Heap::kOld);
|
||||
InitializeObject(address,
|
||||
kObjectPoolCid,
|
||||
ObjectPool::InstanceSize(0));
|
||||
ObjectPool::InstanceSize(0),
|
||||
true);
|
||||
ObjectPool::initializeHandle(
|
||||
empty_object_pool_,
|
||||
reinterpret_cast<RawObjectPool*>(address + kHeapObjectTag));
|
||||
|
@ -673,7 +674,8 @@ void Object::InitOnce(Isolate* isolate) {
|
|||
{
|
||||
uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld);
|
||||
InitializeObject(address, kPcDescriptorsCid,
|
||||
PcDescriptors::InstanceSize(0));
|
||||
PcDescriptors::InstanceSize(0),
|
||||
true);
|
||||
PcDescriptors::initializeHandle(
|
||||
empty_descriptors_,
|
||||
reinterpret_cast<RawPcDescriptors*>(address + kHeapObjectTag));
|
||||
|
@ -687,7 +689,8 @@ void Object::InitOnce(Isolate* isolate) {
|
|||
heap->Allocate(LocalVarDescriptors::InstanceSize(0), Heap::kOld);
|
||||
InitializeObject(address,
|
||||
kLocalVarDescriptorsCid,
|
||||
LocalVarDescriptors::InstanceSize(0));
|
||||
LocalVarDescriptors::InstanceSize(0),
|
||||
true);
|
||||
LocalVarDescriptors::initializeHandle(
|
||||
empty_var_descriptors_,
|
||||
reinterpret_cast<RawLocalVarDescriptors*>(address + kHeapObjectTag));
|
||||
|
@ -703,7 +706,8 @@ void Object::InitOnce(Isolate* isolate) {
|
|||
heap->Allocate(ExceptionHandlers::InstanceSize(0), Heap::kOld);
|
||||
InitializeObject(address,
|
||||
kExceptionHandlersCid,
|
||||
ExceptionHandlers::InstanceSize(0));
|
||||
ExceptionHandlers::InstanceSize(0),
|
||||
true);
|
||||
ExceptionHandlers::initializeHandle(
|
||||
empty_exception_handlers_,
|
||||
reinterpret_cast<RawExceptionHandlers*>(address + kHeapObjectTag));
|
||||
|
@ -809,6 +813,7 @@ class PremarkingVisitor : public ObjectVisitor {
|
|||
ASSERT(!obj->IsMarked());
|
||||
// Free list elements should never be marked.
|
||||
if (!obj->IsFreeListElement()) {
|
||||
ASSERT(obj->IsVMHeapObject());
|
||||
obj->SetMarkBitUnsynchronized();
|
||||
}
|
||||
}
|
||||
|
@ -1674,7 +1679,10 @@ RawString* Object::DictionaryName() const {
|
|||
}
|
||||
|
||||
|
||||
void Object::InitializeObject(uword address, intptr_t class_id, intptr_t size) {
|
||||
void Object::InitializeObject(uword address,
|
||||
intptr_t class_id,
|
||||
intptr_t size,
|
||||
bool is_vm_object) {
|
||||
// TODO(iposva): Get a proper halt instruction from the assembler which
|
||||
// would be needed here for code objects.
|
||||
uword initial_value = reinterpret_cast<uword>(null_);
|
||||
|
@ -1688,7 +1696,9 @@ void Object::InitializeObject(uword address, intptr_t class_id, intptr_t size) {
|
|||
ASSERT(class_id != kIllegalCid);
|
||||
tags = RawObject::ClassIdTag::update(class_id, tags);
|
||||
tags = RawObject::SizeTag::update(size, tags);
|
||||
tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags);
|
||||
reinterpret_cast<RawObject*>(address)->tags_ = tags;
|
||||
ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags));
|
||||
VerifiedMemory::Accept(address, size);
|
||||
}
|
||||
|
||||
|
@ -1746,7 +1756,7 @@ RawObject* Object::Allocate(intptr_t cls_id,
|
|||
Profiler::RecordAllocation(isolate, cls_id);
|
||||
}
|
||||
NoSafepointScope no_safepoint;
|
||||
InitializeObject(address, cls_id, size);
|
||||
InitializeObject(address, cls_id, size, (isolate == Dart::vm_isolate()));
|
||||
RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
|
||||
ASSERT(cls_id == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_));
|
||||
return raw_obj;
|
||||
|
@ -1840,6 +1850,12 @@ RawString* Class::UserVisibleName() const {
|
|||
}
|
||||
|
||||
|
||||
bool Class::IsInFullSnapshot() const {
|
||||
NoSafepointScope no_safepoint;
|
||||
return raw_ptr()->library_->ptr()->is_in_fullsnapshot_;
|
||||
}
|
||||
|
||||
|
||||
RawType* Class::SignatureType() const {
|
||||
ASSERT(IsSignatureClass());
|
||||
const Function& function = Function::Handle(signature_function());
|
||||
|
@ -9828,6 +9844,7 @@ RawLibrary* Library::NewLibraryHelper(const String& url,
|
|||
result.StorePointer(&result.raw_ptr()->load_error_, Instance::null());
|
||||
result.set_native_entry_resolver(NULL);
|
||||
result.set_native_entry_symbol_resolver(NULL);
|
||||
result.set_is_in_fullsnapshot(false);
|
||||
result.StoreNonPointer(&result.raw_ptr()->corelib_imported_, true);
|
||||
result.set_debuggable(false);
|
||||
result.set_is_dart_scheme(url.StartsWith(Symbols::DartScheme()));
|
||||
|
@ -15260,6 +15277,7 @@ RawType* Type::NewNonParameterizedType(const Class& type_class) {
|
|||
void Type::SetIsFinalized() const {
|
||||
ASSERT(!IsFinalized());
|
||||
if (IsInstantiated()) {
|
||||
ASSERT(HasResolvedTypeClass());
|
||||
set_type_state(RawType::kFinalizedInstantiated);
|
||||
} else {
|
||||
set_type_state(RawType::kFinalizedUninstantiated);
|
||||
|
|
|
@ -249,23 +249,6 @@ class Object {
|
|||
return AtomicOperations::CompareAndSwapWord(
|
||||
&raw()->ptr()->tags_, old_tags, new_tags);
|
||||
}
|
||||
void set_tags(intptr_t value) const {
|
||||
ASSERT(!IsNull());
|
||||
// TODO(asiva): Remove the capability of setting tags in general. The mask
|
||||
// here only allows for canonical and from_snapshot flags to be set.
|
||||
value = value & 0x0000000c;
|
||||
uword tags = raw()->ptr()->tags_;
|
||||
uword old_tags;
|
||||
do {
|
||||
old_tags = tags;
|
||||
uword new_tags = (old_tags & ~0x0000000c) | value;
|
||||
tags = CompareAndSwapTags(old_tags, new_tags);
|
||||
} while (tags != old_tags);
|
||||
}
|
||||
void SetCreatedFromSnapshot() const {
|
||||
ASSERT(!IsNull());
|
||||
raw()->SetCreatedFromSnapshot();
|
||||
}
|
||||
bool IsCanonical() const {
|
||||
ASSERT(!IsNull());
|
||||
return raw()->IsCanonical();
|
||||
|
@ -728,7 +711,10 @@ class Object {
|
|||
return -kWordSize;
|
||||
}
|
||||
|
||||
static void InitializeObject(uword address, intptr_t id, intptr_t size);
|
||||
static void InitializeObject(uword address,
|
||||
intptr_t id,
|
||||
intptr_t size,
|
||||
bool is_vm_object);
|
||||
|
||||
static void RegisterClass(const Class& cls,
|
||||
const String& name,
|
||||
|
@ -945,6 +931,7 @@ class Class : public Object {
|
|||
RawString* Name() const;
|
||||
RawString* PrettyName() const;
|
||||
RawString* UserVisibleName() const;
|
||||
bool IsInFullSnapshot() const;
|
||||
|
||||
virtual RawString* DictionaryName() const { return Name(); }
|
||||
|
||||
|
@ -1115,6 +1102,10 @@ class Class : public Object {
|
|||
static bool IsSignatureClass(RawClass* cls) {
|
||||
return cls->ptr()->signature_function_ != Object::null();
|
||||
}
|
||||
static bool IsInFullSnapshot(RawClass* cls) {
|
||||
NoSafepointScope no_safepoint;
|
||||
return cls->ptr()->library_->ptr()->is_in_fullsnapshot_;
|
||||
}
|
||||
|
||||
// Check if this class represents a canonical signature class, i.e. not an
|
||||
// alias as defined in a typedef.
|
||||
|
@ -3392,6 +3383,11 @@ class Library : public Object {
|
|||
native_symbol_resolver);
|
||||
}
|
||||
|
||||
bool is_in_fullsnapshot() const { return raw_ptr()->is_in_fullsnapshot_; }
|
||||
void set_is_in_fullsnapshot(bool value) const {
|
||||
StoreNonPointer(&raw_ptr()->is_in_fullsnapshot_, value);
|
||||
}
|
||||
|
||||
RawError* Patch(const Script& script) const;
|
||||
|
||||
RawString* PrivateName(const String& name) const;
|
||||
|
|
|
@ -18,10 +18,6 @@ namespace dart {
|
|||
DEFINE_FLAG(bool, validate_overwrite, true, "Verify overwritten fields.");
|
||||
#endif // DEBUG
|
||||
|
||||
bool RawObject::IsVMHeapObject() const {
|
||||
return Dart::vm_isolate()->heap()->Contains(ToAddr(this));
|
||||
}
|
||||
|
||||
|
||||
void RawObject::Validate(Isolate* isolate) const {
|
||||
if (Object::void_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) {
|
||||
|
|
|
@ -236,7 +236,7 @@ class RawObject {
|
|||
kWatchedBit = 0,
|
||||
kMarkBit = 1,
|
||||
kCanonicalBit = 2,
|
||||
kFromSnapshotBit = 3,
|
||||
kVMHeapObjectBit = 3,
|
||||
kRememberedBit = 4,
|
||||
#if defined(ARCH_IS_32_BIT)
|
||||
kReservedTagPos = 5, // kReservedBit{100K,1M,10M}
|
||||
|
@ -315,8 +315,6 @@ class RawObject {
|
|||
uword addr = reinterpret_cast<uword>(this);
|
||||
return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
|
||||
}
|
||||
// Assumes this is a heap object.
|
||||
bool IsVMHeapObject() const;
|
||||
|
||||
// Like !IsHeapObject() || IsOldObject(), but compiles to a single branch.
|
||||
bool IsSmiOrOldObject() const {
|
||||
|
@ -372,11 +370,11 @@ class RawObject {
|
|||
void ClearCanonical() {
|
||||
UpdateTagBit<CanonicalObjectTag>(false);
|
||||
}
|
||||
bool IsCreatedFromSnapshot() const {
|
||||
return CreatedFromSnapshotTag::decode(ptr()->tags_);
|
||||
bool IsVMHeapObject() const {
|
||||
return VMHeapObjectTag::decode(ptr()->tags_);
|
||||
}
|
||||
void SetCreatedFromSnapshot() {
|
||||
UpdateTagBit<CreatedFromSnapshotTag>(true);
|
||||
void SetVMHeapObject() {
|
||||
UpdateTagBit<VMHeapObjectTag>(true);
|
||||
}
|
||||
|
||||
// Support for GC remembered bit.
|
||||
|
@ -445,8 +443,8 @@ class RawObject {
|
|||
return reinterpret_cast<uword>(raw_obj->ptr());
|
||||
}
|
||||
|
||||
static bool IsCreatedFromSnapshot(intptr_t value) {
|
||||
return CreatedFromSnapshotTag::decode(value);
|
||||
static bool IsVMHeapObject(intptr_t value) {
|
||||
return VMHeapObjectTag::decode(value);
|
||||
}
|
||||
|
||||
static bool IsCanonical(intptr_t value) {
|
||||
|
@ -482,7 +480,7 @@ class RawObject {
|
|||
|
||||
class CanonicalObjectTag : public BitField<bool, kCanonicalBit, 1> {};
|
||||
|
||||
class CreatedFromSnapshotTag : public BitField<bool, kFromSnapshotBit, 1> {};
|
||||
class VMHeapObjectTag : public BitField<bool, kVMHeapObjectBit, 1> {};
|
||||
|
||||
class ReservedBits : public
|
||||
BitField<intptr_t, kReservedTagPos, kReservedTagSize> {}; // NOLINT
|
||||
|
@ -950,7 +948,9 @@ class RawLibrary : public RawObject {
|
|||
bool corelib_imported_;
|
||||
bool is_dart_scheme_;
|
||||
bool debuggable_; // True if debugger can stop in library.
|
||||
bool is_in_fullsnapshot_; // True if library is in a full snapshot.
|
||||
|
||||
friend class Class;
|
||||
friend class Isolate;
|
||||
};
|
||||
|
||||
|
|
|
@ -31,8 +31,9 @@ RawClass* Class::ReadFrom(SnapshotReader* reader,
|
|||
ASSERT(reader != NULL);
|
||||
|
||||
Class& cls = Class::ZoneHandle(reader->zone(), Class::null());
|
||||
bool is_in_fullsnapshot = reader->Read<bool>();
|
||||
if ((kind == Snapshot::kFull) ||
|
||||
(kind == Snapshot::kScript && !RawObject::IsCreatedFromSnapshot(tags))) {
|
||||
(kind == Snapshot::kScript && !is_in_fullsnapshot)) {
|
||||
// Read in the base information.
|
||||
classid_t class_id = reader->ReadClassIDValue();
|
||||
|
||||
|
@ -49,9 +50,6 @@ RawClass* Class::ReadFrom(SnapshotReader* reader,
|
|||
}
|
||||
reader->AddBackRef(object_id, &cls, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
cls.set_tags(tags);
|
||||
|
||||
// Set all non object fields.
|
||||
if (!RawObject::IsInternalVMdefinedClassId(class_id)) {
|
||||
// Instance size of a VM defined class is already set up.
|
||||
|
@ -76,8 +74,10 @@ RawClass* Class::ReadFrom(SnapshotReader* reader,
|
|||
cls.StorePointer((cls.raw()->from() + i),
|
||||
reader->PassiveObjectHandle()->raw());
|
||||
}
|
||||
ASSERT(!cls.IsInFullSnapshot() || (kind == Snapshot::kFull));
|
||||
} else {
|
||||
cls ^= reader->ReadClassId(object_id);
|
||||
ASSERT((kind == Snapshot::kMessage) || cls.IsInFullSnapshot());
|
||||
}
|
||||
return cls.raw();
|
||||
}
|
||||
|
@ -87,17 +87,22 @@ void RawClass::WriteTo(SnapshotWriter* writer,
|
|||
intptr_t object_id,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
bool is_in_fullsnapshot = Class::IsInFullSnapshot(this);
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
||||
if ((kind == Snapshot::kFull) ||
|
||||
(kind == Snapshot::kScript &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this)))) {
|
||||
// Write out the class and tags information.
|
||||
writer->WriteVMIsolateObject(kClassCid);
|
||||
writer->WriteTags(writer->GetObjectTags(this));
|
||||
// Write out the class and tags information.
|
||||
writer->WriteVMIsolateObject(kClassCid);
|
||||
writer->WriteTags(writer->GetObjectTags(this));
|
||||
|
||||
// Write out the boolean is_in_fullsnapshot first as this will
|
||||
// help the reader decide how the rest of the information needs
|
||||
// to be interpreted.
|
||||
writer->Write<bool>(is_in_fullsnapshot);
|
||||
|
||||
if ((kind == Snapshot::kFull) ||
|
||||
(kind == Snapshot::kScript && !is_in_fullsnapshot)) {
|
||||
// Write out all the non object pointer fields.
|
||||
// NOTE: cpp_vtable_ is not written.
|
||||
classid_t class_id = ptr()->id_;
|
||||
|
@ -144,9 +149,6 @@ RawUnresolvedClass* UnresolvedClass::ReadFrom(SnapshotReader* reader,
|
|||
reader->zone(), NEW_OBJECT(UnresolvedClass));
|
||||
reader->AddBackRef(object_id, &unresolved_class, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
unresolved_class.set_tags(tags);
|
||||
|
||||
// Set all non object fields.
|
||||
unresolved_class.set_token_pos(reader->Read<int32_t>());
|
||||
|
||||
|
@ -229,11 +231,9 @@ RawType* Type::ReadFrom(SnapshotReader* reader,
|
|||
reader->PassiveObjectHandle()->raw());
|
||||
}
|
||||
|
||||
// Set the object tags.
|
||||
type.set_tags(tags);
|
||||
if (defer_canonicalization) {
|
||||
// We are deferring canonicalization so mark object as not canonical.
|
||||
type.ClearCanonical();
|
||||
// Set the canonical bit.
|
||||
if (!defer_canonicalization && RawObject::IsCanonical(tags)) {
|
||||
type.SetCanonical();
|
||||
}
|
||||
|
||||
return type.raw();
|
||||
|
@ -248,6 +248,7 @@ void RawType::WriteTo(SnapshotWriter* writer,
|
|||
// Only resolved and finalized types should be written to a snapshot.
|
||||
ASSERT((ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
|
||||
(ptr()->type_state_ == RawType::kFinalizedUninstantiated));
|
||||
ASSERT(ptr()->type_class_ != Object::null());
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -263,6 +264,7 @@ void RawType::WriteTo(SnapshotWriter* writer,
|
|||
// Write out all the object pointer fields. Since we will be canonicalizing
|
||||
// the type object when reading it back we should write out all the fields
|
||||
// inline and not as references.
|
||||
ASSERT(ptr()->type_class_ != Object::null());
|
||||
SnapshotWriterVisitor visitor(writer);
|
||||
visitor.VisitPointers(from(), to());
|
||||
}
|
||||
|
@ -279,9 +281,6 @@ RawTypeRef* TypeRef::ReadFrom(SnapshotReader* reader,
|
|||
reader->zone(), NEW_OBJECT(TypeRef));
|
||||
reader->AddBackRef(object_id, &type_ref, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
type_ref.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
@ -327,9 +326,6 @@ RawTypeParameter* TypeParameter::ReadFrom(SnapshotReader* reader,
|
|||
reader->zone(), NEW_OBJECT(TypeParameter));
|
||||
reader->AddBackRef(object_id, &type_parameter, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
type_parameter.set_tags(tags);
|
||||
|
||||
// Set all non object fields.
|
||||
type_parameter.set_token_pos(reader->Read<int32_t>());
|
||||
type_parameter.set_index(reader->Read<int16_t>());
|
||||
|
@ -389,9 +385,6 @@ RawBoundedType* BoundedType::ReadFrom(SnapshotReader* reader,
|
|||
reader->zone(), NEW_OBJECT(BoundedType));
|
||||
reader->AddBackRef(object_id, &bounded_type, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
bounded_type.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
@ -478,11 +471,9 @@ RawTypeArguments* TypeArguments::ReadFrom(SnapshotReader* reader,
|
|||
type_arguments.SetTypeAt(i, *reader->TypeHandle());
|
||||
}
|
||||
|
||||
// Set the object tags .
|
||||
type_arguments.set_tags(tags);
|
||||
if (defer_canonicalization) {
|
||||
// We are deferring canonicalization so mark object as not canonical.
|
||||
type_arguments.ClearCanonical();
|
||||
// Set the canonical bit.
|
||||
if (!defer_canonicalization && RawObject::IsCanonical(tags)) {
|
||||
type_arguments.SetCanonical();
|
||||
}
|
||||
|
||||
return type_arguments.raw();
|
||||
|
@ -522,18 +513,12 @@ RawPatchClass* PatchClass::ReadFrom(SnapshotReader* reader,
|
|||
intptr_t tags,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(reader != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(tags)) ||
|
||||
(kind == Snapshot::kFull));
|
||||
|
||||
// Allocate function object.
|
||||
PatchClass& cls = PatchClass::ZoneHandle(reader->zone(),
|
||||
NEW_OBJECT(PatchClass));
|
||||
reader->AddBackRef(object_id, &cls, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
cls.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
@ -543,6 +528,9 @@ RawPatchClass* PatchClass::ReadFrom(SnapshotReader* reader,
|
|||
cls.StorePointer((cls.raw()->from() + i),
|
||||
reader->PassiveObjectHandle()->raw());
|
||||
}
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!Class::IsInFullSnapshot(cls.source_class())) ||
|
||||
(kind == Snapshot::kFull));
|
||||
|
||||
return cls.raw();
|
||||
}
|
||||
|
@ -552,9 +540,7 @@ void RawPatchClass::WriteTo(SnapshotWriter* writer,
|
|||
intptr_t object_id,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -573,18 +559,13 @@ RawClosureData* ClosureData::ReadFrom(SnapshotReader* reader,
|
|||
intptr_t tags,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(reader != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(tags)) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Allocate closure data object.
|
||||
ClosureData& data = ClosureData::ZoneHandle(
|
||||
reader->zone(), NEW_OBJECT(ClosureData));
|
||||
reader->AddBackRef(object_id, &data, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
data.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
@ -601,9 +582,7 @@ void RawClosureData::WriteTo(SnapshotWriter* writer,
|
|||
intptr_t object_id,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -633,18 +612,13 @@ RawRedirectionData* RedirectionData::ReadFrom(SnapshotReader* reader,
|
|||
intptr_t tags,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(reader != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(tags)) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Allocate redirection data object.
|
||||
RedirectionData& data = RedirectionData::ZoneHandle(
|
||||
reader->zone(), NEW_OBJECT(RedirectionData));
|
||||
reader->AddBackRef(object_id, &data, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
data.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
@ -665,9 +639,7 @@ void RawRedirectionData::WriteTo(SnapshotWriter* writer,
|
|||
intptr_t object_id,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -687,18 +659,13 @@ RawFunction* Function::ReadFrom(SnapshotReader* reader,
|
|||
intptr_t tags,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(reader != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(tags)) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Allocate function object.
|
||||
Function& func = Function::ZoneHandle(
|
||||
reader->zone(), NEW_OBJECT(Function));
|
||||
reader->AddBackRef(object_id, &func, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
func.set_tags(tags);
|
||||
|
||||
// Set all the non object fields.
|
||||
func.set_token_pos(reader->Read<int32_t>());
|
||||
func.set_end_token_pos(reader->Read<int32_t>());
|
||||
|
@ -734,9 +701,7 @@ void RawFunction::WriteTo(SnapshotWriter* writer,
|
|||
intptr_t object_id,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -768,17 +733,12 @@ RawField* Field::ReadFrom(SnapshotReader* reader,
|
|||
intptr_t tags,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(reader != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(tags)) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Allocate field object.
|
||||
Field& field = Field::ZoneHandle(reader->zone(), NEW_OBJECT(Field));
|
||||
reader->AddBackRef(object_id, &field, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
field.set_tags(tags);
|
||||
|
||||
// Set all non object fields.
|
||||
field.set_token_pos(reader->Read<int32_t>());
|
||||
field.set_guarded_cid(reader->Read<int32_t>());
|
||||
|
@ -807,9 +767,7 @@ void RawField::WriteTo(SnapshotWriter* writer,
|
|||
intptr_t object_id,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -842,9 +800,6 @@ RawLiteralToken* LiteralToken::ReadFrom(SnapshotReader* reader,
|
|||
reader->zone(), NEW_OBJECT(LiteralToken));
|
||||
reader->AddBackRef(object_id, &literal_token, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
literal_token.set_tags(tags);
|
||||
|
||||
// Read the token attributes.
|
||||
Token::Kind token_kind = static_cast<Token::Kind>(reader->Read<int32_t>());
|
||||
literal_token.set_kind(token_kind);
|
||||
|
@ -890,9 +845,7 @@ RawTokenStream* TokenStream::ReadFrom(SnapshotReader* reader,
|
|||
intptr_t tags,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(reader != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(tags)) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Read the length so that we can determine number of tokens to read.
|
||||
intptr_t len = reader->ReadSmiValue();
|
||||
|
@ -902,9 +855,6 @@ RawTokenStream* TokenStream::ReadFrom(SnapshotReader* reader,
|
|||
reader->zone(), NEW_OBJECT_WITH_LEN(TokenStream, len));
|
||||
reader->AddBackRef(object_id, &token_stream, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
token_stream.set_tags(tags);
|
||||
|
||||
// Read the stream of tokens into the TokenStream object for script
|
||||
// snapshots as we made a copy of token stream.
|
||||
if (kind == Snapshot::kScript) {
|
||||
|
@ -928,9 +878,7 @@ void RawTokenStream::WriteTo(SnapshotWriter* writer,
|
|||
intptr_t object_id,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -957,17 +905,12 @@ RawScript* Script::ReadFrom(SnapshotReader* reader,
|
|||
intptr_t tags,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(reader != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(tags)) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Allocate script object.
|
||||
Script& script = Script::ZoneHandle(reader->zone(), NEW_OBJECT(Script));
|
||||
reader->AddBackRef(object_id, &script, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
script.set_tags(tags);
|
||||
|
||||
script.StoreNonPointer(&script.raw_ptr()->line_offset_,
|
||||
reader->Read<int32_t>());
|
||||
script.StoreNonPointer(&script.raw_ptr()->col_offset_,
|
||||
|
@ -997,9 +940,7 @@ void RawScript::WriteTo(SnapshotWriter* writer,
|
|||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
ASSERT(tokens_ != TokenStream::null());
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -1029,18 +970,16 @@ RawLibrary* Library::ReadFrom(SnapshotReader* reader,
|
|||
Library& library = Library::ZoneHandle(reader->zone(), Library::null());
|
||||
reader->AddBackRef(object_id, &library, kIsDeserialized);
|
||||
|
||||
if ((kind == Snapshot::kScript) && RawObject::IsCreatedFromSnapshot(tags)) {
|
||||
ASSERT(kind != Snapshot::kFull);
|
||||
bool is_in_fullsnapshot = reader->Read<bool>();
|
||||
if ((kind == Snapshot::kScript) && is_in_fullsnapshot) {
|
||||
// Lookup the object as it should already exist in the heap.
|
||||
*reader->StringHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
|
||||
library = Library::LookupLibrary(*reader->StringHandle());
|
||||
ASSERT(library.is_in_fullsnapshot());
|
||||
} else {
|
||||
// Allocate library object.
|
||||
library = NEW_OBJECT(Library);
|
||||
|
||||
// Set the object tags.
|
||||
library.set_tags(tags);
|
||||
|
||||
// Set all non object fields.
|
||||
library.StoreNonPointer(&library.raw_ptr()->index_,
|
||||
reader->ReadClassIDValue());
|
||||
|
@ -1056,6 +995,11 @@ RawLibrary* Library::ReadFrom(SnapshotReader* reader,
|
|||
reader->Read<bool>());
|
||||
library.StoreNonPointer(&library.raw_ptr()->debuggable_,
|
||||
reader->Read<bool>());
|
||||
if (kind == Snapshot::kFull) {
|
||||
is_in_fullsnapshot = true;
|
||||
}
|
||||
library.StoreNonPointer(&library.raw_ptr()->is_in_fullsnapshot_,
|
||||
is_in_fullsnapshot);
|
||||
// The native resolver and symbolizer are not serialized.
|
||||
library.set_native_entry_resolver(NULL);
|
||||
library.set_native_entry_symbol_resolver(NULL);
|
||||
|
@ -1092,12 +1036,16 @@ void RawLibrary::WriteTo(SnapshotWriter* writer,
|
|||
writer->WriteVMIsolateObject(kLibraryCid);
|
||||
writer->WriteTags(writer->GetObjectTags(this));
|
||||
|
||||
if ((kind == Snapshot::kScript) &&
|
||||
RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) {
|
||||
ASSERT(kind != Snapshot::kFull);
|
||||
// Write out the boolean is_in_fullsnapshot_ first as this will
|
||||
// help the reader decide how the rest of the information needs
|
||||
// to be interpreted.
|
||||
writer->Write<bool>(ptr()->is_in_fullsnapshot_);
|
||||
|
||||
if ((kind == Snapshot::kScript) && ptr()->is_in_fullsnapshot_) {
|
||||
// Write out library URL so that it can be looked up when reading.
|
||||
writer->WriteObjectImpl(ptr()->url_, kAsInlinedObject);
|
||||
} else {
|
||||
ASSERT((kind == Snapshot::kFull) || !ptr()->is_in_fullsnapshot_);
|
||||
// Write out all non object fields.
|
||||
writer->WriteClassIDValue(ptr()->index_);
|
||||
writer->WriteClassIDValue(ptr()->num_anonymous_);
|
||||
|
@ -1124,18 +1072,13 @@ RawLibraryPrefix* LibraryPrefix::ReadFrom(SnapshotReader* reader,
|
|||
intptr_t tags,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(reader != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(tags)) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Allocate library prefix object.
|
||||
LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(
|
||||
reader->zone(), NEW_OBJECT(LibraryPrefix));
|
||||
reader->AddBackRef(object_id, &prefix, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
prefix.set_tags(tags);
|
||||
|
||||
// Set all non object fields.
|
||||
prefix.StoreNonPointer(&prefix.raw_ptr()->num_imports_,
|
||||
reader->Read<int16_t>());
|
||||
|
@ -1161,9 +1104,7 @@ void RawLibraryPrefix::WriteTo(SnapshotWriter* writer,
|
|||
intptr_t object_id,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -1188,18 +1129,13 @@ RawNamespace* Namespace::ReadFrom(SnapshotReader* reader,
|
|||
intptr_t tags,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(reader != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(tags)) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Allocate Namespace object.
|
||||
Namespace& ns = Namespace::ZoneHandle(
|
||||
reader->zone(), NEW_OBJECT(Namespace));
|
||||
reader->AddBackRef(object_id, &ns, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
ns.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
@ -1218,9 +1154,7 @@ void RawNamespace::WriteTo(SnapshotWriter* writer,
|
|||
intptr_t object_id,
|
||||
Snapshot::Kind kind) {
|
||||
ASSERT(writer != NULL);
|
||||
ASSERT(((kind == Snapshot::kScript) &&
|
||||
!RawObject::IsCreatedFromSnapshot(writer->GetObjectTags(this))) ||
|
||||
(kind == Snapshot::kFull));
|
||||
ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
|
||||
|
||||
// Write out the serialization header value for this object.
|
||||
writer->WriteInlinedObjectHeader(object_id);
|
||||
|
@ -1296,9 +1230,6 @@ RawPcDescriptors* PcDescriptors::ReadFrom(SnapshotReader* reader,
|
|||
PcDescriptors::New(length));
|
||||
reader->AddBackRef(object_id, &result, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
result.set_tags(tags);
|
||||
|
||||
if (result.Length() > 0) {
|
||||
NoSafepointScope no_safepoint;
|
||||
intptr_t len = result.Length();
|
||||
|
@ -1343,9 +1274,6 @@ RawStackmap* Stackmap::ReadFrom(SnapshotReader* reader,
|
|||
Stackmap::New(length, register_bit_count, pc_offset));
|
||||
reader->AddBackRef(object_id, &result, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
result.set_tags(tags);
|
||||
|
||||
if (result.Length() > 0) {
|
||||
NoSafepointScope no_safepoint;
|
||||
intptr_t len = (result.Length() + 7) / 8;
|
||||
|
@ -1390,9 +1318,6 @@ RawLocalVarDescriptors* LocalVarDescriptors::ReadFrom(SnapshotReader* reader,
|
|||
LocalVarDescriptors::New(num_entries));
|
||||
reader->AddBackRef(object_id, &result, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
result.set_tags(tags);
|
||||
|
||||
for (intptr_t i = 0; i < num_entries; i++) {
|
||||
(*reader->StringHandle()) ^= reader->ReadObjectImpl(kAsReference);
|
||||
result.StorePointer(result.raw()->nameAddrAt(i),
|
||||
|
@ -1446,9 +1371,6 @@ RawExceptionHandlers* ExceptionHandlers::ReadFrom(SnapshotReader* reader,
|
|||
ExceptionHandlers::New(*reader->ArrayHandle()));
|
||||
reader->AddBackRef(object_id, &result, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
result.set_tags(tags);
|
||||
|
||||
if (result.num_entries() > 0) {
|
||||
NoSafepointScope no_safepoint;
|
||||
const intptr_t len =
|
||||
|
@ -1496,9 +1418,6 @@ RawContext* Context::ReadFrom(SnapshotReader* reader,
|
|||
} else {
|
||||
context ^= NEW_OBJECT_WITH_LEN(Context, num_vars);
|
||||
|
||||
// Set the object tags.
|
||||
context.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
@ -1627,9 +1546,6 @@ RawApiError* ApiError::ReadFrom(SnapshotReader* reader,
|
|||
ApiError::ZoneHandle(reader->zone(), NEW_OBJECT(ApiError));
|
||||
reader->AddBackRef(object_id, &api_error, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
api_error.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
@ -1673,9 +1589,6 @@ RawLanguageError* LanguageError::ReadFrom(SnapshotReader* reader,
|
|||
LanguageError::ZoneHandle(reader->zone(), NEW_OBJECT(LanguageError));
|
||||
reader->AddBackRef(object_id, &language_error, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
language_error.set_tags(tags);
|
||||
|
||||
// Set all non object fields.
|
||||
language_error.set_token_pos(reader->Read<int32_t>());
|
||||
language_error.set_kind(reader->Read<uint8_t>());
|
||||
|
@ -1725,9 +1638,6 @@ RawUnhandledException* UnhandledException::ReadFrom(SnapshotReader* reader,
|
|||
reader->zone(), NEW_OBJECT(UnhandledException));
|
||||
reader->AddBackRef(object_id, &result, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
result.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
@ -1784,26 +1694,20 @@ RawInstance* Instance::ReadFrom(SnapshotReader* reader,
|
|||
Instance& obj = Instance::ZoneHandle(reader->zone(), Instance::null());
|
||||
if (kind == Snapshot::kFull) {
|
||||
obj = reader->NewInstance();
|
||||
// Set the canonical bit.
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
obj.SetCanonical();
|
||||
}
|
||||
} else {
|
||||
obj ^= Object::Allocate(kInstanceCid,
|
||||
Instance::InstanceSize(),
|
||||
HEAP_SPACE(kind));
|
||||
// When reading a script snapshot we need to canonicalize only those object
|
||||
// references that are objects from the core library (loaded from a
|
||||
// full snapshot). Objects that are only in the script need not be
|
||||
// canonicalized as they are already canonical.
|
||||
// When reading a message snapshot we always have to canonicalize.
|
||||
if (RawObject::IsCanonical(tags) &&
|
||||
(RawObject::IsCreatedFromSnapshot(tags) ||
|
||||
(kind == Snapshot::kMessage))) {
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
obj = obj.CheckAndCanonicalize(NULL);
|
||||
}
|
||||
}
|
||||
reader->AddBackRef(object_id, &obj, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
obj.set_tags(tags);
|
||||
|
||||
return obj.raw();
|
||||
}
|
||||
|
||||
|
@ -1844,25 +1748,21 @@ RawInteger* Mint::ReadFrom(SnapshotReader* reader,
|
|||
Mint& mint = Mint::ZoneHandle(reader->zone(), Mint::null());
|
||||
if (kind == Snapshot::kFull) {
|
||||
mint = reader->NewMint(value);
|
||||
// Set the object tags.
|
||||
mint.set_tags(tags);
|
||||
// Set the canonical bit.
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
mint.SetCanonical();
|
||||
}
|
||||
} else {
|
||||
// When reading a script snapshot we need to canonicalize only those object
|
||||
// references that are objects from the core library (loaded from a
|
||||
// full snapshot). Objects that are only in the script need not be
|
||||
// canonicalized as they are already canonical.
|
||||
// When reading a message snapshot we always have to canonicalize.
|
||||
if (RawObject::IsCanonical(tags) &&
|
||||
(RawObject::IsCreatedFromSnapshot(tags) ||
|
||||
(kind == Snapshot::kMessage))) {
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
mint = Mint::NewCanonical(value);
|
||||
ASSERT(mint.IsCanonical() &&
|
||||
(kind == Snapshot::kMessage ||
|
||||
RawObject::IsCreatedFromSnapshot(mint.raw()->ptr()->tags_)));
|
||||
ASSERT(mint.IsCanonical());
|
||||
} else {
|
||||
mint = Mint::New(value, HEAP_SPACE(kind));
|
||||
// Set the object tags.
|
||||
mint.set_tags(tags);
|
||||
}
|
||||
}
|
||||
reader->AddBackRef(object_id, &mint, kIsDeserialized);
|
||||
|
@ -1910,25 +1810,17 @@ RawBigint* Bigint::ReadFrom(SnapshotReader* reader,
|
|||
// If it is a canonical constant make it one.
|
||||
// When reading a full snapshot we don't need to canonicalize the object
|
||||
// as it would already be a canonical object.
|
||||
// When reading a script snapshot we need to canonicalize only those object
|
||||
// references that are objects from the core library (loaded from a
|
||||
// full snapshot). Objects that are only in the script need not be
|
||||
// canonicalized as they are already canonical.
|
||||
// When reading a message snapshot we always have to canonicalize the object.
|
||||
if (kind == Snapshot::kFull) {
|
||||
// Set the object tags.
|
||||
obj.set_tags(tags);
|
||||
} else if (RawObject::IsCanonical(tags) &&
|
||||
(RawObject::IsCreatedFromSnapshot(tags) ||
|
||||
(kind == Snapshot::kMessage))) {
|
||||
obj ^= obj.CheckAndCanonicalize(NULL);
|
||||
ASSERT(!obj.IsNull());
|
||||
ASSERT(obj.IsCanonical() &&
|
||||
(kind == Snapshot::kMessage ||
|
||||
RawObject::IsCreatedFromSnapshot(obj.raw()->ptr()->tags_)));
|
||||
} else {
|
||||
// Set the object tags.
|
||||
obj.set_tags(tags);
|
||||
// When reading a script snapshot or a message snapshot we always have
|
||||
// to canonicalize the object.
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
if (kind == Snapshot::kFull) {
|
||||
// Set the canonical bit.
|
||||
obj.SetCanonical();
|
||||
} else {
|
||||
obj ^= obj.CheckAndCanonicalize(NULL);
|
||||
ASSERT(!obj.IsNull());
|
||||
ASSERT(obj.IsCanonical());
|
||||
}
|
||||
}
|
||||
return obj.raw();
|
||||
}
|
||||
|
@ -1965,23 +1857,20 @@ RawDouble* Double::ReadFrom(SnapshotReader* reader,
|
|||
Double& dbl = Double::ZoneHandle(reader->zone(), Double::null());
|
||||
if (kind == Snapshot::kFull) {
|
||||
dbl = reader->NewDouble(value);
|
||||
// Set the object tags.
|
||||
dbl.set_tags(tags);
|
||||
// Set the canonical bit.
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
dbl.SetCanonical();
|
||||
}
|
||||
} else {
|
||||
// When reading a script snapshot we need to canonicalize only those object
|
||||
// references that are objects from the core library (loaded from a
|
||||
// full snapshot). Objects that are only in the script need not be
|
||||
// canonicalized as they are already canonical.
|
||||
if (RawObject::IsCanonical(tags) &&
|
||||
RawObject::IsCreatedFromSnapshot(tags)) {
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
dbl = Double::NewCanonical(value);
|
||||
ASSERT(dbl.IsCanonical() &&
|
||||
(kind == Snapshot::kMessage ||
|
||||
RawObject::IsCreatedFromSnapshot(dbl.raw()->ptr()->tags_)));
|
||||
ASSERT(dbl.IsCanonical());
|
||||
} else {
|
||||
dbl = Double::New(value, HEAP_SPACE(kind));
|
||||
// Set the object tags.
|
||||
dbl.set_tags(tags);
|
||||
}
|
||||
}
|
||||
reader->AddBackRef(object_id, &dbl, kIsDeserialized);
|
||||
|
@ -2041,7 +1930,6 @@ void String::ReadFromImpl(SnapshotReader* reader,
|
|||
} else {
|
||||
// Set up the string object.
|
||||
*str_obj = StringType::New(len, HEAP_SPACE(kind));
|
||||
str_obj->set_tags(tags);
|
||||
str_obj->SetHash(0); // Will get computed when needed.
|
||||
if (len == 0) {
|
||||
return;
|
||||
|
@ -2072,7 +1960,9 @@ RawOneByteString* OneByteString::ReadFrom(SnapshotReader* reader,
|
|||
ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0);
|
||||
RawOneByteString* obj = reader->NewOneByteString(len);
|
||||
str_obj = obj;
|
||||
str_obj.set_tags(tags);
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
str_obj.SetCanonical();
|
||||
}
|
||||
str_obj.SetHash(hash);
|
||||
if (len > 0) {
|
||||
uint8_t* raw_ptr = CharAddr(str_obj, 0);
|
||||
|
@ -2101,7 +1991,9 @@ RawTwoByteString* TwoByteString::ReadFrom(SnapshotReader* reader,
|
|||
if (kind == Snapshot::kFull) {
|
||||
RawTwoByteString* obj = reader->NewTwoByteString(len);
|
||||
str_obj = obj;
|
||||
str_obj.set_tags(tags);
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
str_obj.SetCanonical();
|
||||
}
|
||||
str_obj.SetHash(hash);
|
||||
NoSafepointScope no_safepoint;
|
||||
uint16_t* raw_ptr = (len > 0)? CharAddr(str_obj, 0) : NULL;
|
||||
|
@ -2290,7 +2182,11 @@ RawImmutableArray* ImmutableArray::ReadFrom(SnapshotReader* reader,
|
|||
}
|
||||
reader->ArrayReadFrom(object_id, *array, len, tags);
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
*array ^= array->CheckAndCanonicalize(NULL);
|
||||
if (kind == Snapshot::kFull) {
|
||||
array->SetCanonical();
|
||||
} else {
|
||||
*array ^= array->CheckAndCanonicalize(NULL);
|
||||
}
|
||||
}
|
||||
return raw(*array);
|
||||
}
|
||||
|
@ -2396,8 +2292,6 @@ RawLinkedHashMap* LinkedHashMap::ReadFrom(SnapshotReader* reader,
|
|||
map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind));
|
||||
}
|
||||
reader->AddBackRef(object_id, &map, kIsDeserialized);
|
||||
// Set the object tags.
|
||||
map.set_tags(tags);
|
||||
|
||||
// Read the type arguments.
|
||||
const intptr_t typeargs_offset =
|
||||
|
@ -2509,8 +2403,6 @@ RawFloat32x4* Float32x4::ReadFrom(SnapshotReader* reader,
|
|||
simd = Float32x4::New(value0, value1, value2, value3, HEAP_SPACE(kind));
|
||||
}
|
||||
reader->AddBackRef(object_id, &simd, kIsDeserialized);
|
||||
// Set the object tags.
|
||||
simd.set_tags(tags);
|
||||
return simd.raw();
|
||||
}
|
||||
|
||||
|
@ -2555,8 +2447,6 @@ RawInt32x4* Int32x4::ReadFrom(SnapshotReader* reader,
|
|||
simd = Int32x4::New(value0, value1, value2, value3, HEAP_SPACE(kind));
|
||||
}
|
||||
reader->AddBackRef(object_id, &simd, kIsDeserialized);
|
||||
// Set the object tags.
|
||||
simd.set_tags(tags);
|
||||
return simd.raw();
|
||||
}
|
||||
|
||||
|
@ -2599,8 +2489,6 @@ RawFloat64x2* Float64x2::ReadFrom(SnapshotReader* reader,
|
|||
simd = Float64x2::New(value0, value1, HEAP_SPACE(kind));
|
||||
}
|
||||
reader->AddBackRef(object_id, &simd, kIsDeserialized);
|
||||
// Set the object tags.
|
||||
simd.set_tags(tags);
|
||||
return simd.raw();
|
||||
}
|
||||
|
||||
|
@ -2642,9 +2530,6 @@ RawTypedData* TypedData::ReadFrom(SnapshotReader* reader,
|
|||
: TypedData::New(cid, len, HEAP_SPACE(kind)));
|
||||
reader->AddBackRef(object_id, &result, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
result.set_tags(tags);
|
||||
|
||||
// Setup the array elements.
|
||||
intptr_t element_size = ElementSizeInBytes(cid);
|
||||
intptr_t length_in_bytes = len * element_size;
|
||||
|
@ -2993,9 +2878,6 @@ RawJSRegExp* JSRegExp::ReadFrom(SnapshotReader* reader,
|
|||
reader->zone(), JSRegExp::New(HEAP_SPACE(kind)));
|
||||
reader->AddBackRef(object_id, ®ex, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
regex.set_tags(tags);
|
||||
|
||||
// Read and Set all the other fields.
|
||||
regex.StoreSmi(®ex.raw_ptr()->num_bracket_expressions_,
|
||||
reader->ReadAsSmi());
|
||||
|
@ -3043,9 +2925,6 @@ RawWeakProperty* WeakProperty::ReadFrom(SnapshotReader* reader,
|
|||
reader->zone(), WeakProperty::New(HEAP_SPACE(kind)));
|
||||
reader->AddBackRef(object_id, &weak_property, kIsDeserialized);
|
||||
|
||||
// Set the object tags.
|
||||
weak_property.set_tags(tags);
|
||||
|
||||
// Set all the object fields.
|
||||
// TODO(5411462): Need to assert No GC can happen here, even though
|
||||
// allocations may happen.
|
||||
|
|
|
@ -325,6 +325,11 @@ RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const {
|
|||
}
|
||||
|
||||
|
||||
bool SnapshotReader::is_vm_isolate() const {
|
||||
return isolate_ == Dart::vm_isolate();
|
||||
}
|
||||
|
||||
|
||||
RawObject* SnapshotReader::ReadObjectImpl(bool as_reference,
|
||||
intptr_t patch_object_id,
|
||||
intptr_t patch_offset) {
|
||||
|
@ -463,9 +468,6 @@ RawObject* SnapshotReader::ReadObjectRef(intptr_t object_id,
|
|||
#undef SNAPSHOT_READ
|
||||
default: UNREACHABLE(); break;
|
||||
}
|
||||
if (kind_ == Snapshot::kFull) {
|
||||
pobj_.SetCreatedFromSnapshot();
|
||||
}
|
||||
return pobj_.raw();
|
||||
}
|
||||
|
||||
|
@ -536,10 +538,14 @@ RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id,
|
|||
result->SetFieldAtOffset(offset, Object::null_object());
|
||||
offset += kWordSize;
|
||||
}
|
||||
result->SetCreatedFromSnapshot();
|
||||
} else if (RawObject::IsCanonical(tags)) {
|
||||
*result = result->CheckAndCanonicalize(NULL);
|
||||
ASSERT(!result->IsNull());
|
||||
}
|
||||
if (RawObject::IsCanonical(tags)) {
|
||||
if (kind_ == Snapshot::kFull) {
|
||||
result->SetCanonical();
|
||||
} else {
|
||||
*result = result->CheckAndCanonicalize(NULL);
|
||||
ASSERT(!result->IsNull());
|
||||
}
|
||||
}
|
||||
return result->raw();
|
||||
} else if (header_id == kStaticImplicitClosureObjectId) {
|
||||
|
@ -578,9 +584,6 @@ RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id,
|
|||
#undef SNAPSHOT_READ
|
||||
default: UNREACHABLE(); break;
|
||||
}
|
||||
if (kind_ == Snapshot::kFull) {
|
||||
pobj_.SetCreatedFromSnapshot();
|
||||
}
|
||||
AddPatchRecord(object_id, patch_object_id, patch_offset);
|
||||
return pobj_.raw();
|
||||
}
|
||||
|
@ -1071,6 +1074,7 @@ RawObject* SnapshotReader::AllocateUninitialized(intptr_t class_id,
|
|||
ASSERT(class_id != kIllegalCid);
|
||||
tags = RawObject::ClassIdTag::update(class_id, tags);
|
||||
tags = RawObject::SizeTag::update(size, tags);
|
||||
tags = RawObject::VMHeapObjectTag::update(is_vm_isolate(), tags);
|
||||
raw_obj->ptr()->tags_ = tags;
|
||||
return raw_obj;
|
||||
}
|
||||
|
@ -1209,9 +1213,6 @@ void SnapshotReader::ArrayReadFrom(intptr_t object_id,
|
|||
const Array& result,
|
||||
intptr_t len,
|
||||
intptr_t tags) {
|
||||
// Set the object tags.
|
||||
result.set_tags(tags);
|
||||
|
||||
// Setup the object fields.
|
||||
const intptr_t typeargs_offset =
|
||||
GrowableObjectArray::type_arguments_offset() / kWordSize;
|
||||
|
@ -2053,11 +2054,6 @@ void SnapshotWriter::WriteClassId(RawClass* cls) {
|
|||
ASSERT(kind_ != Snapshot::kFull);
|
||||
int class_id = cls->ptr()->id_;
|
||||
ASSERT(!IsSingletonClassId(class_id) && !IsObjectStoreClassId(class_id));
|
||||
// TODO(5411462): Should restrict this to only core-lib classes in this
|
||||
// case.
|
||||
// Write out the class and tags information.
|
||||
WriteVMIsolateObject(kClassCid);
|
||||
WriteTags(GetObjectTags(cls));
|
||||
|
||||
// Write out the library url and class name.
|
||||
RawLibrary* library = cls->ptr()->library_;
|
||||
|
|
|
@ -450,6 +450,8 @@ class SnapshotReader : public BaseReader {
|
|||
|
||||
RawObject* VmIsolateSnapshotObject(intptr_t index) const;
|
||||
|
||||
bool is_vm_isolate() const;
|
||||
|
||||
Snapshot::Kind kind_; // Indicates type of snapshot(full, script, message).
|
||||
Isolate* isolate_; // Current isolate.
|
||||
Zone* zone_; // Zone for allocations while reading snapshot.
|
||||
|
|
|
@ -18,9 +18,6 @@ ping_test: Skip # Resolve test issues
|
|||
ping_pause_test: Skip # Resolve test issues
|
||||
kill3_test: Pass, Fail # Bad test: expects total message order
|
||||
|
||||
message3_test/constList_identical: RuntimeError # Issue 21816
|
||||
message3_test/constMap: RuntimeError # Issue 21816
|
||||
message3_test/constInstance: RuntimeError # Issue 21816
|
||||
message3_test/byteBuffer: Crash # Issue 21818
|
||||
message3_test/int32x4: Crash # Issue 21818
|
||||
|
||||
|
|
|
@ -394,7 +394,7 @@ void runTests(SendPort ping, Queue checks) {
|
|||
Expect.equals("field", f.field);
|
||||
Expect.isFalse(identical(nonConstF, f));
|
||||
});
|
||||
checks.add((x) { // g1.
|
||||
checks.add((x) { // g2.
|
||||
Expect.isTrue(x is G);
|
||||
Expect.isFalse(identical(g1, x));
|
||||
F f = x.field;
|
||||
|
@ -403,7 +403,7 @@ void runTests(SendPort ping, Queue checks) {
|
|||
});
|
||||
checks.add((x) { // g3.
|
||||
Expect.isTrue(x is G);
|
||||
Expect.identical(g1, x); /// constInstance: continued
|
||||
Expect.identical(g3, x); /// constInstance: continued
|
||||
F f = x.field;
|
||||
Expect.equals("field", f.field);
|
||||
Expect.identical(constF, f); /// constInstance: continued
|
||||
|
|
Loading…
Reference in a new issue