Skip to content

Commit

Permalink
Various redemptions
Browse files Browse the repository at this point in the history
R=efortuna@google.com

Review-Url: https://codereview.chromium.org/2994333002 .
  • Loading branch information
johnniwinther committed Aug 17, 2017
1 parent 7ad43da commit 49b064d
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 68 deletions.
5 changes: 4 additions & 1 deletion pkg/compiler/lib/src/common_elements.dart
Expand Up @@ -1329,9 +1329,12 @@ abstract class ElementEnvironment {
/// `Object`.
DartType getTypeVariableBound(TypeVariableEntity typeVariable);

/// Returns the type if [function].
/// Returns the type of [function].
FunctionType getFunctionType(FunctionEntity function);

/// Returns the type of [field].
DartType getFieldType(FieldEntity field);

/// Returns the type of the [local] function.
FunctionType getLocalFunctionType(Local local);

Expand Down
19 changes: 13 additions & 6 deletions pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
Expand Up @@ -48,7 +48,7 @@ class Collector {
/// This flag is updated in [computeNeededConstants].
bool outputContainsConstantList = false;

final List<ClassElement> nativeClassesAndSubclasses = <ClassElement>[];
final List<ClassEntity> nativeClassesAndSubclasses = <ClassEntity>[];

List<TypedefEntity> typedefsNeededForReflection;

Expand Down Expand Up @@ -88,7 +88,7 @@ class Collector {
*/
Function computeClassFilter() {
if (_mirrorsData.isTreeShakingDisabled) {
return (ClassElement cls) => true;
return (ClassEntity cls) => true;
}

Set<ClassEntity> unneededClasses = new Set<ClassEntity>();
Expand Down Expand Up @@ -136,17 +136,24 @@ class Collector {
if (_mirrorsData.mustRetainMetadata) {
// TODO(floitsch): verify that we don't run through the same elements
// multiple times.
for (MemberElement element in _generatedCode.keys) {
for (MemberEntity element in _generatedCode.keys) {
if (_mirrorsData.isMemberAccessibleByReflection(element)) {
_mirrorsData.retainMetadataOfMember(element);
}
}
for (ClassElement cls in neededClasses) {
for (ClassEntity cls in neededClasses) {
final onlyForRti = classesOnlyNeededForRti.contains(cls);
if (!onlyForRti) {
_mirrorsData.retainMetadataOfClass(cls);
new FieldVisitor(_options, _elementEnvironment, _worldBuilder,
_nativeData, _mirrorsData, _namer, _closedWorld)
new FieldVisitor(
_options,
_elementEnvironment,
_commonElements,
_worldBuilder,
_nativeData,
_mirrorsData,
_namer,
_closedWorld)
.visitFields((FieldEntity member,
js.Name name,
js.Name accessorName,
Expand Down
18 changes: 10 additions & 8 deletions pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
Expand Up @@ -28,6 +28,7 @@ typedef void AcceptField(FieldEntity member, js.Name name, js.Name accessorName,
class FieldVisitor {
final CompilerOptions _options;
final ElementEnvironment _elementEnvironment;
final CommonElements _commonElements;
final CodegenWorldBuilder _codegenWorldBuilder;
final NativeData _nativeData;
final MirrorsData _mirrorsData;
Expand All @@ -37,6 +38,7 @@ class FieldVisitor {
FieldVisitor(
this._options,
this._elementEnvironment,
this._commonElements,
this._codegenWorldBuilder,
this._nativeData,
this._mirrorsData,
Expand All @@ -46,13 +48,13 @@ class FieldVisitor {
/**
* Invokes [f] for each of the fields of [element].
*
* [element] must be a [ClassElement] or a [LibraryElement].
* [element] must be a [ClassEntity] or a [LibraryEntity].
*
* If [element] is a [ClassElement], the static fields of the class are
* If [element] is a [ClassEntity], the static fields of the class are
* visited if [visitStatics] is true and the instance fields are visited if
* [visitStatics] is false.
*
* If [element] is a [LibraryElement], [visitStatics] must be true.
* If [element] is a [LibraryEntity], [visitStatics] must be true.
*
* When visiting the instance fields of a class, the fields of its superclass
* are also visited if the class is instantiated.
Expand All @@ -79,8 +81,8 @@ class FieldVisitor {
isLibrary = true;
assert(visitStatics, failedAt(library));
} else {
failedAt(NO_LOCATION_SPANNABLE,
'Expected a ClassElement or a LibraryElement.');
failedAt(
NO_LOCATION_SPANNABLE, 'Expected a ClassEntity or a LibraryEntity.');
}

void visitField(FieldEntity field, {ClassEntity holder}) {
Expand Down Expand Up @@ -175,10 +177,10 @@ class FieldVisitor {
field is ClosureFieldElement;
}

bool canAvoidGeneratedCheckedSetter(FieldElement member) {
bool canAvoidGeneratedCheckedSetter(FieldEntity member) {
// We never generate accessors for top-level/static fields.
if (!member.isInstanceMember) return true;
ResolutionDartType type = member.type;
return type.treatAsDynamic || type.isObject;
DartType type = _elementEnvironment.getFieldType(member);
return type.treatAsDynamic || type == _commonElements.objectType;
}
}
Expand Up @@ -15,16 +15,8 @@ import '../../constants/values.dart'
import '../../common_elements.dart' show CommonElements, ElementEnvironment;
import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit;
import '../../elements/elements.dart'
show
ClassElement,
FieldElement,
FunctionSignature,
LibraryElement,
MemberElement,
MethodElement,
ParameterElement;
show ClassElement, FieldElement, LibraryElement, MethodElement;
import '../../elements/entities.dart';
import '../../elements/resolution_types.dart' show ResolutionDartType;
import '../../elements/types.dart';
import '../../js/js.dart' as js;
import '../../js_backend/backend.dart' show SuperMemberData;
Expand Down Expand Up @@ -192,7 +184,7 @@ class ProgramBuilder {
///
/// Also contains classes that are not tracked by the profile run (like
/// interceptors, ...).
Set<ClassElement> _notSoftDeferred;
Set<ClassEntity> _notSoftDeferred;

Program buildProgram({bool storeFunctionTypesInMetadata: false}) {
collector.collect();
Expand Down Expand Up @@ -326,24 +318,25 @@ class ProgramBuilder {

String data = new File(allocatedClassesPath).readAsStringSync();
Set<String> allocatedClassesKeys = JSON.decode(data).keys.toSet();
Set<ClassElement> allocatedClasses = new Set<ClassElement>();
Set<ClassEntity> allocatedClasses = new Set<ClassEntity>();

// Collects all super and mixin classes of a class.
void collect(ClassElement element) {
void collect(ClassEntity element) {
allocatedClasses.add(element);
if (element.isMixinApplication) {
if (_elementEnvironment.isMixinApplication(element)) {
collect(_elementEnvironment.getEffectiveMixinClass(element));
}
if (element.superclass != null) {
collect(element.superclass);
ClassEntity superclass = _elementEnvironment.getSuperClass(element);
if (superclass != null) {
collect(superclass);
}
}

// For every known class, see if it was allocated in the profile. If yes,
// collect its dependencies (supers and mixins) and mark them as
// not-soft-deferrable.
collector.outputClassLists.forEach((_, List<ClassEntity> elements) {
for (ClassElement element in elements) {
for (ClassEntity element in elements) {
// TODO(29574): share the encoding of the element with the code
// that emits the profile-run.
var key = "${element.library.canonicalUri}:${element.name}";
Expand Down Expand Up @@ -562,7 +555,7 @@ class ProgramBuilder {

if (member.isFunction) {
MethodElement fn = member;
functionType = fn.type;
functionType = _elementEnvironment.getFunctionType(fn);
} else if (member.isGetter) {
if (_options.trustTypeAnnotations) {
DartType returnType =
Expand Down Expand Up @@ -786,7 +779,7 @@ class ProgramBuilder {
for (Field field in instanceFields) {
if (field.needsCheckedSetter) {
assert(!field.needsUncheckedSetter);
FieldElement element = field.element;
FieldEntity element = field.element;
js.Expression code = _generatedCode[element];
assert(code != null);
js.Name name = _namer.deriveSetterName(field.accessorName);
Expand Down Expand Up @@ -863,23 +856,28 @@ class ProgramBuilder {
_closedWorld.getMightBePassedToApply(method);
}

/* Map | List */ _computeParameterDefaultValues(FunctionSignature signature) {
/* Map | List */ _computeParameterDefaultValues(FunctionEntity method) {
var /* Map | List */ optionalParameterDefaultValues;
if (signature.optionalParametersAreNamed) {
ParameterStructure parameterStructure = method.parameterStructure;
if (parameterStructure.namedParameters.isNotEmpty) {
optionalParameterDefaultValues = new Map<String, ConstantValue>();
signature.forEachOptionalParameter((_parameter) {
ParameterElement parameter = _parameter;
ConstantValue def =
_constantHandler.getConstantValue(parameter.constant);
optionalParameterDefaultValues[parameter.name] = def;
_worldBuilder.forEachParameter(method,
(DartType type, String name, ConstantValue defaultValue) {
if (parameterStructure.namedParameters.contains(name)) {
assert(defaultValue != null);
optionalParameterDefaultValues[name] = defaultValue;
}
});
} else {
optionalParameterDefaultValues = <ConstantValue>[];
signature.forEachOptionalParameter((_parameter) {
ParameterElement parameter = _parameter;
ConstantValue def =
_constantHandler.getConstantValue(parameter.constant);
optionalParameterDefaultValues.add(def);
int index = 0;
_worldBuilder.forEachParameter(method,
(DartType type, String name, ConstantValue defaultValue) {
if (index >= parameterStructure.requiredParameters) {
assert(defaultValue != null);
optionalParameterDefaultValues.add(defaultValue);
}
index++;
});
}
return optionalParameterDefaultValues;
Expand Down Expand Up @@ -945,11 +943,10 @@ class ProgramBuilder {
var /* List | Map */ optionalParameterDefaultValues;
if (canBeApplied || canBeReflected) {
// TODO(redemption): Handle function entities.
MethodElement method = element;
FunctionSignature signature = method.functionSignature;
requiredParameterCount = signature.requiredParameterCount;
optionalParameterDefaultValues =
_computeParameterDefaultValues(signature);
FunctionEntity method = element;
ParameterStructure parameterStructure = method.parameterStructure;
requiredParameterCount = parameterStructure.requiredParameters;
optionalParameterDefaultValues = _computeParameterDefaultValues(method);
}

return new InstanceMethod(element, name, code,
Expand Down Expand Up @@ -995,7 +992,7 @@ class ProgramBuilder {
/// Stub methods may have an element that can be used for code-size
/// attribution.
Method _buildStubMethod(js.Name name, js.Expression code,
{MemberElement element}) {
{MemberEntity element}) {
return new StubMethod(name, code, element: element);
}

Expand Down Expand Up @@ -1085,8 +1082,15 @@ class ProgramBuilder {
needsCheckedSetter));
}

FieldVisitor visitor = new FieldVisitor(_options, _elementEnvironment,
_worldBuilder, _nativeData, _mirrorsData, _namer, _closedWorld);
FieldVisitor visitor = new FieldVisitor(
_options,
_elementEnvironment,
_commonElements,
_worldBuilder,
_nativeData,
_mirrorsData,
_namer,
_closedWorld);
visitor.visitFields(visitField,
visitStatics: visitStatics, library: library, cls: cls);

Expand Down Expand Up @@ -1152,11 +1156,10 @@ class ProgramBuilder {
var /* List | Map */ optionalParameterDefaultValues;
if (canBeApplied || canBeReflected) {
// TODO(redemption): Support entities;
MethodElement method = element;
FunctionSignature signature = method.functionSignature;
requiredParameterCount = signature.requiredParameterCount;
optionalParameterDefaultValues =
_computeParameterDefaultValues(signature);
FunctionEntity method = element;
ParameterStructure parameterStructure = method.parameterStructure;
requiredParameterCount = parameterStructure.requiredParameters;
optionalParameterDefaultValues = _computeParameterDefaultValues(method);
}

// TODO(floitsch): we shouldn't update the registry in the middle of
Expand Down
Expand Up @@ -12,7 +12,7 @@ class LibraryContents {
/// Maps [LibraryEntity]s to their [ClassEntity]s and [MemberEntity]s.
///
/// Fundamentally, this class nicely encapsulates a
/// `Map<LibraryElement, Pair<List<ClassElement>, List<MemberElement>>>`.
/// `Map<LibraryEntity, Pair<List<ClassEntity>, List<MemberEntity>>>`.
///
/// There exists exactly one instance per [OutputUnit].
class LibrariesMap {
Expand Down
7 changes: 2 additions & 5 deletions pkg/compiler/lib/src/js_emitter/type_test_registry.dart
Expand Up @@ -6,9 +6,7 @@ library dart2js.js_emitter.type_test_registry;

import '../common.dart';
import '../common_elements.dart';
import '../elements/elements.dart' show MethodElement;
import '../elements/entities.dart';
import '../elements/types.dart' show DartType;
import '../elements/types.dart';
import '../js_backend/runtime_types.dart'
show
Expand Down Expand Up @@ -168,9 +166,8 @@ class TypeTestRegistry {
liveMembers.where((MemberEntity element) {
return canBeReflectedAsFunction(element) && canBeReified(element);
}).forEach((_function) {
// TODO(redemption): Support entities.
MethodElement function = _function;
FunctionType type = function.type;
FunctionEntity function = _function;
FunctionType type = _elementEnvironment.getFunctionType(function);
for (ClassEntity cls in _rtiChecks.getReferencedClasses(type)) {
while (cls != null) {
_rtiNeededClasses.add(cls);
Expand Down
6 changes: 6 additions & 0 deletions pkg/compiler/lib/src/js_model/closure.dart
Expand Up @@ -508,6 +508,12 @@ class ClosureFunctionData extends ClosureMemberData implements FunctionData {
class ClosureFieldData extends ClosureMemberData implements FieldData {
ClosureFieldData(MemberDefinition definition) : super(definition);

@override
DartType getFieldType(KernelToElementMap elementMap) {
// A closure field doesn't have a Dart type.
return null;
}

@override
ConstantExpression getFieldConstant(
KernelToElementMap elementMap, FieldEntity field) {
Expand Down
11 changes: 11 additions & 0 deletions pkg/compiler/lib/src/kernel/element_map_impl.dart
Expand Up @@ -619,6 +619,12 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin {
return data.getFunctionType(this);
}

DartType _getFieldType(IndexedField field) {
assert(checkFamily(field));
FieldData data = _memberData[field.memberIndex];
return data.getFieldType(this);
}

ClassEntity _getAppliedMixin(IndexedClass cls) {
assert(checkFamily(cls));
ClassData data = _classData[cls.classIndex];
Expand Down Expand Up @@ -1336,6 +1342,11 @@ class KernelElementEnvironment implements ElementEnvironment {
return elementMap._getFunctionType(function);
}

@override
DartType getFieldType(FieldEntity field) {
return elementMap._getFieldType(field);
}

@override
FunctionType getLocalFunctionType(covariant KLocalFunction function) {
return function.functionType;
Expand Down
7 changes: 7 additions & 0 deletions pkg/compiler/lib/src/kernel/env.dart
Expand Up @@ -563,18 +563,25 @@ class ConstructorDataImpl extends FunctionDataImpl implements ConstructorData {
}

abstract class FieldData extends MemberData {
DartType getFieldType(KernelToElementMap elementMap);

ConstantExpression getFieldConstant(
KernelToElementMapBase elementMap, FieldEntity field);
}

class FieldDataImpl extends MemberDataImpl implements FieldData {
DartType _type;
ConstantExpression _constant;

FieldDataImpl(ir.Field node, MemberDefinition definition)
: super(node, definition);

ir.Field get node => super.node;

DartType getFieldType(covariant KernelToElementMapBase elementMap) {
return _type ??= elementMap.getDartType(node.type);
}

ConstantExpression getFieldConstant(
KernelToElementMapBase elementMap, FieldEntity field) {
if (_constant == null) {
Expand Down

0 comments on commit 49b064d

Please sign in to comment.