Chromium Code Reviews| 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) { |