Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Unified Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10917285: Stub implementation of patch invariants for the patch refactoring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/compiler/implementation/ssa/builder.dart
diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
index bf79a1efc38e9aadf92f818c9b8e3981c3e9d666..af06d16149942fe2b3dd50fe9d6f8ad55a3411ee 100644
--- a/lib/compiler/implementation/ssa/builder.dart
+++ b/lib/compiler/implementation/ssa/builder.dart
@@ -167,7 +167,7 @@ class SsaBuilderTask extends CompilerTask {
HGraph build(WorkItem work) {
return measure(() {
- Element element = work.element;
+ Element element = work.element.implementation;
ngeoffray 2012/09/20 11:38:37 I think in this method you could just use element
Johnni Winther 2012/09/21 09:18:25 But then we would have to change line 182, 184, an
HInstruction.idCounter = 0;
ConstantSystem constantSystem = compiler.backend.constantSystem;
SsaBuilder builder = new SsaBuilder(constantSystem, this, work);
@@ -179,21 +179,21 @@ class SsaBuilderTask extends CompilerTask {
kind === ElementKind.FUNCTION ||
kind === ElementKind.GETTER ||
kind === ElementKind.SETTER) {
- graph = builder.buildMethod(work.element);
+ graph = builder.buildMethod(element);
} else if (kind === ElementKind.FIELD) {
- graph = builder.buildLazyInitializer(work.element);
+ graph = builder.buildLazyInitializer(element);
}
assert(graph.isValid());
if (kind !== ElementKind.FIELD) {
- bool inLoop = functionsCalledInLoop.contains(element);
+ bool inLoop = functionsCalledInLoop.contains(element.declaration);
if (!inLoop) {
Selector selector = selectorsCalledInLoop[element.name];
inLoop = selector !== null && selector.applies(element, compiler);
}
graph.calledInLoop = inLoop;
- // If there is an estimate of the parameter types assume these types when
- // compiling.
+ // If there is an estimate of the parameter types assume these types
+ // when compiling.
OptionalParameterTypes defaultValueTypes = null;
FunctionSignature signature = element.computeSignature(compiler);
if (signature.optionalParameterCount > 0) {
@@ -208,7 +208,8 @@ class SsaBuilderTask extends CompilerTask {
});
}
HTypeList parameterTypes =
- backend.optimisticParameterTypes(element, defaultValueTypes);
+ backend.optimisticParameterTypes(element.declaration,
+ defaultValueTypes);
if (!parameterTypes.allUnknown) {
int i = 0;
signature.forEachParameter((Element param) {
@@ -241,7 +242,7 @@ class SsaBuilderTask extends CompilerTask {
HGraph compileConstructor(SsaBuilder builder, WorkItem work) {
// The body of the constructor will be generated in a separate function.
final ClassElement classElement = work.element.getEnclosingClass();
- return builder.buildFactory(classElement, work.element);
+ return builder.buildFactory(classElement, work.element.implementation);
}
}
@@ -352,8 +353,14 @@ class LocalsHandler {
updateLocal(boxElement, newBox);
}
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [function] must be an implementation element.
+ */
void startFunction(FunctionElement function,
FunctionExpression node) {
+ assert(invariant(function, function.isImplementation));
ahe 2012/09/20 11:12:07 First argument should be node.
Johnni Winther 2012/09/21 09:18:25 Done.
Compiler compiler = builder.compiler;
closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
node, builder.elements);
@@ -897,8 +904,17 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
methodInterceptionEnabled = true;
}
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [functionElement] must be an implementation element.
+ */
HGraph buildMethod(FunctionElement functionElement) {
+ assert(invariant(functionElement, functionElement.isImplementation));
FunctionExpression function = functionElement.parseNode(compiler);
+ assert(function !== null);
+ assert(function.modifiers === null || !function.modifiers.isExternal());
+ assert(elements[function] !== null);
openFunction(functionElement, function);
function.body.accept(this);
return closeFunction();
@@ -928,10 +944,10 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
*/
ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
assert(constructor.isGenerativeConstructor());
+ assert(invariant(constructor, constructor.isImplementation));
if (constructor is SynthesizedConstructorElement) return null;
FunctionExpression node = constructor.parseNode(compiler);
- // If we know the body doesn't have any code, we don't generate
- // it.
+ // If we know the body doesn't have any code, we don't generate it.
if (node.body.asBlock() !== null) {
NodeList statements = node.body.asBlock().statements;
if (statements.isEmpty()) return null;
@@ -953,18 +969,26 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
if (bodyElement === null) {
bodyElement = new ConstructorBodyElement(constructor);
TreeElements treeElements =
ngeoffray 2012/09/20 11:38:37 Please add a comment here on why you need to use d
Johnni Winther 2012/09/21 09:18:25 Done.
- compiler.resolver.resolveMethodElement(constructor);
- compiler.enqueuer.codegen.addToWorkList(bodyElement, treeElements);
+ compiler.resolver.resolveMethodElement(constructor.declaration);
classElement.backendMembers =
classElement.backendMembers.prepend(bodyElement);
+ compiler.enqueuer.codegen.addToWorkList(bodyElement.declaration,
ngeoffray 2012/09/20 11:38:37 We just constructed bodyElement. Could we avoid ha
Johnni Winther 2012/09/21 09:18:25 If [constructor] is a patch we will need both. Thi
+ treeElements);
}
assert(bodyElement.isGenerativeConstructorBody());
return bodyElement;
}
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [function] must be an implementation element.
+ */
InliningState enterInlinedMethod(PartialFunctionElement function,
Selector selector,
Link<Node> arguments) {
+ assert(invariant(function, function.isImplementation));
+
// Once we start to compile the arguments we must be sure that we don't
// abort.
List<HInstruction> compiledArguments = new List<HInstruction>();
@@ -985,6 +1009,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
localsHandler.updateLocal(returnElement,
graph.addConstantNull(constantSystem));
elements = compiler.enqueuer.resolution.getCachedElements(function);
+ assert(elements !== null);
FunctionSignature signature = function.computeSignature(compiler);
int index = 0;
signature.forEachParameter((Element parameter) {
@@ -1008,9 +1033,15 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
stack = state.oldStack;
}
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [element] must be an implementation element.
+ */
bool tryInlineMethod(Element element,
Selector selector,
Link<Node> arguments) {
+ assert(invariant(element, element.isImplementation));
// TODO(floitsch): we should be able to inline inside lazy initializers.
if (!currentElement.isFunction()) return false;
// TODO(floitsch): we should be able to inline getters, setters and
@@ -1051,11 +1082,18 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
return true;
}
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [constructor] and [constructors] must all be implementation
+ * elements.
+ */
void inlineSuperOrRedirect(FunctionElement constructor,
Selector selector,
Link<Node> arguments,
List<FunctionElement> constructors,
Map<Element, HInstruction> fieldValues) {
+ assert(invariant(constructor, constructor.isImplementation));
constructors.addLast(constructor);
List<HInstruction> compiledArguments = new List<HInstruction>();
@@ -1099,10 +1137,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
*
* The constructors of the inlined initializers is added to [constructors]
* with sub constructors having a lower index than super constructors.
+ *
+ * Invariant: The [constructor] and elements in [constructors] must all be
+ * implementation elements.
*/
void buildInitializers(FunctionElement constructor,
List<FunctionElement> constructors,
Map<Element, HInstruction> fieldValues) {
+ assert(invariant(constructor, constructor.isImplementation));
FunctionExpression functionNode = constructor.parseNode(compiler);
bool foundSuperOrRedirect = false;
@@ -1140,7 +1182,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
// the class is not Object.
ClassElement enclosingClass = constructor.getEnclosingClass();
ClassElement superClass = enclosingClass.superclass;
- if (enclosingClass != compiler.objectClass) {
+ if (!enclosingClass.isObject(compiler)) {
assert(superClass !== null);
assert(superClass.resolutionState == STATE_DONE);
Selector selector =
@@ -1149,7 +1191,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
if (target === null) {
compiler.internalError("no default constructor available");
}
- inlineSuperOrRedirect(target,
+ inlineSuperOrRedirect(target.implementation,
selector,
const EmptyLink<Node>(),
constructors,
@@ -1161,9 +1203,12 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
/**
* Run through the fields of [cls] and add their potential
* initializers.
+ *
+ * Invariant: [classElement] must be a declaration element.
*/
void buildFieldInitializers(ClassElement classElement,
Map<Element, HInstruction> fieldValues) {
+ assert(invariant(classElement, classElement.isDeclaration));
classElement.forEachInstanceField(
includeBackendMembers: true,
includeSuperMembers: false,
@@ -1195,9 +1240,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
* to, starting from the current constructor.
* - Call the the constructor bodies, starting from the constructor(s) in the
* super class(es).
+ *
+ * Invariants: [classElement] must be a declaration element, and
+ * [functionElement] must be an implementation element.
*/
HGraph buildFactory(ClassElement classElement,
FunctionElement functionElement) {
+ assert(invariant(classElement, classElement.isDeclaration));
+ assert(invariant(functionElement, functionElement.isImplementation));
FunctionExpression function = functionElement.parseNode(compiler);
// Note that constructors (like any other static function) do not need
// to deal with optional arguments. It is the callers job to provide all
@@ -1255,18 +1305,21 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
// Generate calls to the constructor bodies.
for (int index = constructors.length - 1; index >= 0; index--) {
FunctionElement constructor = constructors[index];
+ assert(invariant(functionElement, constructor.isImplementation));
ConstructorBodyElement body = getConstructorBody(constructor);
if (body === null) continue;
List bodyCallInputs = <HInstruction>[];
bodyCallInputs.add(newObject);
- int arity = body.functionSignature.parameterCount;
- body.functionSignature.forEachParameter((parameter) {
+ FunctionSignature functionSignature = body.computeSignature(compiler);
+ int arity = functionSignature.parameterCount;
+ functionSignature.forEachParameter((parameter) {
bodyCallInputs.add(localsHandler.readLocal(parameter));
});
// TODO(ahe): The constructor name is statically resolved. See
// SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner
// way to do this?
- SourceString name = new SourceString(backend.namer.getName(body));
+ SourceString name =
+ new SourceString(backend.namer.getName(body.declaration));
// TODO(kasperl): This seems fishy. We shouldn't be inventing all
// these selectors. Maybe the resolver can do more of the work
// for us here?
@@ -1324,8 +1377,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
localsHandler.updateLocal(checkResultElement, check);
}
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [functionElement] must be the implementation element.
+ */
void openFunction(FunctionElement functionElement,
FunctionExpression node) {
+ assert(invariant(functionElement, functionElement.isImplementation));
HBasicBlock block = graph.addNewBlock();
open(graph.entry);
@@ -2060,7 +2119,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
} else if (element.isField() && compiler.isLazilyInitialized(element)) {
push(new HLazyStatic(element));
} else {
- push(new HStatic(element));
+ push(new HStatic(element.declaration));
ngeoffray 2012/09/20 11:38:37 Please add TODO to try to get rid of this. Maybe a
Johnni Winther 2012/09/21 09:18:25 Done.
if (element.isGetter()) {
push(new HInvokeStatic(<HInstruction>[pop()]));
}
@@ -2069,7 +2128,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
HInstruction receiver = generateInstanceSendReceiver(send);
generateInstanceGetterWithCompiledReceiver(send, receiver);
} else if (Elements.isStaticOrTopLevelFunction(element)) {
- push(new HStatic(element));
+ push(new HStatic(element.declaration));
ngeoffray 2012/09/20 11:38:37 Ditto.
Johnni Winther 2012/09/21 09:18:25 Done.
// TODO(ahe): This should be registered in codegen.
compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
} else if (Elements.isErroneousElement(element)) {
@@ -2289,11 +2348,15 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
/**
* Returns true if the arguments were compatible with the function signature.
+ *
+ * Invariant: [element] must be an implementation element.
*/
bool addStaticSendArgumentsToList(Selector selector,
Link<Node> arguments,
FunctionElement element,
List<HInstruction> list) {
+ assert(invariant(element, element.isImplementation));
+
HInstruction compileArgument(Node argument) {
visit(argument);
return pop();
@@ -2520,7 +2583,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
node: closure);
}
FunctionElement function = element;
- FunctionSignature params = function.computeSignature(compiler);
+ FunctionSignature params
+ = function.implementation.computeSignature(compiler);
ngeoffray 2012/09/20 11:38:37 How can a declaration and an implementation have a
Johnni Winther 2012/09/21 09:18:25 The signatures have different elements for the par
if (params.optionalParameterCount !== 0) {
compiler.cancel(
'JS_TO_CLOSURE does not handle closure with optional parameters',
@@ -2587,7 +2651,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
Selector selector = elements.getSelector(node);
Element element = elements[node];
if (element === null) return generateSuperNoSuchMethodSend(node);
- HInstruction target = new HStatic(element);
+ HInstruction target = new HStatic(element.declaration);
ngeoffray 2012/09/20 11:38:37 Add TODO
Johnni Winther 2012/09/21 09:18:25 Done.
HInstruction context = localsHandler.readThis();
add(target);
var inputs = <HInstruction>[target, context];
@@ -2595,7 +2659,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
push(new HInvokeSuper(inputs));
} else if (element.isFunction() || element.isGenerativeConstructor()) {
bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
- element, inputs);
+ element.implementation,
ngeoffray 2012/09/20 11:38:37 ditto.
Johnni Winther 2012/09/21 09:18:25 Done.
+ inputs);
if (!succeeded) {
// TODO(ngeoffray): Match the VM behavior and throw an
// exception at runtime.
@@ -2733,12 +2798,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
FunctionElement functionElement = constructor;
constructor = functionElement.defaultImplementation;
- HInstruction target = new HStatic(constructor);
+ HInstruction target = new HStatic(constructor.declaration);
ngeoffray 2012/09/20 11:38:37 ditto
Johnni Winther 2012/09/21 09:18:25 Done.
add(target);
var inputs = <HInstruction>[];
inputs.add(target);
bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
- constructor, inputs);
+ constructor.implementation,
ngeoffray 2012/09/20 11:38:37 ditto
Johnni Winther 2012/09/21 09:18:25 Done.
+ inputs);
if (!succeeded) {
// TODO(ngeoffray): Match the VM behavior and throw an
// exception at runtime.
@@ -2782,13 +2848,16 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
compiler.ensure(!element.isGenerativeConstructor());
if (element.isFunction()) {
- if (tryInlineMethod(element, selector, node.arguments)) return;
+ if (tryInlineMethod(element.implementation, selector, node.arguments)) {
ngeoffray 2012/09/20 11:38:37 I would fetch the implementation in tryInlineMetho
Johnni Winther 2012/09/21 09:18:25 Done.
+ return;
+ }
HInstruction target = new HStatic(element);
add(target);
var inputs = <HInstruction>[target];
bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
- element, inputs);
+ element.implementation,
ngeoffray 2012/09/20 11:38:37 TODO
Johnni Winther 2012/09/21 09:18:25 Done.
+ inputs);
if (!succeeded) {
// TODO(ngeoffray): Match the VM behavior and throw an
// exception at runtime.
@@ -3994,6 +4063,11 @@ class InlineWeeder extends AbstractVisitor {
}
class InliningState {
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: [function] must be an implementation element.
+ */
final PartialFunctionElement function;
final Element oldReturnElement;
final TreeElements oldElements;
@@ -4002,7 +4076,9 @@ class InliningState {
InliningState(this.function,
this.oldReturnElement,
this.oldElements,
- this.oldStack);
+ this.oldStack) {
+ assert(function.isImplementation);
+ }
}
class SsaBranch {

Powered by Google App Engine
This is Rietveld 408576698