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

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

Issue 10855174: Lazy implementation of final variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase wrt CL 10832351. Created 8 years, 4 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 68d6d505819092e2fb2af2fb1b1b75ff63312b2b..5c8784725958bdb7539fa4c00b3a2c54e4a80d14 100644
--- a/lib/compiler/implementation/ssa/builder.dart
+++ b/lib/compiler/implementation/ssa/builder.dart
@@ -151,7 +151,7 @@ class SsaBuilderTask extends CompilerTask {
HGraph build(WorkItem work) {
return measure(() {
- FunctionElement element = work.element;
+ Element element = work.element;
HInstruction.idCounter = 0;
SsaBuilder builder = new SsaBuilder(this, work);
HGraph graph;
@@ -163,26 +163,32 @@ class SsaBuilderTask extends CompilerTask {
kind === ElementKind.GETTER ||
kind === ElementKind.SETTER) {
graph = builder.buildMethod(work.element);
+ } else if (kind === ElementKind.FIELD) {
+ graph = builder.buildLazyInitializer(work.element);
}
assert(graph.isValid());
- bool inLoop = functionsCalledInLoop.contains(element);
- 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.
- List<HType> parameterTypes =
- backend.optimisticParameterTypesWithRecompilationOnTypeChange(
- element);
- if (parameterTypes != null) {
- FunctionSignature signature = element.computeSignature(compiler);
- int i = 0;
- signature.forEachParameter((Element param) {
- builder.parameters[param].guaranteedType = parameterTypes[i++];
- });
+ if (kind !== ElementKind.FIELD) {
+ bool inLoop = functionsCalledInLoop.contains(element);
+ 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.
+ List<HType> parameterTypes =
+ backend.optimisticParameterTypesWithRecompilationOnTypeChange(
+ element);
+ if (parameterTypes != null) {
+ FunctionElement functionElement = element;
+ FunctionSignature signature =
+ functionElement.computeSignature(compiler);
+ int i = 0;
+ signature.forEachParameter((Element param) {
+ builder.parameters[param].guaranteedType = parameterTypes[i++];
+ });
+ }
}
if (compiler.tracer.enabled) {
@@ -191,7 +197,7 @@ class SsaBuilderTask extends CompilerTask {
String className = element.getEnclosingClass().name.slowToString();
String memberName = element.name.slowToString();
name = "$className.$memberName";
- if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) {
+ if (element.isGenerativeConstructorBody()) {
name = "$name (body)";
}
} else {
@@ -283,7 +289,7 @@ class LocalsHandler {
scopeData.capturedVariableMapping.forEach((Element from, Element to) {
// The [from] can only be a parameter for function-scopes and not
// loop scopes.
- if (from.kind == ElementKind.PARAMETER) {
+ if (from.isParameter()) {
// Store the captured parameter in the box. Get the current value
// before we put the redirection in place.
HInstruction instruction = readLocal(from);
@@ -423,7 +429,7 @@ class LocalsHandler {
// accessed through a closure-field.
// Calling [readLocal] makes sure we generate the correct code to get
// the box.
- assert(redirect.enclosingElement.kind == ElementKind.VARIABLE);
+ assert(redirect.enclosingElement.isVariable());
HInstruction box = readLocal(redirect.enclosingElement);
HInstruction lookup = new HFieldGet.withElement(redirect, box);
builder.add(lookup);
@@ -483,7 +489,7 @@ class LocalsHandler {
// is captured will be boxed, but the box itself will be a local.
// Inside the closure the box is stored in a closure-field and cannot
// be accessed directly.
- assert(redirect.enclosingElement.kind == ElementKind.VARIABLE);
+ assert(redirect.enclosingElement.isVariable());
HInstruction box = readLocal(redirect.enclosingElement);
builder.add(new HFieldSet.withElement(redirect, box, value));
} else {
@@ -858,6 +864,20 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
return closeFunction();
}
+ HGraph buildLazyInitializer(VariableElement variable) {
+ HBasicBlock block = graph.addNewBlock();
+ open(graph.entry);
+ close(new HGoto()).addSuccessor(block);
+ open(block);
+ SendSet node = variable.parseNode(compiler);
+ Link<Node> link = node.arguments;
+ assert(!link.isEmpty() && link.tail.isEmpty());
+ visit(link.head);
+ close(new HReturn(pop())).addSuccessor(graph.exit);
+ graph.finalize();
+ return graph;
+ }
+
/**
* Returns the constructor body associated with the given constructor or
* creates a new constructor body, if none can be found.
@@ -865,7 +885,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
* Returns [:null:] if the constructor does not have a body.
*/
ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
- assert(constructor.kind === ElementKind.GENERATIVE_CONSTRUCTOR);
+ assert(constructor.isGenerativeConstructor());
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
@@ -880,7 +900,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
!backendMembers.isEmpty();
backendMembers = backendMembers.tail) {
Element backendMember = backendMembers.head;
- if (backendMember.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) {
+ if (backendMember.isGenerativeConstructorBody()) {
ConstructorBodyElement body = backendMember;
if (body.constructor == constructor) {
bodyElement = backendMember;
@@ -896,7 +916,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
classElement.backendMembers =
classElement.backendMembers.prepend(bodyElement);
}
- assert(bodyElement.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY);
+ assert(bodyElement.isGenerativeConstructorBody());
return bodyElement;
}
@@ -1051,7 +1071,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
if (value === null) {
// The field has no value in the initializer list. Initialize it
// with the declaration-site constant (if any).
- Constant fieldValue = compiler.constantHandler.compileVariable(member);
+ Constant fieldValue = compiler.compileConstant(member);
value = graph.addConstant(fieldValue);
}
constructorArguments.add(value);
@@ -1565,7 +1585,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
for (Element member in closureClassElement.backendMembers) {
// The backendMembers also contains the call method(s). We are only
// interested in the fields.
- if (member.kind == ElementKind.FIELD) {
+ if (member.isField()) {
Element capturedLocal = nestedClosureData.capturedFieldMapping[member];
assert(capturedLocal != null);
capturedVariables.add(localsHandler.readLocal(capturedLocal));
@@ -1764,13 +1784,19 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
void generateGetter(Send send, Element element) {
if (Elements.isStaticOrTopLevelField(element)) {
- if (element.kind == ElementKind.FIELD && !element.isAssignable()) {
- // A static final. Get its constant value and inline it.
- Constant value = compiler.constantHandler.compileVariable(element);
+ Constant value;
+ if (element.isField() && !element.isAssignable()) {
+ // A static final or const. Get its constant value and inline it if
+ // the value can be compiled eagerly.
+ value = compiler.compileVariable(element);
+ }
+ if (value != null) {
stack.add(graph.addConstant(value));
+ } else if (element.isField() && compiler.isLazilyInitialized(element)) {
+ push(new HLazyStatic(element));
} else {
push(new HStatic(element));
- if (element.kind == ElementKind.GETTER) {
+ if (element.isGetter()) {
push(new HInvokeStatic(<HInstruction>[pop()]));
}
}
@@ -1811,7 +1837,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
void generateSetter(SendSet send, Element element, HInstruction value) {
if (Elements.isStaticOrTopLevelField(element)) {
- if (element.kind == ElementKind.SETTER) {
+ if (element.isSetter()) {
HStatic target = new HStatic(element);
add(target);
add(new HInvokeStatic(<HInstruction>[target, value]));
@@ -1903,7 +1929,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression);
typeInfo = pop();
}
- if (type.element.kind === ElementKind.TYPE_VARIABLE) {
+ if (type.element.isTypeVariable()) {
// TODO(karlklose): We emulate the frog behavior and answer
// true to any is check involving a type variable -- both is T
// and is !T -- until we have a proper implementation of
@@ -1988,7 +2014,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
HInstruction compileConstant(Element constantElement) {
- Constant constant = compiler.compileVariable(constantElement);
+ Constant constant = compiler.compileConstant(constantElement);
return graph.addConstant(constant);
}
@@ -2266,8 +2292,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
var inputs = <HInstruction>[target, context];
if (node.isPropertyAccess) {
push(new HInvokeSuper(inputs));
- } else if (element.kind == ElementKind.FUNCTION ||
- element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+ } else if (element.isFunction() || element.isGenerativeConstructor()) {
bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
element, inputs);
if (!succeeded) {
@@ -3224,7 +3249,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
} else {
// TODO(aprelev@gmail.com): Once old catch syntax is removed
// "if" condition above and this "else" branch should be deleted as
- // type of declared variable won't matter for the catch
+ // type of declared variable won't matter for the catch
// condition
kasperl 2012/08/17 09:30:04 Terminate comment with .
floitsch 2012/09/04 17:32:21 Done.
Type type = elements.getType(declaration.type);
if (type == null) {

Powered by Google App Engine
This is Rietveld 408576698