Extract SuperMemberData from JavaScriptBackend

Yet another move towards passing all information through data objects
computed by previous phases rather than pulling it directly from
Backend or Compiler.

This is needed to support a shift from model K to model J between
resolution and codegen.

R=efortuna@google.com

Review-Url: https://codereview.chromium.org/2783623002 .
This commit is contained in:
Johnni Winther 2017-03-29 11:55:13 +02:00
parent 6f48182a04
commit 72fc95113c
4 changed files with 35 additions and 36 deletions

View file

@ -355,11 +355,6 @@ class JavaScriptBackend {
*/
final Set<ClassElement> specialOperatorEqClasses = new Set<ClassElement>();
/**
* A set of members that are called from subclasses via `super`.
*/
final Set<MethodElement> aliasedSuperMembers = new Setlet<MethodElement>();
List<CompilerTask> get tasks {
List<CompilerTask> result = functionCompiler.tasks;
result.add(emitter);
@ -446,6 +441,8 @@ class JavaScriptBackend {
MirrorsDataImpl _mirrorsData;
CheckedModeHelpers _checkedModeHelpers;
final SuperMemberData superMemberData = new SuperMemberData();
native.NativeResolutionEnqueuer _nativeResolutionEnqueuer;
native.NativeCodegenEnqueuer _nativeCodegenEnqueuer;
@ -742,31 +739,6 @@ class JavaScriptBackend {
!mirrorsData.invokedReflectively(method);
}
/**
* Record that [method] is called from a subclass via `super`.
*/
bool maybeRegisterAliasedSuperMember(
MemberElement member, Selector selector) {
if (!canUseAliasedSuperMember(member, selector)) {
// Invoking a super getter isn't supported, this would require changes to
// compact field descriptors in the emitter.
return false;
}
aliasedSuperMembers.add(member);
return true;
}
bool canUseAliasedSuperMember(Element member, Selector selector) {
return !selector.isGetter;
}
/**
* Returns `true` if [member] is called from a subclass via `super`.
*/
bool isAliasedSuperMember(FunctionElement member) {
return aliasedSuperMembers.contains(member);
}
/// Maps compile-time classes to their runtime class. The runtime class is
/// always a superclass or the class itself.
ClassElement getRuntimeClass(ClassElement class_) {
@ -1618,3 +1590,28 @@ class JavaScriptBackendTarget extends Target {
@override
bool isForeign(Element element) => _backend.isForeign(element);
}
class SuperMemberData {
/// A set of member that are called from subclasses via `super`.
final Set<MemberEntity> _aliasedSuperMembers = new Setlet<MemberEntity>();
/// Record that [member] is called from a subclass via `super`.
bool maybeRegisterAliasedSuperMember(MemberEntity member, Selector selector) {
if (!canUseAliasedSuperMember(member, selector)) {
// Invoking a super getter isn't supported, this would require changes to
// compact field descriptors in the emitter.
return false;
}
_aliasedSuperMembers.add(member);
return true;
}
bool canUseAliasedSuperMember(MemberEntity member, Selector selector) {
return !selector.isGetter;
}
/// Returns `true` if [member] is called from a subclass via `super`.
bool isAliasedSuperMember(MemberEntity member) {
return _aliasedSuperMembers.contains(member);
}
}

View file

@ -701,7 +701,7 @@ class ProgramBuilder {
bool canBeReflected = _methodCanBeReflected(element);
bool canBeApplied = _methodCanBeApplied(element);
js.Name aliasName = backend.isAliasedSuperMember(element)
js.Name aliasName = backend.superMemberData.isAliasedSuperMember(element)
? namer.aliasedSuperMemberPropertyName(element)
: null;

View file

@ -322,7 +322,8 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
.visitGraph(graph);
new SsaTypeKnownRemover().visitGraph(graph);
new SsaTrustedCheckRemover(compiler.options).visitGraph(graph);
new SsaInstructionMerger(generateAtUseSite, backend).visitGraph(graph);
new SsaInstructionMerger(generateAtUseSite, backend.superMemberData)
.visitGraph(graph);
new SsaConditionMerger(generateAtUseSite, controlFlowOperators)
.visitGraph(graph);
SsaLiveIntervalBuilder intervalBuilder =
@ -1900,7 +1901,8 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
}
} else {
Selector selector = node.selector;
if (!backend.maybeRegisterAliasedSuperMember(superElement, selector)) {
if (!backend.superMemberData
.maybeRegisterAliasedSuperMember(superElement, selector)) {
js.Name methodName;
if (selector.isGetter && !superElement.isGetter) {
// If this is a tear-off, register the fact that a tear-off closure

View file

@ -334,7 +334,7 @@ class SsaTrustedCheckRemover extends HBaseVisitor {
* t2 = add(4, 3);
*/
class SsaInstructionMerger extends HBaseVisitor {
final JavaScriptBackend _backend;
final SuperMemberData _superMemberData;
/**
* List of [HInstruction] that the instruction merger expects in
* order when visiting the inputs of an instruction.
@ -353,7 +353,7 @@ class SsaInstructionMerger extends HBaseVisitor {
generateAtUseSite.add(instruction);
}
SsaInstructionMerger(this.generateAtUseSite, this._backend);
SsaInstructionMerger(this.generateAtUseSite, this._superMemberData);
void visitGraph(HGraph graph) {
visitDominatorTree(graph);
@ -436,7 +436,7 @@ class SsaInstructionMerger extends HBaseVisitor {
// after first access if we use lazy initialization.
// In this case, we therefore don't allow the receiver (the first argument)
// to be generated at use site, and only analyze all other arguments.
if (!_backend.canUseAliasedSuperMember(superMethod, selector)) {
if (!_superMemberData.canUseAliasedSuperMember(superMethod, selector)) {
analyzeInputs(instruction, 1);
} else {
super.visitInvokeSuper(instruction);