From 936c0a0ae91e2b002c884b44e3d4537b7092f139 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Wed, 30 Oct 2013 14:19:37 +0400 Subject: [PATCH] Lazy calculation of outer expression --- compiler/backend/backend.iml | 2 +- .../codegen/ImplementationBodyCodegen.java | 2 +- .../jet/codegen/context/CodegenContext.java | 34 ++++++++++++------- .../codegen/context/ConstructorContext.java | 13 ++++--- .../jet/codegen/context/MethodContext.java | 13 ++++++- 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/compiler/backend/backend.iml b/compiler/backend/backend.iml index 737dd163839..6cd681955b5 100644 --- a/compiler/backend/backend.iml +++ b/compiler/backend/backend.iml @@ -15,7 +15,7 @@ - + diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 19463c304e0..c10ef5b387a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -1129,7 +1129,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final MutableClosure closure = context.closure; ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass); - ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor); + ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, closure); if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { lookupConstructorExpressionsInClosureIfPresent(constructorContext); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index dbf72d35b82..64355ed58cd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.codegen.context; +import jet.Function0; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.Type; @@ -30,6 +31,8 @@ import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.storage.LockBasedStorageManager; +import org.jetbrains.jet.storage.NullableLazyValue; import java.util.Collections; import java.util.HashMap; @@ -62,7 +65,7 @@ public abstract class CodegenContext { private Map childContexts; - protected StackValue outerExpression; + private NullableLazyValue lazyOuterExpression; private final LocalLookup enclosingLocalLookup; @@ -129,7 +132,7 @@ public abstract class CodegenContext { } private StackValue getOuterExpression(@Nullable StackValue prefix, boolean ignoreNoOuter, boolean captureThis) { - if (outerExpression == null) { + if (lazyOuterExpression == null || lazyOuterExpression.invoke() == null) { if (ignoreNoOuter) { return null; } @@ -140,7 +143,7 @@ public abstract class CodegenContext { if (captureThis) { closure.setCaptureThis(); } - return prefix != null ? StackValue.composed(prefix, outerExpression) : outerExpression; + return prefix != null ? StackValue.composed(prefix, lazyOuterExpression.invoke()) : lazyOuterExpression.invoke(); } @NotNull @@ -184,13 +187,13 @@ public abstract class CodegenContext { } @NotNull - public ConstructorContext intoConstructor(ConstructorDescriptor descriptor) { + public ConstructorContext intoConstructor(@Nullable ConstructorDescriptor descriptor, @Nullable MutableClosure closure) { if (descriptor == null) { descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.emptyList(), true) .initialize(Collections.emptyList(), Collections.emptyList(), Visibilities.PUBLIC); } - return new ConstructorContext(descriptor, getContextKind(), this); + return new ConstructorContext(descriptor, getContextKind(), this, closure); } @NotNull @@ -294,14 +297,19 @@ public abstract class CodegenContext { public abstract boolean isStatic(); - protected void initOuterExpression(JetTypeMapper typeMapper, ClassDescriptor classDescriptor) { - ClassDescriptor enclosingClass = getEnclosingClass(); - outerExpression = enclosingClass != null && canHaveOuter(typeMapper.getBindingContext(), classDescriptor) - ? StackValue.field(typeMapper.mapType(enclosingClass), - CodegenBinding.getAsmType(typeMapper.getBindingTrace(), classDescriptor), - CAPTURED_THIS_FIELD, - false) - : null; + protected void initOuterExpression(@NotNull final JetTypeMapper typeMapper, @NotNull final ClassDescriptor classDescriptor) { + lazyOuterExpression = LockBasedStorageManager.NO_LOCKS.createNullableLazyValue(new Function0() { + @Override + public StackValue invoke() { + ClassDescriptor enclosingClass = getEnclosingClass(); + return enclosingClass != null && canHaveOuter(typeMapper.getBindingContext(), classDescriptor) + ? StackValue.field(typeMapper.mapType(enclosingClass), + CodegenBinding.getAsmType(typeMapper.getBindingTrace(), classDescriptor), + CAPTURED_THIS_FIELD, + false) + : null; + } + }); } public StackValue lookupInContext(DeclarationDescriptor d, @Nullable StackValue result, GenerationState state, boolean ignoreNoOuter) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/ConstructorContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/ConstructorContext.java index 62162202bfc..fae01feb874 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/ConstructorContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/ConstructorContext.java @@ -17,9 +17,10 @@ package org.jetbrains.jet.codegen.context; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.OwnerKind; import org.jetbrains.jet.codegen.StackValue; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; @@ -30,17 +31,15 @@ public class ConstructorContext extends MethodContext { public ConstructorContext( @NotNull ConstructorDescriptor contextDescriptor, @NotNull OwnerKind kind, - @NotNull CodegenContext parent + @NotNull CodegenContext parent, + @Nullable MutableClosure closure ) { - super(contextDescriptor, kind, parent); - - ClassDescriptor type = getEnclosingClass(); - outerExpression = type != null ? local1 : null; + super(contextDescriptor, kind, parent, closure); } @Override public StackValue getOuterExpression(StackValue prefix, boolean ignoreNoOuter) { - return outerExpression; + return closure != null && closure.getCaptureThis() != null ? local1 : null; } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java index 6451c386573..3d65991849e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.codegen.context; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.codegen.OwnerKind; import org.jetbrains.jet.codegen.StackValue; @@ -27,14 +28,24 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor; public class MethodContext extends CodegenContext { + public MethodContext( @NotNull FunctionDescriptor contextType, @NotNull OwnerKind contextKind, @NotNull CodegenContext parentContext + ) { + this(contextType, contextKind, parentContext, null); + } + + protected MethodContext( + @NotNull FunctionDescriptor contextType, + @NotNull OwnerKind contextKind, + @NotNull CodegenContext parentContext, + @Nullable MutableClosure closure ) { super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor) contextType).getCorrespondingProperty() - : contextType, contextKind, parentContext, null, + : contextType, contextKind, parentContext, closure, parentContext.hasThisDescriptor() ? parentContext.getThisDescriptor() : null, null); }