if a shared variable is a result of the block, release it only after it has been put

#KT-2151 Fixed
This commit is contained in:
Dmitry Jemerov
2012-06-08 17:58:09 +02:00
parent 56310599a5
commit 8baae95531
4 changed files with 37 additions and 4 deletions
@@ -917,8 +917,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final Type sharedVarType = typeMapper.getSharedVarType(variableDescriptor);
final Type type = sharedVarType != null ? sharedVarType : asmType(variableDescriptor.getType());
if(sharedVarType != null) {
v.aconst(null);
v.store(index, TYPE_OBJECT);
if (answer instanceof StackValue.Shared && index == ((StackValue.Shared) answer).getIndex()) {
((StackValue.Shared) answer).releaseOnPut();
}
else {
v.aconst(null);
v.store(index, TYPE_OBJECT);
}
}
v.visitLocalVariable(var.getName(), type.getDescriptor(), null, blockStart, blockEnd, index);
@@ -924,20 +924,33 @@ public abstract class StackValue {
public static class Shared extends StackValue {
private final int index;
private boolean isReleaseOnPut = false;
public Shared(int index, Type type) {
super(type);
this.index = index;
}
public void releaseOnPut() {
isReleaseOnPut = true;
}
public int getIndex() {
return index;
}
@Override
public void put(Type type, InstructionAdapter v) {
v.load(index, JetTypeMapper.TYPE_OBJECT);
Type refType = refType(this.type);
Type sharedType = sharedTypeForType(this.type);
v.visitFieldInsn(Opcodes.GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
StackValue.onStack(refType).coerce(this.type, v);
StackValue.onStack(this.type).coerce(type, v);
coerce(refType, this.type, v);
coerce(this.type, type, v);
if (isReleaseOnPut) {
v.aconst(null);
v.store(index, JetTypeMapper.TYPE_OBJECT);
}
}
@Override