Skip to content

Commit

Permalink
Remove definitions from Kernel canonical names.
Browse files Browse the repository at this point in the history
Before: Canonical names contained pointers to the corresponding Kernel
tree which assumed that the whole tree was in memory whenever the
canonical names were.

Now: Canonical names do not contain these pointers.  They were only
really used to perform name-based lookup in the VM's heap so the
canonical name itself is enough.

If we later find that we need to get from a canonical name to its
Kernel tree we can add an offset in the binary (for instance) to the
canonical name or in a separate mapping on the side.

BUG=
R=asgerf@google.com, jensj@google.com, vegorov@google.com

Committed: ed77783
Review-Url: https://codereview.chromium.org/2781893004 .
  • Loading branch information
Kevin Millikin committed Mar 30, 2017
1 parent cc1ba09 commit d562f7c
Show file tree
Hide file tree
Showing 10 changed files with 412 additions and 355 deletions.
1 change: 1 addition & 0 deletions pkg/kernel/lib/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,7 @@ class Procedure extends Member {
bool get isAccessor => isGetter || isSetter;
bool get hasGetter => kind != ProcedureKind.Setter;
bool get hasSetter => kind == ProcedureKind.Setter;
bool get isFactory => kind == ProcedureKind.Factory;

accept(MemberVisitor v) => v.visitProcedure(this);

Expand Down
8 changes: 7 additions & 1 deletion pkg/kernel/lib/canonical_name.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import 'ast.dart';
/// "@fields"
/// Qualified name
///
/// Procedure that is not an accessor:
/// Procedure that is not an accessor or factory:
/// Canonical name of enclosing class or library
/// "@methods"
/// Qualified name
Expand All @@ -45,6 +45,11 @@ import 'ast.dart';
/// "@setters"
/// Qualified name
///
/// Procedure that is a factory:
/// Canonical name of enclosing class
/// "@factories"
/// Qualified name
///
/// Qualified name:
/// if private: URI of library
/// Name text
Expand Down Expand Up @@ -136,6 +141,7 @@ class CanonicalName {
if (member is Procedure) {
if (member.isGetter) return '@getters';
if (member.isSetter) return '@setters';
if (member.isFactory) return '@factories';
return '@methods';
}
if (member is Field) {
Expand Down
4 changes: 2 additions & 2 deletions runtime/tests/vm/vm.status
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,6 @@ dart/data_uri_import_test/nomime: CompileTimeError
dart/data_uri_import_test/percentencoded: CompileTimeError
dart/data_uri_import_test/wrongmime: CompileTimeError
dart/data_uri_spawn_test: RuntimeError
dart/redirection_type_shuffling_test/00: RuntimeError
dart/redirection_type_shuffling_test/none: RuntimeError
dart/redirection_type_shuffling_test/00: Crash # Issue 29201
dart/redirection_type_shuffling_test/none: Crash # Issue 29201
dart/spawn_shutdown_test: Timeout
202 changes: 133 additions & 69 deletions runtime/vm/kernel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,6 @@ CanonicalName* CanonicalName::NewRoot() {
}


void CanonicalName::BindTo(LinkedNode* new_target) {
ASSERT(new_target != NULL);
if (definition_ == new_target) return;
ASSERT(definition_ == NULL);
ASSERT(new_target->canonical_name_ == NULL);
definition_ = new_target;
new_target->canonical_name_ = this;
}


void CanonicalName::Unbind() {
if (definition_ == NULL) return;
ASSERT(definition_->canonical_name_ == this);
definition_->canonical_name_ = NULL;
definition_ = NULL;
}


CanonicalName* CanonicalName::AddChild(String* name) {
CanonicalName* child = new CanonicalName();
child->parent_ = this;
Expand All @@ -60,33 +42,153 @@ CanonicalName* CanonicalName::AddChild(String* name) {
}


Library* CanonicalName::AsLibrary() {
return Library::Cast(definition());
bool CanonicalName::IsAdministrative() {
// Administrative names start with '@'.
return (name()->size() > 0) && (name()->buffer()[0] == '@');
}


bool CanonicalName::IsPrivate() {
// Private names start with '_'.
return (name()->size() > 0) && (name()->buffer()[0] == '_');
}


Class* CanonicalName::AsClass() {
return Class::Cast(definition());
bool CanonicalName::IsRoot() {
// The root is the only canonical name with no parent.
return parent() == NULL;
}


Member* CanonicalName::AsMember() {
return Member::Cast(definition());
bool CanonicalName::IsLibrary() {
// Libraries are the only canonical names with the root as their parent.
return !IsRoot() && parent()->IsRoot();
}


Field* CanonicalName::AsField() {
return Field::Cast(definition());
bool CanonicalName::IsClass() {
// Classes have the library as their parent and are not an administrative
// name starting with @.
return !IsAdministrative() && !IsRoot() && parent()->IsLibrary();
}


Constructor* CanonicalName::AsConstructor() {
return Constructor::Cast(definition());
bool CanonicalName::IsMember() {
return IsConstructor() || IsField() || IsProcedure();
}


Procedure* CanonicalName::AsProcedure() {
return Procedure::Cast(definition());
// Note the two occurrences of the parameter 'literal'.
#define COMPARE_NAME(canonical_name, literal) \
memcmp((canonical_name)->name()->buffer(), (literal), strlen(literal)) == 0

bool CanonicalName::IsField() {
// Fields with private names have the import URI of the library where they are
// visible as the parent and the string "@fields" as the parent's parent.
// Fields with non-private names have the string "@fields' as the parent.
if (IsRoot()) {
return false;
}
CanonicalName* kind = this->parent();
if (IsPrivate()) {
kind = kind->parent();
}
return COMPARE_NAME(kind, "@fields");
}


bool CanonicalName::IsConstructor() {
// Constructors with private names have the import URI of the library where
// they are visible as the parent and the string "@constructors" as the
// parent's parent. Constructors with non-private names have the string
// "@constructors" as the parent.
if (IsRoot()) {
return false;
}
CanonicalName* kind = this->parent();
if (IsPrivate()) {
kind = kind->parent();
}
return COMPARE_NAME(kind, "@constructors");
}


bool CanonicalName::IsProcedure() {
return IsMethod() || IsGetter() || IsSetter() || IsFactory();
}


bool CanonicalName::IsMethod() {
// Methods with private names have the import URI of the library where they
// are visible as the parent and the string "@methods" as the parent's parent.
// Methods with non-private names have the string "@methods" as the parent.
if (IsRoot()) {
return false;
}
CanonicalName* kind = this->parent();
if (IsPrivate()) {
kind = kind->parent();
}
return COMPARE_NAME(kind, "@methods");
}


bool CanonicalName::IsGetter() {
// Getters with private names have the import URI of the library where they
// are visible as the parent and the string "@getters" as the parent's parent.
// Getters with non-private names have the string "@getters" as the parent.
if (IsRoot()) {
return false;
}
CanonicalName* kind = this->parent();
if (IsPrivate()) {
kind = kind->parent();
}
return COMPARE_NAME(kind, "@getters");
}


bool CanonicalName::IsSetter() {
// Setters with private names have the import URI of the library where they
// are visible as the parent and the string "@setters" as the parent's parent.
// Setters with non-private names have the string "@setters" as the parent.
if (IsRoot()) {
return false;
}
CanonicalName* kind = this->parent();
if (IsPrivate()) {
kind = kind->parent();
}
return COMPARE_NAME(kind, "@setters");
}


bool CanonicalName::IsFactory() {
// Factories with private names have the import URI of the library where they
// are visible as the parent and the string "@factories" as the parent's
// parent. Factories with non-private names have the string "@factories" as
// the parent.
if (IsRoot()) {
return false;
}
CanonicalName* kind = this->parent();
if (IsPrivate()) {
kind = kind->parent();
}
return COMPARE_NAME(kind, "@factories");
}

#undef COMPARE_NAME


CanonicalName* CanonicalName::EnclosingName() {
ASSERT(IsField() || IsConstructor() || IsProcedure());
CanonicalName* enclosing = parent()->parent();
if (IsPrivate()) {
enclosing = enclosing->parent();
}
ASSERT(enclosing->IsLibrary() || enclosing->IsClass());
return enclosing;
}


Expand Down Expand Up @@ -135,11 +237,6 @@ void NormalClass::AcceptClassVisitor(ClassVisitor* visitor) {
}


void NormalClass::AcceptReferenceVisitor(ClassReferenceVisitor* visitor) {
visitor->VisitNormalClassReference(this);
}


void NormalClass::VisitChildren(Visitor* visitor) {
VisitList(&type_parameters(), visitor);
if (super_class() != NULL) visitor->VisitInterfaceType(super_class());
Expand All @@ -158,11 +255,6 @@ void MixinClass::AcceptClassVisitor(ClassVisitor* visitor) {
}


void MixinClass::AcceptReferenceVisitor(ClassReferenceVisitor* visitor) {
visitor->VisitMixinClassReference(this);
}


void MixinClass::VisitChildren(Visitor* visitor) {
VisitList(&type_parameters(), visitor);
visitor->VisitInterfaceType(first());
Expand All @@ -188,11 +280,6 @@ void Field::AcceptMemberVisitor(MemberVisitor* visitor) {
}


void Field::AcceptReferenceVisitor(MemberReferenceVisitor* visitor) {
visitor->VisitFieldReference(this);
}


void Field::VisitChildren(Visitor* visitor) {
type()->AcceptDartTypeVisitor(visitor);
visitor->VisitName(name());
Expand All @@ -208,11 +295,6 @@ void Constructor::AcceptMemberVisitor(MemberVisitor* visitor) {
}


void Constructor::AcceptReferenceVisitor(MemberReferenceVisitor* visitor) {
visitor->VisitConstructorReference(this);
}


void Constructor::VisitChildren(Visitor* visitor) {
visitor->VisitName(name());
visitor->VisitFunctionNode(function());
Expand All @@ -228,11 +310,6 @@ void Procedure::AcceptMemberVisitor(MemberVisitor* visitor) {
}


void Procedure::AcceptReferenceVisitor(MemberReferenceVisitor* visitor) {
visitor->VisitProcedureReference(this);
}


void Procedure::VisitChildren(Visitor* visitor) {
visitor->VisitName(name());
if (function() != NULL) visitor->VisitFunctionNode(function());
Expand Down Expand Up @@ -267,7 +344,6 @@ void FieldInitializer::AcceptInitializerVisitor(InitializerVisitor* visitor) {


void FieldInitializer::VisitChildren(Visitor* visitor) {
visitor->VisitFieldReference(field());
value()->AcceptExpressionVisitor(visitor);
}

Expand All @@ -281,7 +357,6 @@ void SuperInitializer::AcceptInitializerVisitor(InitializerVisitor* visitor) {


void SuperInitializer::VisitChildren(Visitor* visitor) {
visitor->VisitConstructorReference(target());
visitor->VisitArguments(arguments());
}

Expand All @@ -296,7 +371,6 @@ void RedirectingInitializer::AcceptInitializerVisitor(


void RedirectingInitializer::VisitChildren(Visitor* visitor) {
visitor->VisitConstructorReference(target());
visitor->VisitArguments(arguments());
}

Expand Down Expand Up @@ -413,7 +487,6 @@ void DirectPropertyGet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {

void DirectPropertyGet::VisitChildren(Visitor* visitor) {
receiver()->AcceptExpressionVisitor(visitor);
target()->AcceptReferenceVisitor(visitor);
}


Expand All @@ -427,7 +500,6 @@ void DirectPropertySet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {

void DirectPropertySet::VisitChildren(Visitor* visitor) {
receiver()->AcceptExpressionVisitor(visitor);
target()->AcceptReferenceVisitor(visitor);
value()->AcceptExpressionVisitor(visitor);
}

Expand All @@ -440,9 +512,7 @@ void StaticGet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
}


void StaticGet::VisitChildren(Visitor* visitor) {
target()->AcceptReferenceVisitor(visitor);
}
void StaticGet::VisitChildren(Visitor* visitor) {}


StaticSet::~StaticSet() {}
Expand All @@ -454,7 +524,6 @@ void StaticSet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {


void StaticSet::VisitChildren(Visitor* visitor) {
target()->AcceptReferenceVisitor(visitor);
expression()->AcceptExpressionVisitor(visitor);
}

Expand Down Expand Up @@ -513,7 +582,6 @@ void DirectMethodInvocation::AcceptExpressionVisitor(

void DirectMethodInvocation::VisitChildren(Visitor* visitor) {
receiver()->AcceptExpressionVisitor(visitor);
visitor->VisitProcedureReference(target());
visitor->VisitArguments(arguments());
}

Expand All @@ -527,7 +595,6 @@ void StaticInvocation::AcceptExpressionVisitor(ExpressionVisitor* visitor) {


void StaticInvocation::VisitChildren(Visitor* visitor) {
visitor->VisitProcedureReference(procedure());
visitor->VisitArguments(arguments());
}

Expand All @@ -542,7 +609,6 @@ void ConstructorInvocation::AcceptExpressionVisitor(


void ConstructorInvocation::VisitChildren(Visitor* visitor) {
visitor->VisitConstructorReference(target());
visitor->VisitArguments(arguments());
}

Expand Down Expand Up @@ -1194,7 +1260,6 @@ void InterfaceType::AcceptDartTypeVisitor(DartTypeVisitor* visitor) {


void InterfaceType::VisitChildren(Visitor* visitor) {
klass()->AcceptReferenceVisitor(visitor);
VisitList(&type_arguments(), visitor);
}

Expand Down Expand Up @@ -1258,7 +1323,6 @@ void Program::AcceptTreeVisitor(TreeVisitor* visitor) {

void Program::VisitChildren(Visitor* visitor) {
VisitList(&libraries(), visitor);
visitor->VisitProcedureReference(main_method());
}


Expand Down

0 comments on commit d562f7c

Please sign in to comment.