Revert "[vm] Track metadata by identity instead of name."
This reverts commit bfd382820f.
Reason for revert: Breaks several lib_2/mirrors/ tests
Original change's description:
> [vm] Track metadata by identity instead of name.
>
> Remove the use of Fields, which have since the metadata mechanism was introduced come to require global registration.
>
> TEST=ci
> Change-Id: Ic2e0c4408557514507fd732e0cb19b022b2539c7
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/161631
> Commit-Queue: Ryan Macnak <rmacnak@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
TBR=kustermann@google.com,aam@google.com,rmacnak@google.com
Change-Id: Icf75e91872d9c85ce9be29a9a178d72ca024c98b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174920
Reviewed-by: Clement Skau <cskau@google.com>
Commit-Queue: Clement Skau <cskau@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
923facf226
commit
c5eb666bcf
@@ -435,12 +435,11 @@ static InstancePtr CreateLibraryDependencyMirror(Thread* thread,
|
||||
const LibraryPrefix& prefix,
|
||||
const bool is_import,
|
||||
const bool is_deferred) {
|
||||
const Library& importee = Library::Handle(ns.target());
|
||||
const Library& importee = Library::Handle(ns.library());
|
||||
const Array& show_names = Array::Handle(ns.show_names());
|
||||
const Array& hide_names = Array::Handle(ns.hide_names());
|
||||
|
||||
const Library& owner = Library::Handle(ns.owner());
|
||||
Object& metadata = Object::Handle(owner.GetMetadata(ns));
|
||||
Object& metadata = Object::Handle(ns.GetMetadata());
|
||||
if (metadata.IsError()) {
|
||||
Exceptions::PropagateError(Error::Cast(metadata));
|
||||
UNREACHABLE();
|
||||
|
||||
@@ -254,38 +254,6 @@ class CanonicalTypeArgumentsTraits {
|
||||
typedef UnorderedHashSet<CanonicalTypeArgumentsTraits>
|
||||
CanonicalTypeArgumentsSet;
|
||||
|
||||
class MetadataMapTraits {
|
||||
public:
|
||||
static const char* Name() { return "MetadataMapTraits"; }
|
||||
static bool ReportStats() { return false; }
|
||||
static bool IsMatch(const Object& key, const Object& candidate) {
|
||||
return key.raw() == candidate.raw();
|
||||
}
|
||||
static uword Hash(const Object& key) {
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
if (key.IsLibrary()) {
|
||||
return String::Hash(Library::Cast(key).url());
|
||||
} else if (key.IsClass()) {
|
||||
return String::Hash(Class::Cast(key).Name());
|
||||
} else if (key.IsPatchClass()) {
|
||||
return Hash(Object::Handle(PatchClass::Cast(key).patched_class()));
|
||||
} else if (key.IsFunction()) {
|
||||
return CombineHashes(String::Hash(Function::Cast(key).name()),
|
||||
Hash(Object::Handle(Function::Cast(key).Owner())));
|
||||
} else if (key.IsField()) {
|
||||
return CombineHashes(String::Hash(Field::Cast(key).name()),
|
||||
Hash(Object::Handle(Field::Cast(key).Owner())));
|
||||
} else if (key.IsTypeParameter()) {
|
||||
return TypeParameter::Cast(key).Hash();
|
||||
} else if (key.IsNamespace()) {
|
||||
return Hash(Library::Handle(Namespace::Cast(key).target()));
|
||||
}
|
||||
#endif
|
||||
UNREACHABLE();
|
||||
}
|
||||
};
|
||||
typedef UnorderedHashMap<MetadataMapTraits> MetadataMap;
|
||||
|
||||
} // namespace dart
|
||||
|
||||
#endif // RUNTIME_VM_CANONICAL_TABLES_H_
|
||||
|
||||
@@ -5836,12 +5836,7 @@ ZoneGrowableArray<Object*>* Serializer::Serialize(SerializationRoots* roots) {
|
||||
WriteUnsigned(num_objects);
|
||||
WriteUnsigned(canonical_clusters.length());
|
||||
WriteUnsigned(clusters.length());
|
||||
// TODO(dartbug.com/36097): Not every snapshot carries the field table.
|
||||
if (current_loading_unit_id_ <= LoadingUnit::kRootId) {
|
||||
WriteUnsigned(initial_field_table_->NumFieldIds());
|
||||
} else {
|
||||
WriteUnsigned(0);
|
||||
}
|
||||
WriteUnsigned(initial_field_table_->NumFieldIds());
|
||||
|
||||
for (SerializationCluster* cluster : canonical_clusters) {
|
||||
cluster->WriteAndMeasureAlloc(this);
|
||||
@@ -6577,8 +6572,8 @@ void Deserializer::Deserialize(DeserializationRoots* roots) {
|
||||
refs_ = Array::New(num_objects_ + kFirstReference, Heap::kOld);
|
||||
if (initial_field_table_len > 0) {
|
||||
initial_field_table_->AllocateIndex(initial_field_table_len - 1);
|
||||
ASSERT_EQUAL(initial_field_table_->NumFieldIds(), initial_field_table_len);
|
||||
}
|
||||
ASSERT_EQUAL(initial_field_table_->NumFieldIds(), initial_field_table_len);
|
||||
|
||||
{
|
||||
NoSafepointScope no_safepoint;
|
||||
|
||||
@@ -2117,9 +2117,47 @@ void Precompiler::TraceTypesFromRetainedClasses() {
|
||||
|
||||
void Precompiler::DropMetadata() {
|
||||
Library& lib = Library::Handle(Z);
|
||||
const GrowableObjectArray& null_growable_list =
|
||||
GrowableObjectArray::Handle(Z);
|
||||
Array& dependencies = Array::Handle(Z);
|
||||
Namespace& ns = Namespace::Handle(Z);
|
||||
const Field& null_field = Field::Handle(Z);
|
||||
GrowableObjectArray& metadata = GrowableObjectArray::Handle(Z);
|
||||
Field& metadata_field = Field::Handle(Z);
|
||||
|
||||
for (intptr_t i = 0; i < libraries_.Length(); i++) {
|
||||
lib ^= libraries_.At(i);
|
||||
lib.set_metadata(Array::null_array());
|
||||
metadata ^= lib.metadata();
|
||||
for (intptr_t j = 0; j < metadata.Length(); j++) {
|
||||
metadata_field ^= metadata.At(j);
|
||||
if (metadata_field.is_static()) {
|
||||
// Although this field will become garbage after clearing the list
|
||||
// below, we also need to clear its value from the field table.
|
||||
// The value may be an instance of an otherwise dead class, and if
|
||||
// it remains in the field table we can get an instance on the heap
|
||||
// with a deleted class.
|
||||
metadata_field.SetStaticValue(Object::null_instance(),
|
||||
/*save_initial_value=*/true);
|
||||
}
|
||||
}
|
||||
|
||||
lib.set_metadata(null_growable_list);
|
||||
|
||||
dependencies = lib.imports();
|
||||
for (intptr_t j = 0; j < dependencies.Length(); j++) {
|
||||
ns ^= dependencies.At(j);
|
||||
if (!ns.IsNull()) {
|
||||
ns.set_metadata_field(null_field);
|
||||
}
|
||||
}
|
||||
|
||||
dependencies = lib.exports();
|
||||
for (intptr_t j = 0; j < dependencies.Length(); j++) {
|
||||
ns ^= dependencies.At(j);
|
||||
if (!ns.IsNull()) {
|
||||
ns.set_metadata_field(null_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6007,7 +6007,7 @@ DART_EXPORT Dart_Handle Dart_GetImportsOfScheme(Dart_Handle scheme) {
|
||||
for (intptr_t j = 0; j < imports.Length(); j++) {
|
||||
ns ^= imports.At(j);
|
||||
if (ns.IsNull()) continue;
|
||||
importee = ns.target();
|
||||
importee = ns.library();
|
||||
importee_uri = importee.url();
|
||||
if (importee_uri.StartsWith(scheme_vm)) {
|
||||
result.Add(importer);
|
||||
|
||||
@@ -961,7 +961,7 @@ void IsolateGroupReloadContext::BuildModifiedLibrariesClosure(
|
||||
for (intptr_t import_idx = 0; import_idx < ports.Length(); import_idx++) {
|
||||
ns ^= ports.At(import_idx);
|
||||
if (!ns.IsNull()) {
|
||||
target = ns.target();
|
||||
target = ns.library();
|
||||
target_url = target.url();
|
||||
if (!target_url.StartsWith(Symbols::DartExtensionScheme())) {
|
||||
(*imported_by)[target.index()]->Add(lib.index());
|
||||
@@ -974,7 +974,7 @@ void IsolateGroupReloadContext::BuildModifiedLibrariesClosure(
|
||||
for (intptr_t export_idx = 0; export_idx < ports.Length(); export_idx++) {
|
||||
ns ^= ports.At(export_idx);
|
||||
if (!ns.IsNull()) {
|
||||
target = ns.target();
|
||||
target = ns.library();
|
||||
(*imported_by)[target.index()]->Add(lib.index());
|
||||
}
|
||||
}
|
||||
@@ -992,7 +992,7 @@ void IsolateGroupReloadContext::BuildModifiedLibrariesClosure(
|
||||
import_idx++) {
|
||||
ns ^= ports.At(import_idx);
|
||||
if (!ns.IsNull()) {
|
||||
target = ns.target();
|
||||
target = ns.library();
|
||||
(*imported_by)[target.index()]->Add(lib.index());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,28 +430,26 @@ class MetadataEvaluator : public KernelReaderHelper {
|
||||
DISALLOW_COPY_AND_ASSIGN(MetadataEvaluator);
|
||||
};
|
||||
|
||||
ObjectPtr EvaluateMetadata(const Library& library,
|
||||
intptr_t kernel_offset,
|
||||
ObjectPtr EvaluateMetadata(const Field& metadata_field,
|
||||
bool is_annotations_offset) {
|
||||
LongJumpScope jump;
|
||||
if (setjmp(*jump.Set()) == 0) {
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
TranslationHelper helper(thread);
|
||||
Script& script = Script::Handle(
|
||||
zone, Class::Handle(zone, library.toplevel_class()).script());
|
||||
Script& script = Script::Handle(zone, metadata_field.Script());
|
||||
helper.InitFromScript(script);
|
||||
|
||||
const Class& owner_class = Class::Handle(zone, library.toplevel_class());
|
||||
const Class& owner_class = Class::Handle(zone, metadata_field.Owner());
|
||||
ActiveClass active_class;
|
||||
ActiveClassScope active_class_scope(&active_class, &owner_class);
|
||||
|
||||
MetadataEvaluator metadata_evaluator(
|
||||
zone, &helper, script,
|
||||
ExternalTypedData::Handle(zone, library.kernel_data()),
|
||||
library.kernel_offset(), &active_class);
|
||||
ExternalTypedData::Handle(zone, metadata_field.KernelData()),
|
||||
metadata_field.KernelDataProgramOffset(), &active_class);
|
||||
|
||||
return metadata_evaluator.EvaluateMetadata(kernel_offset,
|
||||
return metadata_evaluator.EvaluateMetadata(metadata_field.kernel_offset(),
|
||||
is_annotations_offset);
|
||||
|
||||
} else {
|
||||
|
||||
+1
-2
@@ -196,8 +196,7 @@ class KernelLineStartsReader {
|
||||
void CollectTokenPositionsFor(const Script& script);
|
||||
|
||||
ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field);
|
||||
ObjectPtr EvaluateMetadata(const Library& library,
|
||||
intptr_t kernel_offset,
|
||||
ObjectPtr EvaluateMetadata(const Field& metadata_field,
|
||||
bool is_annotations_offset);
|
||||
ObjectPtr BuildParameterDescriptor(const Function& function);
|
||||
|
||||
|
||||
@@ -694,7 +694,7 @@ void KernelLoader::LoadNativeExtensionLibraries() {
|
||||
// Dart_GetImportsOfScheme('dart-ext').
|
||||
const auto& native_library = Library::Handle(Library::New(uri_path));
|
||||
library.AddImport(Namespace::Handle(Namespace::New(
|
||||
native_library, Array::null_array(), Array::null_array(), library)));
|
||||
native_library, Array::null_array(), Array::null_array())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1122,7 +1122,8 @@ LibraryPtr KernelLoader::LoadLibrary(intptr_t index) {
|
||||
|
||||
if (FLAG_enable_mirrors && annotation_count > 0) {
|
||||
ASSERT(annotations_kernel_offset > 0);
|
||||
library.AddMetadata(library, annotations_kernel_offset);
|
||||
library.AddLibraryMetadata(toplevel_class, TokenPosition::kNoSource,
|
||||
annotations_kernel_offset);
|
||||
}
|
||||
|
||||
if (register_class) {
|
||||
@@ -1247,7 +1248,7 @@ void KernelLoader::FinishTopLevelClassLoading(
|
||||
|
||||
if ((FLAG_enable_mirrors || has_pragma_annotation) &&
|
||||
annotation_count > 0) {
|
||||
library.AddMetadata(field, field_offset);
|
||||
library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset);
|
||||
}
|
||||
fields_.Add(&field);
|
||||
}
|
||||
@@ -1365,7 +1366,7 @@ void KernelLoader::LoadLibraryImportsAndExports(Library* library,
|
||||
"import of dart:ffi is not supported in the current Dart runtime");
|
||||
}
|
||||
String& prefix = H.DartSymbolPlain(dependency_helper.name_index_);
|
||||
ns = Namespace::New(target_library, show_names, hide_names, *library);
|
||||
ns = Namespace::New(target_library, show_names, hide_names);
|
||||
if ((dependency_helper.flags_ & LibraryDependencyHelper::Export) != 0) {
|
||||
library->AddExport(ns);
|
||||
} else {
|
||||
@@ -1388,7 +1389,8 @@ void KernelLoader::LoadLibraryImportsAndExports(Library* library,
|
||||
|
||||
if (FLAG_enable_mirrors && dependency_helper.annotation_count_ > 0) {
|
||||
ASSERT(annotations_kernel_offset > 0);
|
||||
library->AddMetadata(ns, annotations_kernel_offset);
|
||||
ns.AddMetadata(toplevel_class, TokenPosition::kNoSource,
|
||||
annotations_kernel_offset);
|
||||
}
|
||||
|
||||
if (prefix.IsNull()) {
|
||||
@@ -1509,7 +1511,9 @@ void KernelLoader::LoadClass(const Library& library,
|
||||
}
|
||||
|
||||
if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) {
|
||||
library.AddMetadata(*out_class, class_offset - correction_offset_);
|
||||
library.AddClassMetadata(*out_class, toplevel_class,
|
||||
TokenPosition::kNoSource,
|
||||
class_offset - correction_offset_);
|
||||
}
|
||||
|
||||
// We do not register expression evaluation classes with the VM:
|
||||
@@ -1621,7 +1625,7 @@ void KernelLoader::FinishClassLoading(const Class& klass,
|
||||
}
|
||||
if ((FLAG_enable_mirrors || has_pragma_annotation) &&
|
||||
annotation_count > 0) {
|
||||
library.AddMetadata(field, field_offset);
|
||||
library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset);
|
||||
}
|
||||
fields_.Add(&field);
|
||||
}
|
||||
@@ -1720,7 +1724,8 @@ void KernelLoader::FinishClassLoading(const Class& klass,
|
||||
|
||||
if ((FLAG_enable_mirrors || has_pragma_annotation) &&
|
||||
annotation_count > 0) {
|
||||
library.AddMetadata(function, constructor_offset);
|
||||
library.AddFunctionMetadata(function, TokenPosition::kNoSource,
|
||||
constructor_offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2044,7 +2049,8 @@ void KernelLoader::LoadProcedure(const Library& library,
|
||||
helper_.SetOffset(procedure_end);
|
||||
|
||||
if (annotation_count > 0) {
|
||||
library.AddMetadata(function, procedure_offset);
|
||||
library.AddFunctionMetadata(function, TokenPosition::kNoSource,
|
||||
procedure_offset);
|
||||
}
|
||||
|
||||
if (has_pragma_annotation) {
|
||||
|
||||
+248
-59
@@ -11586,25 +11586,175 @@ void Library::SetLoaded() const {
|
||||
StoreNonPointer(&raw_ptr()->load_state_, LibraryLayout::kLoaded);
|
||||
}
|
||||
|
||||
void Library::AddMetadata(const Object& declaration,
|
||||
static StringPtr MakeClassMetaName(Thread* thread,
|
||||
Zone* zone,
|
||||
const Class& cls) {
|
||||
return Symbols::FromConcat(thread, Symbols::At(),
|
||||
String::Handle(zone, cls.Name()));
|
||||
}
|
||||
|
||||
static StringPtr MakeFieldMetaName(Thread* thread,
|
||||
Zone* zone,
|
||||
const Field& field) {
|
||||
const String& cname = String::Handle(
|
||||
zone,
|
||||
MakeClassMetaName(thread, zone, Class::Handle(zone, field.Origin())));
|
||||
GrowableHandlePtrArray<const String> pieces(zone, 3);
|
||||
pieces.Add(cname);
|
||||
pieces.Add(Symbols::At());
|
||||
pieces.Add(String::Handle(zone, field.name()));
|
||||
return Symbols::FromConcatAll(thread, pieces);
|
||||
}
|
||||
|
||||
static StringPtr MakeFunctionMetaName(Thread* thread,
|
||||
Zone* zone,
|
||||
const Function& func) {
|
||||
const String& cname = String::Handle(
|
||||
zone,
|
||||
MakeClassMetaName(thread, zone, Class::Handle(zone, func.origin())));
|
||||
GrowableHandlePtrArray<const String> pieces(zone, 3);
|
||||
pieces.Add(cname);
|
||||
pieces.Add(Symbols::At());
|
||||
pieces.Add(String::Handle(zone, func.name()));
|
||||
return Symbols::FromConcatAll(thread, pieces);
|
||||
}
|
||||
|
||||
static StringPtr MakeTypeParameterMetaName(Thread* thread,
|
||||
Zone* zone,
|
||||
const TypeParameter& param) {
|
||||
const String& cname = String::Handle(
|
||||
zone,
|
||||
MakeClassMetaName(thread, zone,
|
||||
Class::Handle(zone, param.parameterized_class())));
|
||||
GrowableHandlePtrArray<const String> pieces(zone, 3);
|
||||
pieces.Add(cname);
|
||||
pieces.Add(Symbols::At());
|
||||
pieces.Add(String::Handle(zone, param.name()));
|
||||
return Symbols::FromConcatAll(thread, pieces);
|
||||
}
|
||||
|
||||
void Library::AddMetadata(const Object& owner,
|
||||
const String& name,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
UNREACHABLE();
|
||||
#else
|
||||
MetadataMap map(metadata());
|
||||
map.UpdateOrInsert(declaration, Smi::Handle(Smi::New(kernel_offset)));
|
||||
set_metadata(map.Release());
|
||||
Thread* thread = Thread::Current();
|
||||
ASSERT(thread->IsMutatorThread());
|
||||
Zone* zone = thread->zone();
|
||||
const String& metaname = String::Handle(zone, Symbols::New(thread, name));
|
||||
const Field& field =
|
||||
Field::Handle(zone, Field::NewTopLevel(metaname,
|
||||
false, // is_final
|
||||
false, // is_const
|
||||
false, // is_late
|
||||
owner, token_pos, token_pos));
|
||||
field.SetFieldType(Object::dynamic_type());
|
||||
field.set_is_reflectable(false);
|
||||
field.set_kernel_offset(kernel_offset);
|
||||
thread->isolate_group()->RegisterStaticField(field, Array::empty_array());
|
||||
|
||||
GrowableObjectArray& metadata =
|
||||
GrowableObjectArray::Handle(zone, this->metadata());
|
||||
metadata.Add(field, Heap::kOld);
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
}
|
||||
|
||||
ObjectPtr Library::GetMetadata(const Object& declaration) const {
|
||||
void Library::AddClassMetadata(const Class& cls,
|
||||
const Object& tl_owner,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const {
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
// We use the toplevel class as the owner of a class's metadata field because
|
||||
// a class's metadata is in scope of the library, not the class.
|
||||
AddMetadata(tl_owner,
|
||||
String::Handle(zone, MakeClassMetaName(thread, zone, cls)),
|
||||
token_pos, kernel_offset);
|
||||
}
|
||||
|
||||
void Library::AddFieldMetadata(const Field& field,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const {
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
const auto& owner = Object::Handle(zone, field.RawOwner());
|
||||
const auto& name =
|
||||
String::Handle(zone, MakeFieldMetaName(thread, zone, field));
|
||||
AddMetadata(owner, name, token_pos, kernel_offset);
|
||||
}
|
||||
|
||||
void Library::AddFunctionMetadata(const Function& func,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const {
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
const auto& owner = Object::Handle(zone, func.RawOwner());
|
||||
const auto& name =
|
||||
String::Handle(zone, MakeFunctionMetaName(thread, zone, func));
|
||||
AddMetadata(owner, name, token_pos, kernel_offset);
|
||||
}
|
||||
|
||||
void Library::AddTypeParameterMetadata(const TypeParameter& param,
|
||||
TokenPosition token_pos) const {
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
const auto& owner = Class::Handle(zone, param.parameterized_class());
|
||||
const auto& name =
|
||||
String::Handle(zone, MakeTypeParameterMetaName(thread, zone, param));
|
||||
AddMetadata(owner, name, token_pos, 0);
|
||||
}
|
||||
|
||||
void Library::AddLibraryMetadata(const Object& tl_owner,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const {
|
||||
AddMetadata(tl_owner, Symbols::TopLevel(), token_pos, kernel_offset);
|
||||
}
|
||||
|
||||
StringPtr Library::MakeMetadataName(const Object& obj) const {
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
if (obj.IsClass()) {
|
||||
return MakeClassMetaName(thread, zone, Class::Cast(obj));
|
||||
} else if (obj.IsField()) {
|
||||
return MakeFieldMetaName(thread, zone, Field::Cast(obj));
|
||||
} else if (obj.IsFunction()) {
|
||||
return MakeFunctionMetaName(thread, zone, Function::Cast(obj));
|
||||
} else if (obj.IsLibrary()) {
|
||||
return Symbols::TopLevel().raw();
|
||||
} else if (obj.IsTypeParameter()) {
|
||||
return MakeTypeParameterMetaName(thread, zone, TypeParameter::Cast(obj));
|
||||
}
|
||||
UNIMPLEMENTED();
|
||||
return String::null();
|
||||
}
|
||||
|
||||
FieldPtr Library::GetMetadataField(const String& metaname) const {
|
||||
const GrowableObjectArray& metadata =
|
||||
GrowableObjectArray::Handle(this->metadata());
|
||||
Field& entry = Field::Handle();
|
||||
String& entryname = String::Handle();
|
||||
intptr_t num_entries = metadata.Length();
|
||||
for (intptr_t i = 0; i < num_entries; i++) {
|
||||
entry ^= metadata.At(i);
|
||||
entryname = entry.name();
|
||||
if (entryname.Equals(metaname)) {
|
||||
return entry.raw();
|
||||
}
|
||||
}
|
||||
return Field::null();
|
||||
}
|
||||
|
||||
ObjectPtr Library::GetMetadata(const Object& obj) const {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
return Object::empty_array().raw();
|
||||
#else
|
||||
RELEASE_ASSERT(declaration.IsClass() || declaration.IsField() ||
|
||||
declaration.IsFunction() || declaration.IsLibrary() ||
|
||||
declaration.IsTypeParameter() || declaration.IsNamespace());
|
||||
if (declaration.IsLibrary()) {
|
||||
if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction() &&
|
||||
!obj.IsLibrary() && !obj.IsTypeParameter()) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (obj.IsLibrary()) {
|
||||
// Ensure top-level class is loaded as it may contain annotations of
|
||||
// a library.
|
||||
const auto& cls = Class::Handle(toplevel_class());
|
||||
@@ -11612,36 +11762,31 @@ ObjectPtr Library::GetMetadata(const Object& declaration) const {
|
||||
cls.EnsureDeclarationLoaded();
|
||||
}
|
||||
}
|
||||
Object& value = Object::Handle();
|
||||
{
|
||||
MetadataMap map(metadata());
|
||||
value = map.GetOrNull(declaration);
|
||||
set_metadata(map.Release());
|
||||
}
|
||||
if (value.IsNull()) {
|
||||
const String& metaname = String::Handle(MakeMetadataName(obj));
|
||||
Field& field = Field::Handle(GetMetadataField(metaname));
|
||||
if (field.IsNull()) {
|
||||
// There is no metadata for this object.
|
||||
return Object::empty_array().raw();
|
||||
}
|
||||
if (!value.IsSmi()) {
|
||||
// Metadata is already evaluated.
|
||||
ASSERT(value.IsArray());
|
||||
return value.raw();
|
||||
}
|
||||
intptr_t kernel_offset = Smi::Cast(value).Value();
|
||||
ASSERT(kernel_offset > 0);
|
||||
value = kernel::EvaluateMetadata(
|
||||
*this, kernel_offset,
|
||||
/* is_annotations_offset = */ declaration.IsLibrary() ||
|
||||
declaration.IsNamespace());
|
||||
if (value.IsArray() || value.IsNull()) {
|
||||
ASSERT(value.raw() != Object::empty_array().raw());
|
||||
if (!Compiler::IsBackgroundCompilation()) {
|
||||
MetadataMap map(metadata());
|
||||
map.UpdateOrInsert(declaration, value);
|
||||
set_metadata(map.Release());
|
||||
Object& metadata = Object::Handle(field.StaticValue());
|
||||
if (metadata.raw() == Object::empty_array().raw()) {
|
||||
ASSERT(field.kernel_offset() > 0);
|
||||
metadata = kernel::EvaluateMetadata(
|
||||
field, /* is_annotations_offset = */ obj.IsLibrary());
|
||||
if (metadata.IsArray() || metadata.IsNull()) {
|
||||
ASSERT(metadata.raw() != Object::empty_array().raw());
|
||||
if (!Compiler::IsBackgroundCompilation()) {
|
||||
field.SetStaticValue(
|
||||
metadata.IsNull() ? Object::null_array() : Array::Cast(metadata),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return value.raw();
|
||||
if (metadata.IsNull()) {
|
||||
// Metadata field exists in order to reference extended metadata.
|
||||
return Object::empty_array().raw();
|
||||
}
|
||||
return metadata.raw();
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
}
|
||||
|
||||
@@ -12188,7 +12333,7 @@ ObjectPtr Library::LookupImportedObject(const String& name) const {
|
||||
import = ImportAt(i);
|
||||
obj = import.Lookup(name);
|
||||
if (!obj.IsNull()) {
|
||||
import_lib = import.target();
|
||||
import_lib = import.library();
|
||||
import_lib_url = import_lib.url();
|
||||
if (found_obj.raw() != obj.raw()) {
|
||||
if (first_import_lib_url.IsNull() ||
|
||||
@@ -12312,7 +12457,7 @@ void Library::set_dependencies(const Array& deps) const {
|
||||
raw_ptr()->set_dependencies(deps.raw());
|
||||
}
|
||||
|
||||
void Library::set_metadata(const Array& value) const {
|
||||
void Library::set_metadata(const GrowableObjectArray& value) const {
|
||||
raw_ptr()->set_metadata(value.raw());
|
||||
}
|
||||
|
||||
@@ -12321,7 +12466,7 @@ LibraryPtr Library::ImportLibraryAt(intptr_t index) const {
|
||||
if (import.IsNull()) {
|
||||
return Library::null();
|
||||
}
|
||||
return import.target();
|
||||
return import.library();
|
||||
}
|
||||
|
||||
NamespacePtr Library::ImportAt(intptr_t index) const {
|
||||
@@ -12343,7 +12488,7 @@ void Library::DropDependenciesAndCaches() const {
|
||||
for (int i = 0; i < imports.Length(); ++i) {
|
||||
ns = Namespace::RawCast(imports.At(i));
|
||||
if (ns.IsNull()) continue;
|
||||
lib = ns.target();
|
||||
lib = ns.library();
|
||||
url = lib.url();
|
||||
if (url.StartsWith(Symbols::DartExtensionScheme())) {
|
||||
native_import_count++;
|
||||
@@ -12354,7 +12499,7 @@ void Library::DropDependenciesAndCaches() const {
|
||||
for (int i = 0, j = 0; i < imports.Length(); ++i) {
|
||||
ns = Namespace::RawCast(imports.At(i));
|
||||
if (ns.IsNull()) continue;
|
||||
lib = ns.target();
|
||||
lib = ns.library();
|
||||
url = lib.url();
|
||||
if (url.StartsWith(Symbols::DartExtensionScheme())) {
|
||||
new_imports.SetAt(j++, ns);
|
||||
@@ -12472,11 +12617,10 @@ LibraryPtr Library::NewLibraryHelper(const String& url, bool import_core_lib) {
|
||||
result.raw_ptr()->set_resolved_names(Array::null());
|
||||
result.raw_ptr()->set_exported_names(Array::null());
|
||||
result.raw_ptr()->set_dictionary(Object::empty_array().raw());
|
||||
Array& array = Array::Handle(zone);
|
||||
array = HashTables::New<MetadataMap>(4, Heap::kOld);
|
||||
result.raw_ptr()->set_metadata(array.raw());
|
||||
result.raw_ptr()->set_toplevel_class(Class::null());
|
||||
GrowableObjectArray& list = GrowableObjectArray::Handle(zone);
|
||||
list = GrowableObjectArray::New(4, Heap::kOld);
|
||||
result.raw_ptr()->set_metadata(list.raw());
|
||||
result.raw_ptr()->set_toplevel_class(Class::null());
|
||||
list = GrowableObjectArray::New(Object::empty_array(), Heap::kOld);
|
||||
result.raw_ptr()->set_used_scripts(list.raw());
|
||||
result.raw_ptr()->set_imports(Object::empty_array().raw());
|
||||
@@ -12506,9 +12650,9 @@ LibraryPtr Library::NewLibraryHelper(const String& url, bool import_core_lib) {
|
||||
if (import_core_lib) {
|
||||
const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
|
||||
ASSERT(!core_lib.IsNull());
|
||||
const Namespace& ns =
|
||||
Namespace::Handle(zone, Namespace::New(core_lib, Object::null_array(),
|
||||
Object::null_array(), result));
|
||||
const Namespace& ns = Namespace::Handle(
|
||||
zone,
|
||||
Namespace::New(core_lib, Object::null_array(), Object::null_array()));
|
||||
result.AddImport(ns);
|
||||
}
|
||||
return result.raw();
|
||||
@@ -13133,7 +13277,7 @@ LibraryPtr LibraryPrefix::GetLibrary(int index) const {
|
||||
const Array& imports = Array::Handle(this->imports());
|
||||
Namespace& import = Namespace::Handle();
|
||||
import ^= imports.At(index);
|
||||
return import.target();
|
||||
return import.library();
|
||||
}
|
||||
return Library::null();
|
||||
}
|
||||
@@ -13203,8 +13347,59 @@ const char* LibraryPrefix::ToCString() const {
|
||||
return prefix.ToCString();
|
||||
}
|
||||
|
||||
void Namespace::set_metadata_field(const Field& value) const {
|
||||
raw_ptr()->set_metadata_field(value.raw());
|
||||
}
|
||||
|
||||
void Namespace::AddMetadata(const Object& owner,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) {
|
||||
auto thread = Thread::Current();
|
||||
auto zone = thread->zone();
|
||||
auto isolate_group = thread->isolate_group();
|
||||
ASSERT(Field::Handle(zone, metadata_field()).IsNull());
|
||||
Field& field =
|
||||
Field::Handle(zone, Field::NewTopLevel(Symbols::TopLevel(),
|
||||
false, // is_final
|
||||
false, // is_const
|
||||
false, // is_late
|
||||
owner, token_pos, token_pos));
|
||||
field.set_is_reflectable(false);
|
||||
field.SetFieldType(Object::dynamic_type());
|
||||
field.set_kernel_offset(kernel_offset);
|
||||
isolate_group->RegisterStaticField(field, Array::empty_array());
|
||||
set_metadata_field(field);
|
||||
}
|
||||
|
||||
ObjectPtr Namespace::GetMetadata() const {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
return Object::empty_array().raw();
|
||||
#else
|
||||
Field& field = Field::Handle(metadata_field());
|
||||
if (field.IsNull()) {
|
||||
// There is no metadata for this object.
|
||||
return Object::empty_array().raw();
|
||||
}
|
||||
Object& metadata = Object::Handle();
|
||||
metadata = field.StaticValue();
|
||||
if (field.StaticValue() == Object::empty_array().raw()) {
|
||||
if (field.kernel_offset() > 0) {
|
||||
metadata =
|
||||
kernel::EvaluateMetadata(field, /* is_annotations_offset = */ true);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (metadata.IsArray()) {
|
||||
ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw());
|
||||
field.SetStaticValue(Array::Cast(metadata), true);
|
||||
}
|
||||
}
|
||||
return metadata.raw();
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
}
|
||||
|
||||
const char* Namespace::ToCString() const {
|
||||
const Library& lib = Library::Handle(target());
|
||||
const Library& lib = Library::Handle(library());
|
||||
return OS::SCreate(Thread::Current()->zone(), "Namespace for library '%s'",
|
||||
lib.ToCString());
|
||||
}
|
||||
@@ -13258,7 +13453,7 @@ bool Namespace::HidesName(const String& name) const {
|
||||
ObjectPtr Namespace::Lookup(const String& name,
|
||||
ZoneGrowableArray<intptr_t>* trail) const {
|
||||
Zone* zone = Thread::Current()->zone();
|
||||
const Library& lib = Library::Handle(zone, target());
|
||||
const Library& lib = Library::Handle(zone, library());
|
||||
|
||||
if (trail != NULL) {
|
||||
// Look for cycle in reexport graph.
|
||||
@@ -13319,17 +13514,15 @@ NamespacePtr Namespace::New() {
|
||||
return static_cast<NamespacePtr>(raw);
|
||||
}
|
||||
|
||||
NamespacePtr Namespace::New(const Library& target,
|
||||
NamespacePtr Namespace::New(const Library& library,
|
||||
const Array& show_names,
|
||||
const Array& hide_names,
|
||||
const Library& owner) {
|
||||
const Array& hide_names) {
|
||||
ASSERT(show_names.IsNull() || (show_names.Length() > 0));
|
||||
ASSERT(hide_names.IsNull() || (hide_names.Length() > 0));
|
||||
const Namespace& result = Namespace::Handle(Namespace::New());
|
||||
result.raw_ptr()->set_target(target.raw());
|
||||
result.raw_ptr()->set_library(library.raw());
|
||||
result.raw_ptr()->set_show_names(show_names.raw());
|
||||
result.raw_ptr()->set_hide_names(hide_names.raw());
|
||||
result.raw_ptr()->set_owner(owner.raw());
|
||||
return result.raw();
|
||||
}
|
||||
|
||||
@@ -24875,13 +25068,9 @@ ErrorPtr Function::VerifyClosurizedEntryPoint() const {
|
||||
const Library& lib = Library::Handle(cls.library());
|
||||
switch (kind()) {
|
||||
case FunctionLayout::kRegularFunction:
|
||||
case FunctionLayout::kImplicitClosureFunction:
|
||||
return dart::VerifyEntryPoint(lib, *this, *this,
|
||||
{EntryPointPragma::kGetterOnly});
|
||||
case FunctionLayout::kImplicitClosureFunction: {
|
||||
const Function& parent = Function::Handle(parent_function());
|
||||
return dart::VerifyEntryPoint(lib, parent, parent,
|
||||
{EntryPointPragma::kGetterOnly});
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
+35
-8
@@ -4738,8 +4738,22 @@ class Library : public Object {
|
||||
|
||||
void AddExport(const Namespace& ns) const;
|
||||
|
||||
void AddMetadata(const Object& declaration, intptr_t kernel_offset) const;
|
||||
ObjectPtr GetMetadata(const Object& declaration) const;
|
||||
void AddClassMetadata(const Class& cls,
|
||||
const Object& tl_owner,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const;
|
||||
void AddFieldMetadata(const Field& field,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const;
|
||||
void AddFunctionMetadata(const Function& func,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const;
|
||||
void AddLibraryMetadata(const Object& tl_owner,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const;
|
||||
void AddTypeParameterMetadata(const TypeParameter& param,
|
||||
TokenPosition token_pos) const;
|
||||
ObjectPtr GetMetadata(const Object& obj) const;
|
||||
|
||||
// Tries to finds a @pragma annotation on [object].
|
||||
//
|
||||
@@ -4964,8 +4978,8 @@ class Library : public Object {
|
||||
void set_flags(uint8_t flags) const;
|
||||
bool HasExports() const;
|
||||
ArrayPtr loaded_scripts() const { return raw_ptr()->loaded_scripts(); }
|
||||
ArrayPtr metadata() const { return raw_ptr()->metadata(); }
|
||||
void set_metadata(const Array& value) const;
|
||||
GrowableObjectArrayPtr metadata() const { return raw_ptr()->metadata(); }
|
||||
void set_metadata(const GrowableObjectArray& value) const;
|
||||
ArrayPtr dictionary() const { return raw_ptr()->dictionary(); }
|
||||
void InitClassDictionary() const;
|
||||
|
||||
@@ -4993,6 +5007,13 @@ class Library : public Object {
|
||||
|
||||
void AllocatePrivateKey() const;
|
||||
|
||||
StringPtr MakeMetadataName(const Object& obj) const;
|
||||
FieldPtr GetMetadataField(const String& metaname) const;
|
||||
void AddMetadata(const Object& owner,
|
||||
const String& name,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset) const;
|
||||
|
||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(Library, Object);
|
||||
|
||||
friend class Bootstrap;
|
||||
@@ -5010,10 +5031,14 @@ class Library : public Object {
|
||||
// the show/hide combinators.
|
||||
class Namespace : public Object {
|
||||
public:
|
||||
LibraryPtr target() const { return raw_ptr()->target(); }
|
||||
LibraryPtr library() const { return raw_ptr()->library(); }
|
||||
ArrayPtr show_names() const { return raw_ptr()->show_names(); }
|
||||
ArrayPtr hide_names() const { return raw_ptr()->hide_names(); }
|
||||
LibraryPtr owner() const { return raw_ptr()->owner(); }
|
||||
|
||||
void AddMetadata(const Object& owner,
|
||||
TokenPosition token_pos,
|
||||
intptr_t kernel_offset = 0);
|
||||
ObjectPtr GetMetadata() const;
|
||||
|
||||
static intptr_t InstanceSize() {
|
||||
return RoundedAllocationSize(sizeof(NamespaceLayout));
|
||||
@@ -5025,12 +5050,14 @@ class Namespace : public Object {
|
||||
|
||||
static NamespacePtr New(const Library& library,
|
||||
const Array& show_names,
|
||||
const Array& hide_names,
|
||||
const Library& owner);
|
||||
const Array& hide_names);
|
||||
|
||||
private:
|
||||
static NamespacePtr New();
|
||||
|
||||
FieldPtr metadata_field() const { return raw_ptr()->metadata_field(); }
|
||||
void set_metadata_field(const Field& value) const;
|
||||
|
||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(Namespace, Object);
|
||||
friend class Class;
|
||||
friend class Precompiler;
|
||||
|
||||
@@ -519,7 +519,7 @@ void Library::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
||||
jsdep.AddProperty("isDeferred", false);
|
||||
jsdep.AddProperty("isExport", false);
|
||||
jsdep.AddProperty("isImport", true);
|
||||
target = ns.target();
|
||||
target = ns.library();
|
||||
jsdep.AddProperty("target", target);
|
||||
}
|
||||
|
||||
@@ -533,7 +533,7 @@ void Library::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
||||
jsdep.AddProperty("isDeferred", false);
|
||||
jsdep.AddProperty("isExport", true);
|
||||
jsdep.AddProperty("isImport", false);
|
||||
target = ns.target();
|
||||
target = ns.library();
|
||||
jsdep.AddProperty("target", target);
|
||||
}
|
||||
|
||||
@@ -559,7 +559,7 @@ void Library::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
||||
prefix_name = prefix.name();
|
||||
ASSERT(!prefix_name.IsNull());
|
||||
jsdep.AddProperty("prefix", prefix_name.ToCString());
|
||||
target = ns.target();
|
||||
target = ns.library();
|
||||
jsdep.AddProperty("target", target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1409,7 +1409,8 @@ class LibraryLayout : public ObjectLayout {
|
||||
POINTER_FIELD(StringPtr, url)
|
||||
POINTER_FIELD(StringPtr, private_key)
|
||||
POINTER_FIELD(ArrayPtr, dictionary) // Top-level names in this library.
|
||||
POINTER_FIELD(ArrayPtr, metadata) // Metadata on classes, methods etc.
|
||||
POINTER_FIELD(GrowableObjectArrayPtr,
|
||||
metadata) // Metadata on classes, methods etc.
|
||||
POINTER_FIELD(ClassPtr,
|
||||
toplevel_class) // Class containing top-level elements.
|
||||
POINTER_FIELD(GrowableObjectArrayPtr, used_scripts)
|
||||
@@ -1461,12 +1462,14 @@ class LibraryLayout : public ObjectLayout {
|
||||
class NamespaceLayout : public ObjectLayout {
|
||||
RAW_HEAP_OBJECT_IMPLEMENTATION(Namespace);
|
||||
|
||||
VISIT_FROM(ObjectPtr, target)
|
||||
POINTER_FIELD(LibraryPtr, target) // library with name dictionary.
|
||||
VISIT_FROM(ObjectPtr, library)
|
||||
POINTER_FIELD(LibraryPtr, library) // library with name dictionary.
|
||||
POINTER_FIELD(ArrayPtr, show_names) // list of names that are exported.
|
||||
POINTER_FIELD(ArrayPtr, hide_names) // list of names that are hidden.
|
||||
POINTER_FIELD(LibraryPtr, owner)
|
||||
VISIT_TO(ObjectPtr, owner)
|
||||
POINTER_FIELD(FieldPtr,
|
||||
metadata_field) // remembers the token pos of metadata if any,
|
||||
// and the metadata values if computed.
|
||||
VISIT_TO(ObjectPtr, metadata_field)
|
||||
ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -75,10 +75,10 @@ namespace dart {
|
||||
F(Library, resolved_names_) \
|
||||
F(Library, exported_names_) \
|
||||
F(Library, loaded_scripts_) \
|
||||
F(Namespace, target_) \
|
||||
F(Namespace, library_) \
|
||||
F(Namespace, show_names_) \
|
||||
F(Namespace, hide_names_) \
|
||||
F(Namespace, owner_) \
|
||||
F(Namespace, metadata_field_) \
|
||||
F(KernelProgramInfo, string_offsets_) \
|
||||
F(KernelProgramInfo, string_data_) \
|
||||
F(KernelProgramInfo, canonical_names_) \
|
||||
|
||||
Reference in New Issue
Block a user