[vm] Fix @pragma detection in KernelLoader.
Change-Id: If09f26a27f84bbed4841eb6d868aea38af564e4a
Cq-Include-Trybots: luci.dart.try:vm-kernel-win-release-x64-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/68362
Reviewed-by: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index c688a31..41d2016 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -1567,7 +1567,7 @@
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 @@
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 @@
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 5595412..ac2c227 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -182,7 +182,8 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
*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 @@
// 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 @@
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 @@
// 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 @@
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 8a24d34..671e71b 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -273,6 +273,15 @@
}
}
+ 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 @@
GrowableObjectArray& potential_natives_;
GrowableObjectArray& potential_extension_libraries_;
+ Class& pragma_class_;
+
Mapping<Library> libraries_;
Mapping<Class> classes_;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6ba5988..b9f0f7b 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -12508,6 +12508,7 @@
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 @@
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 @@
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 85af75f..d4e3f63 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4106,6 +4106,7 @@
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 @@
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 52c0f09..ab1af6d 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1239,7 +1239,12 @@
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<RawObject**>(&ptr()->potential_natives_);
+ }
};
class RawCode : public RawObject {
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 2609707..7d6bc72 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -1334,7 +1334,8 @@
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 @@
// 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,