diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc index c688a316ecfe9..41d201686faa7 100644 --- a/runtime/vm/clustered_snapshot.cc +++ b/runtime/vm/clustered_snapshot.cc @@ -1567,7 +1567,7 @@ class KernelProgramInfoSerializationCluster : public SerializationCluster { objects_.Add(info); RawObject** from = info->from(); - RawObject** to = info->to(); + RawObject** to = info->to_snapshot(s->kind()); for (RawObject** p = from; p <= to; p++) { s->Push(*p); } @@ -1588,7 +1588,7 @@ class KernelProgramInfoSerializationCluster : public SerializationCluster { for (intptr_t i = 0; i < count; i++) { RawKernelProgramInfo* info = objects_[i]; RawObject** from = info->from(); - RawObject** to = info->to(); + RawObject** to = info->to_snapshot(s->kind()); for (RawObject** p = from; p <= to; p++) { s->WriteRef(*p); } @@ -1627,10 +1627,14 @@ class KernelProgramInfoDeserializationCluster : public DeserializationCluster { KernelProgramInfo::InstanceSize(), is_vm_object); RawObject** from = info->from(); - RawObject** to = info->to(); + RawObject** to = info->to_snapshot(d->kind()); + RawObject** end = info->to(); for (RawObject** p = from; p <= to; p++) { *p = d->ReadRef(); } + for (RawObject** p = to + 1; p <= end; p++) { + *p = Object::null(); + } } } }; diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc index 559541213808e..ac2c227910481 100644 --- a/runtime/vm/kernel_loader.cc +++ b/runtime/vm/kernel_loader.cc @@ -182,7 +182,8 @@ KernelLoader::KernelLoader(Program* program) external_name_class_(Class::Handle(Z)), external_name_field_(Field::Handle(Z)), potential_natives_(GrowableObjectArray::Handle(Z)), - potential_extension_libraries_(GrowableObjectArray::Handle(Z)) { + potential_extension_libraries_(GrowableObjectArray::Handle(Z)), + pragma_class_(Class::Handle(Z)) { if (!program->is_single_program()) { FATAL( "Trying to load a concatenated dill file at a time where that is " @@ -283,6 +284,12 @@ void KernelLoader::InitializeFields() { Z, reader.ExternalDataFromTo(reader.offset(), reader.offset() + end_offset)); + // Create a view of the constants table. The trailing ComponentIndex is + // negligible in size. + const ExternalTypedData& constants_table = ExternalTypedData::Handle( + Z, reader.ExternalDataFromTo(program_->constant_table_offset(), + program_->kernel_data_size())); + // Copy the canonical names into the VM's heap. Encode them as unsigned, so // the parent indexes are adjusted when extracted. reader.set_offset(program_->name_table_offset()); @@ -303,8 +310,9 @@ void KernelLoader::InitializeFields() { Z, reader.ExternalDataFromTo(program_->metadata_mappings_offset(), program_->string_table_offset())); - kernel_program_info_ = KernelProgramInfo::New( - offsets, data, names, metadata_payloads, metadata_mappings, scripts); + kernel_program_info_ = + KernelProgramInfo::New(offsets, data, names, metadata_payloads, + metadata_mappings, constants_table, scripts); H.InitFromKernelProgramInfo(kernel_program_info_); @@ -335,7 +343,8 @@ KernelLoader::KernelLoader(const Script& script, external_name_class_(Class::Handle(Z)), external_name_field_(Field::Handle(Z)), potential_natives_(GrowableObjectArray::Handle(Z)), - potential_extension_libraries_(GrowableObjectArray::Handle(Z)) { + potential_extension_libraries_(GrowableObjectArray::Handle(Z)), + pragma_class_(Class::Handle(Z)) { ASSERT(T.active_class_ == &active_class_); T.finalize_ = false; @@ -588,6 +597,7 @@ RawObject* KernelLoader::LoadProgram(bool process_pending_classes) { // c) update all scripts with the constants array ASSERT(kernel_program_info_.constants() == Array::null()); kernel_program_info_.set_constants(constants); + kernel_program_info_.set_constants_table(ExternalTypedData::Handle(Z)); NameIndex main = program_->main_method(); if (main == -1) { @@ -1335,7 +1345,6 @@ void KernelLoader::ReadProcedureAnnotations(intptr_t annotation_count, *is_potential_native = false; *has_pragma_annotation = false; String& detected_name = String::Handle(Z); - Class& pragma_class = Class::Handle(Z, I->object_store()->pragma_class()); for (intptr_t i = 0; i < annotation_count; ++i) { const intptr_t tag = helper_.PeekTag(); if (tag == kConstructorInvocation || tag == kConstConstructorInvocation) { @@ -1361,10 +1370,8 @@ void KernelLoader::ReadProcedureAnnotations(intptr_t annotation_count, // constants in the annotation list to later. *is_potential_native = true; - if (program_ == nullptr) { - helper_.SkipExpression(); - continue; - } + ASSERT(kernel_program_info_.constants_table() != + ExternalTypedData::null()); // For pragma annotations, we seek into the constants table and peek // into the Kernel representation of the constant. @@ -1376,13 +1383,16 @@ void KernelLoader::ReadProcedureAnnotations(intptr_t annotation_count, const intptr_t offset_in_constant_table = helper_.ReadUInt(); - AlternativeReadingScope scope(&helper_.reader_, - program_->constant_table_offset()); + AlternativeReadingScope scope( + &helper_.reader_, + &ExternalTypedData::Handle(Z, + kernel_program_info_.constants_table()), + 0); // Seek into the position within the constant table where we can inspect // this constant's Kernel representation. helper_.ReadUInt(); // skip constant table size - helper_.SetOffset(helper_.ReaderOffset() + offset_in_constant_table); + helper_.SkipBytes(offset_in_constant_table); uint8_t tag = helper_.ReadTag(); if (tag == kInstanceConstant) { *has_pragma_annotation = @@ -1396,6 +1406,9 @@ void KernelLoader::ReadProcedureAnnotations(intptr_t annotation_count, // Obtain `dart:_internal::ExternalName.name`. EnsureExternalClassIsLookedUp(); + // Obtain `dart:_internal::pragma`. + EnsurePragmaClassIsLookedUp(); + const intptr_t constant_table_index = helper_.ReadUInt(); const Object& constant = Object::Handle(constant_table.GetOrDie(constant_table_index)); @@ -1404,7 +1417,7 @@ void KernelLoader::ReadProcedureAnnotations(intptr_t annotation_count, Instance::Handle(Instance::RawCast(constant.raw())); *native_name = String::RawCast(instance.GetField(external_name_field_)); - } else if (constant.clazz() == pragma_class.raw()) { + } else if (constant.clazz() == pragma_class_.raw()) { *has_pragma_annotation = true; } ASSERT(constant_table.Release().raw() == constant_table_array.raw()); diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h index 8a24d34a1bebc..671e71b0a77ef 100644 --- a/runtime/vm/kernel_loader.h +++ b/runtime/vm/kernel_loader.h @@ -273,6 +273,15 @@ class KernelLoader : public ValueObject { } } + void EnsurePragmaClassIsLookedUp() { + if (pragma_class_.IsNull()) { + const Library& internal_lib = + Library::Handle(zone_, dart::Library::InternalLibrary()); + pragma_class_ = internal_lib.LookupClass(Symbols::Pragma()); + ASSERT(!pragma_class_.IsNull()); + } + } + void EnsurePotentialNatives() { potential_natives_ = kernel_program_info_.potential_natives(); if (potential_natives_.IsNull()) { @@ -317,6 +326,8 @@ class KernelLoader : public ValueObject { GrowableObjectArray& potential_natives_; GrowableObjectArray& potential_extension_libraries_; + Class& pragma_class_; + Mapping libraries_; Mapping classes_; diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 6ba5988a88928..b9f0f7b700857 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -12508,6 +12508,7 @@ RawKernelProgramInfo* KernelProgramInfo::New( const TypedData& canonical_names, const ExternalTypedData& metadata_payloads, const ExternalTypedData& metadata_mappings, + const ExternalTypedData& constants_table, const Array& scripts) { const KernelProgramInfo& info = KernelProgramInfo::Handle(KernelProgramInfo::New()); @@ -12519,6 +12520,7 @@ RawKernelProgramInfo* KernelProgramInfo::New( info.StorePointer(&info.raw_ptr()->metadata_mappings_, metadata_mappings.raw()); info.StorePointer(&info.raw_ptr()->scripts_, scripts.raw()); + info.StorePointer(&info.raw_ptr()->constants_table_, constants_table.raw()); return info.raw(); } @@ -12536,6 +12538,11 @@ void KernelProgramInfo::set_constants(const Array& constants) const { StorePointer(&raw_ptr()->constants_, constants.raw()); } +void KernelProgramInfo::set_constants_table( + const ExternalTypedData& value) const { + StorePointer(&raw_ptr()->constants_table_, value.raw()); +} + void KernelProgramInfo::set_potential_natives( const GrowableObjectArray& candidates) const { StorePointer(&raw_ptr()->potential_natives_, candidates.raw()); diff --git a/runtime/vm/object.h b/runtime/vm/object.h index 85af75f5d11b4..d4e3f63c6e1e2 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -4106,6 +4106,7 @@ class KernelProgramInfo : public Object { const TypedData& canonical_names, const ExternalTypedData& metadata_payload, const ExternalTypedData& metadata_mappings, + const ExternalTypedData& constants_table, const Array& scripts); static intptr_t InstanceSize() { @@ -4126,6 +4127,12 @@ class KernelProgramInfo : public Object { return raw_ptr()->metadata_mappings_; } + RawExternalTypedData* constants_table() const { + return raw_ptr()->constants_table_; + } + + void set_constants_table(const ExternalTypedData& value) const; + RawArray* scripts() const { return raw_ptr()->scripts_; } RawArray* constants() const { return raw_ptr()->constants_; } diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index 52c0f0957a679..ab1af6da79fcc 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -1239,7 +1239,12 @@ class RawKernelProgramInfo : public RawObject { RawArray* scripts_; RawArray* constants_; RawGrowableObjectArray* potential_natives_; - VISIT_TO(RawObject*, potential_natives_); + RawExternalTypedData* constants_table_; + VISIT_TO(RawObject*, constants_table_); + + RawObject** to_snapshot(Snapshot::Kind kind) { + return reinterpret_cast(&ptr()->potential_natives_); + } }; class RawCode : public RawObject { diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc index 2609707e3a6c5..7d6bc72f3b358 100644 --- a/runtime/vm/raw_object_snapshot.cc +++ b/runtime/vm/raw_object_snapshot.cc @@ -1334,7 +1334,8 @@ RawKernelProgramInfo* KernelProgramInfo::ReadFrom(SnapshotReader* reader, reader->AddBackRef(object_id, &info, kIsDeserialized); // Set all the object fields. - READ_OBJECT_FIELDS(info, info.raw()->from(), info.raw()->to(), kAsReference); + READ_OBJECT_FIELDS(info, info.raw()->from(), info.raw()->to_snapshot(kind), + kAsReference); return info.raw(); } @@ -1354,7 +1355,7 @@ void RawKernelProgramInfo::WriteTo(SnapshotWriter* writer, // Write out all the object pointer fields. SnapshotWriterVisitor visitor(writer, kAsReference); - visitor.VisitPointers(from(), to()); + visitor.VisitPointers(from(), to_snapshot(kind)); } RawCode* Code::ReadFrom(SnapshotReader* reader,