Refactoring FrameMap:

- dangerous enter() and leave() methods removed
- all variables are eneted/left with their type, not numeric size
This commit is contained in:
Andrey Breslav
2012-08-22 15:00:09 +04:00
parent 1c2e8ad550
commit 72de754731
7 changed files with 84 additions and 77 deletions
@@ -27,6 +27,8 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import java.util.Collections;
import java.util.HashMap;
import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT;
/*
* @author max
* @author alex.tkachman
@@ -149,13 +151,13 @@ public abstract class CodegenContext {
FrameMap frameMap = new FrameMap();
if (getContextKind() != OwnerKind.NAMESPACE) {
frameMap.enterTemp(); // 0 slot for this
frameMap.enterTemp(TYPE_OBJECT); // 0 slot for this
}
CallableDescriptor receiverDescriptor = getReceiverDescriptor();
if (receiverDescriptor != null) {
Type type = mapper.mapType(receiverDescriptor.getReceiverParameter().getType(), MapTypeMode.VALUE);
frameMap.enterTemp(type.getSize()); // Next slot for fake this
frameMap.enterTemp(type); // Next slot for fake this
}
return frameMap;
@@ -33,10 +33,10 @@ public class ConstructorFrameMap extends FrameMap {
private int myOuterThisIndex = -1;
public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, boolean hasThis0) {
enterTemp(); // this
enterTemp(JetTypeMapper.TYPE_OBJECT); // this
if (descriptor != null) {
if (hasThis0) {
myOuterThisIndex = enterTemp(); // outer class instance
myOuterThisIndex = enterTemp(JetTypeMapper.TYPE_OBJECT); // outer class instance
}
}
@@ -45,8 +45,8 @@ public class ConstructorFrameMap extends FrameMap {
if (descriptor != null &&
(descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS ||
descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_ENTRY)) {
enterTemp(); // name
enterTemp(); // ordinal
enterTemp(JetTypeMapper.TYPE_OBJECT); // name
enterTemp(Type.INT_TYPE); // ordinal
}
List<ValueParameterDescriptor> paramDescrs = descriptor != null
@@ -54,7 +54,7 @@ public class ConstructorFrameMap extends FrameMap {
: Collections.<ValueParameterDescriptor>emptyList();
for (int i = 0; i < paramDescrs.size(); i++) {
ValueParameterDescriptor parameter = paramDescrs.get(i);
enter(parameter, explicitArgTypes.get(i).getSize());
enter(parameter, explicitArgTypes.get(i));
}
}
@@ -384,7 +384,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetType paramType = parameterDescriptor.getType();
Type asmParamType = asmType(paramType);
int iteratorVar = myFrameMap.enterTemp();
int iteratorVar = myFrameMap.enterTemp(asmIterType);
gen(expression.getLoopRange(), boxType(loopRangeType));
invokeFunctionNoParams(iteratorDescriptor, asmIterType, v);
v.store(iteratorVar, asmIterType);
@@ -413,7 +413,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
v.ifeq(end);
myFrameMap.enter(parameterDescriptor, asmParamType.getSize());
myFrameMap.enter(parameterDescriptor, asmParamType);
v.load(iteratorVar, asmIterType);
invokeFunctionNoParams(nextDescriptor, asmParamType, v);
@@ -431,7 +431,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
int paramIndex = myFrameMap.leave(parameterDescriptor);
//noinspection ConstantConditions
v.visitLocalVariable(loopParameter.getName(), asmParamType.getDescriptor(), null, begin, end, paramIndex);
myFrameMap.leaveTemp();
myFrameMap.leaveTemp(asmIterType);
blockStackElements.pop();
}
@@ -459,7 +459,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetType paramType = parameterDescriptor.getType();
Type asmParamType = asmType(paramType);
myFrameMap.enter(parameterDescriptor, asmParamType.getSize());
myFrameMap.enter(parameterDescriptor, asmParamType);
generatePrologue();
Label condition = new Label();
@@ -507,7 +507,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
protected void generatePrologue() {
myIndexVar = myFrameMap.enterTemp();
myIndexVar = myFrameMap.enterTemp(Type.INT_TYPE);
StackValue value = gen(expression.getLoopRange());
if (value instanceof StackValue.Local) {
@@ -515,7 +515,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
localArrayVar = true;
}
else {
myArrayVar = myFrameMap.enterTemp();
myArrayVar = myFrameMap.enterTemp(TYPE_OBJECT);
value.put(loopRangeType, v);
v.store(myArrayVar, TYPE_OBJECT);
}
@@ -558,7 +558,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
protected void cleanupTemp() {
myFrameMap.leaveTemp(localArrayVar ? 1 : 2);
myFrameMap.leaveTemp(Type.INT_TYPE);
if (!localArrayVar) {
myFrameMap.leaveTemp(TYPE_OBJECT);
}
}
}
@@ -574,8 +577,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
protected void generatePrologue() {
myIndexVar = lookupLocal(parameterDescriptor);
myCountVar = myFrameMap.enterTemp();
myDeltaVar = myFrameMap.enterTemp();
myCountVar = myFrameMap.enterTemp(Type.INT_TYPE);
myDeltaVar = myFrameMap.enterTemp(Type.INT_TYPE);
if (isIntRangeExpr(expression.getLoopRange())) {
JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getLoopRange();
//noinspection ConstantConditions
@@ -638,8 +641,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
protected void cleanupTemp() {
myFrameMap.leaveTemp();
myFrameMap.leaveTemp();
myFrameMap.leaveTemp(Type.INT_TYPE);
myFrameMap.leaveTemp(Type.INT_TYPE);
}
}
@@ -949,7 +952,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final Type sharedVarType = typeMapper.getSharedVarType(variableDescriptor);
final Type type = sharedVarType != null ? sharedVarType : asmType(variableDescriptor.getType());
int index = myFrameMap.enter(variableDescriptor, type.getSize());
int index = myFrameMap.enter(variableDescriptor, type);
if (sharedVarType != null) {
v.anew(sharedVarType);
@@ -981,7 +984,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private void generateLocalFunctionDeclaration(@NotNull JetNamedFunction namedFunction, @NotNull List<Function<StackValue, Void>> leaveTasks) {
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, namedFunction);
myFrameMap.enter(descriptor, 1);
myFrameMap.enter(descriptor, TYPE_OBJECT);
leaveTasks.add(new Function<StackValue, Void>() {
@Override
@@ -2764,8 +2767,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
if (args.size() == 2) {
int sizeIndex = myFrameMap.enterTemp(2);
int indexIndex = sizeIndex + 1;
int sizeIndex = myFrameMap.enterTemp(Type.INT_TYPE);
int indexIndex = myFrameMap.enterTemp(Type.INT_TYPE);
v.dup();
v.arraylength();
@@ -2796,7 +2799,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v.visitLabel(end);
v.pop();
myFrameMap.leaveTemp(2);
myFrameMap.leaveTemp(Type.INT_TYPE);
myFrameMap.leaveTemp(Type.INT_TYPE);
}
}
@@ -2922,7 +2926,7 @@ The "returned" value of try expression with no finally is either the last expres
gen(expression.getTryBlock(), expectedAsmType);
int savedValue = myFrameMap.enterTemp(expectedAsmType.getSize());
int savedValue = myFrameMap.enterTemp(expectedAsmType);
v.store(savedValue, expectedAsmType);
Label tryEnd = new Label();
@@ -2945,7 +2949,7 @@ The "returned" value of try expression with no finally is either the last expres
VariableDescriptor descriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, clause.getCatchParameter());
assert descriptor != null;
Type descriptorType = asmType(descriptor.getType());
myFrameMap.enter(descriptor, 1);
myFrameMap.enter(descriptor, descriptorType);
int index = lookupLocal(descriptor);
v.store(index, descriptorType);
@@ -2972,7 +2976,7 @@ The "returned" value of try expression with no finally is either the last expres
Label finallyStart = new Label();
v.mark(finallyStart);
int savedException = myFrameMap.enterTemp();
int savedException = myFrameMap.enterTemp(TYPE_THROWABLE);
v.store(savedException, TYPE_THROWABLE);
blockStackElements.pop();
@@ -2980,7 +2984,7 @@ The "returned" value of try expression with no finally is either the last expres
blockStackElements.push(finallyBlockStackElement);
v.load(savedException, TYPE_THROWABLE);
myFrameMap.leaveTemp();
myFrameMap.leaveTemp(TYPE_THROWABLE);
v.athrow();
@@ -2989,7 +2993,7 @@ The "returned" value of try expression with no finally is either the last expres
v.mark(end);
v.load(savedValue, expectedAsmType);
myFrameMap.leaveTemp(expectedAsmType.getSize());
myFrameMap.leaveTemp(expectedAsmType);
if (finallyBlock != null) {
blockStackElements.pop();
@@ -3108,7 +3112,7 @@ The "returned" value of try expression with no finally is either the last expres
final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, var);
assert variableDescriptor != null;
final Type varType = asmType(variableDescriptor.getType());
myFrameMap.enter(variableDescriptor, varType.getSize());
myFrameMap.enter(variableDescriptor, varType);
expressionToMatch.dupReceiver(v);
expressionToMatch.put(varType, v);
final int varIndex = myFrameMap.getIndex(variableDescriptor);
@@ -3197,7 +3201,7 @@ The "returned" value of try expression with no finally is either the last expres
JetType subjectJetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expr);
final Type subjectType = asmTypeOrVoid(subjectJetType);
final Type resultType = expressionType(expression);
final int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType.getSize()) : -1;
final int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType) : -1;
if (subjectLocal != -1) {
gen(expr, subjectType);
v.store(subjectLocal, subjectType);
@@ -3248,7 +3252,7 @@ The "returned" value of try expression with no finally is either the last expres
}
v.mark(end);
myFrameMap.leaveTemp(subjectType.getSize());
myFrameMap.leaveTemp(subjectType);
return StackValue.onStack(resultType);
}
@@ -19,6 +19,7 @@ package org.jetbrains.jet.codegen;
import com.google.common.collect.Lists;
import gnu.trove.TObjectIntHashMap;
import gnu.trove.TObjectIntIterator;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import java.util.ArrayList;
@@ -34,11 +35,11 @@ public class FrameMap {
private final TObjectIntHashMap<DeclarationDescriptor> myVarSizes = new TObjectIntHashMap<DeclarationDescriptor>();
private int myMaxIndex = 0;
public int enter(DeclarationDescriptor descriptor, int size) {
public int enter(DeclarationDescriptor descriptor, Type type) {
int index = myMaxIndex;
myVarIndex.put(descriptor, index);
myMaxIndex += size;
myVarSizes.put(descriptor, size);
myMaxIndex += type.getSize();
myVarSizes.put(descriptor, type.getSize());
return index;
}
@@ -53,22 +54,14 @@ public class FrameMap {
return oldIndex;
}
public int enterTemp() {
return enterTemp(1);
}
public int enterTemp(int size) {
public int enterTemp(Type type) {
int result = myMaxIndex;
myMaxIndex += size;
myMaxIndex += type.getSize();
return result;
}
public void leaveTemp() {
myMaxIndex--;
}
public void leaveTemp(int size) {
myMaxIndex -= size;
public void leaveTemp(Type type) {
myMaxIndex -= type.getSize();
}
public int getIndex(DeclarationDescriptor descriptor) {
@@ -219,7 +219,7 @@ public class FunctionCodegen {
for (int i = 0; i < paramDescrs.size(); i++) {
ValueParameterDescriptor parameter = paramDescrs.get(i);
frameMap.enter(parameter, argTypes[i + add].getSize());
frameMap.enter(parameter, argTypes[i + add]);
}
if (!isStatic &&
@@ -488,7 +488,7 @@ public class FunctionCodegen {
FrameMap frameMap = owner.prepareFrame(state.getInjector().getJetTypeMapper());
if (kind instanceof OwnerKind.StaticDelegateKind) {
frameMap.leaveTemp();
frameMap.leaveTemp(JetTypeMapper.TYPE_OBJECT);
}
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), owner, state);
@@ -510,8 +510,9 @@ public class FunctionCodegen {
Type[] argTypes = jvmSignature.getArgumentTypes();
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
for (int i = 0; i < paramDescrs.size(); i++) {
int size = argTypes[i + (hasReceiver ? 1 : 0)].getSize();
frameMap.enter(paramDescrs.get(i), size);
Type argType = argTypes[i + (hasReceiver ? 1 : 0)];
int size = argType.getSize();
frameMap.enter(paramDescrs.get(i), argType);
var += size;
}
@@ -535,7 +536,7 @@ public class FunctionCodegen {
Type t = argTypes[extra + index];
if (frameMap.getIndex(parameterDescriptor) < 0) {
frameMap.enter(parameterDescriptor, t.getSize());
frameMap.enter(parameterDescriptor, t);
}
if (parameterDescriptor.declaresDefaultValue()) {
@@ -38,6 +38,8 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import javax.inject.Inject;
import java.util.List;
import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT;
/**
* @author Stepan Koltsov
*/
@@ -155,7 +157,7 @@ public class ScriptCodegen {
FrameMap frameMap = context.prepareFrame(jetTypeMapper);
for (ScriptDescriptor importedScript : importedScripts) {
frameMap.enter(importedScript, 1);
frameMap.enter(importedScript, TYPE_OBJECT);
}
Type[] argTypes = jvmSignature.getAsmMethod().getArgumentTypes();
@@ -163,7 +165,7 @@ public class ScriptCodegen {
for (int i = 0; i < scriptDescriptor.getValueParameters().size(); i++) {
ValueParameterDescriptor parameter = scriptDescriptor.getValueParameters().get(i);
frameMap.enter(parameter, argTypes[i + add].getSize());
frameMap.enter(parameter, argTypes[i + add]);
}
ImplementationBodyCodegen.generateInitializers(
@@ -35,6 +35,8 @@ import org.jetbrains.jet.lexer.JetTokens;
import java.util.List;
import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT;
/**
* @author yole
* @author alex.tkachman
@@ -269,11 +271,11 @@ public abstract class StackValue {
pop(fromType, v);
putTuple0Instance(v);
}
else if (toType.getSort() == Type.OBJECT && fromType.equals(JetTypeMapper.TYPE_OBJECT) || toType.getSort() == Type.ARRAY) {
else if (toType.getSort() == Type.OBJECT && fromType.equals(TYPE_OBJECT) || toType.getSort() == Type.ARRAY) {
v.checkcast(toType);
}
else if (toType.getSort() == Type.OBJECT) {
if (fromType.getSort() == Type.OBJECT && !toType.equals(JetTypeMapper.TYPE_OBJECT)) {
if (fromType.getSort() == Type.OBJECT && !toType.equals(TYPE_OBJECT)) {
v.checkcast(toType);
}
else {
@@ -281,7 +283,7 @@ public abstract class StackValue {
}
}
else if (fromType.getSort() == Type.OBJECT && toType.getSort() <= Type.DOUBLE) {
if (fromType.equals(JetTypeMapper.TYPE_OBJECT)) {
if (fromType.equals(TYPE_OBJECT)) {
if (toType.getSort() == Type.BOOLEAN) {
v.checkcast(JvmPrimitiveType.BOOLEAN.getWrapper().getAsmType());
}
@@ -479,7 +481,7 @@ public abstract class StackValue {
putTuple0Instance(v);
return;
}
if (type != Type.BOOLEAN_TYPE && !type.equals(JetTypeMapper.TYPE_OBJECT) && !type.equals(JetTypeMapper.JL_BOOLEAN_TYPE)) {
if (type != Type.BOOLEAN_TYPE && !type.equals(TYPE_OBJECT) && !type.equals(JetTypeMapper.JL_BOOLEAN_TYPE)) {
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type " + type);
}
putAsBoolean(v);
@@ -568,7 +570,7 @@ public abstract class StackValue {
myOperand.put(type, v); // the operand will remove itself from the stack if needed
return;
}
if (type != Type.BOOLEAN_TYPE && !type.equals(JetTypeMapper.TYPE_OBJECT) && !type.equals(JetTypeMapper.JL_BOOLEAN_TYPE)) {
if (type != Type.BOOLEAN_TYPE && !type.equals(TYPE_OBJECT) && !type.equals(JetTypeMapper.JL_BOOLEAN_TYPE)) {
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type");
}
putAsBoolean(v);
@@ -696,8 +698,9 @@ public abstract class StackValue {
}
else {
int size = 0;
int lastIndex = frame.enterTemp();
frame.leaveTemp();
// ugly hack: getting the last variable index
int lastIndex = frame.enterTemp(Type.INT_TYPE);
frame.leaveTemp(Type.INT_TYPE);
// indexes
List<ValueParameterDescriptor> valueParameters = resolvedGetCall.getResultingDescriptor().getValueParameters();
@@ -705,7 +708,7 @@ public abstract class StackValue {
for (int i = valueParameters.size() - 1; i >= 0; --i) {
Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE);
int sz = type.getSize();
frame.enterTemp(sz);
frame.enterTemp(type);
lastIndex += sz;
size += sz;
v.store((firstParamIndex = lastIndex) - sz, type);
@@ -715,10 +718,10 @@ public abstract class StackValue {
int firstTypeParamIndex = -1;
for (int i = typeParameters.size() - 1; i >= 0; --i) {
if (typeParameters.get(i).isReified()) {
frame.enterTemp();
frame.enterTemp(TYPE_OBJECT);
lastIndex++;
size++;
v.store(firstTypeParamIndex = lastIndex - 1, JetTypeMapper.TYPE_OBJECT);
v.store(firstTypeParamIndex = lastIndex - 1, TYPE_OBJECT);
}
}
@@ -727,7 +730,7 @@ public abstract class StackValue {
if (receiverParameter.exists()) {
Type type = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
int sz = type.getSize();
frame.enterTemp(sz);
frame.enterTemp(type);
lastIndex += sz;
size += sz;
v.store((receiverIndex = lastIndex) - sz, type);
@@ -736,10 +739,10 @@ public abstract class StackValue {
ReceiverDescriptor thisObject = resolvedGetCall.getThisObject();
int thisIndex = -1;
if (thisObject.exists()) {
frame.enterTemp();
frame.enterTemp(TYPE_OBJECT);
lastIndex++;
size++;
v.store((thisIndex = lastIndex) - 1, JetTypeMapper.TYPE_OBJECT);
v.store((thisIndex = lastIndex) - 1, TYPE_OBJECT);
}
// for setter
@@ -753,7 +756,7 @@ public abstract class StackValue {
}
else {
realReceiverIndex = thisIndex;
realReceiverType = JetTypeMapper.TYPE_OBJECT;
realReceiverType = TYPE_OBJECT;
}
}
else {
@@ -768,7 +771,7 @@ public abstract class StackValue {
if (resolvedSetCall.getThisObject().exists()) {
if (resolvedSetCall.getReceiverArgument().exists()) {
codegen.generateFromResolvedCall(resolvedSetCall.getThisObject(), JetTypeMapper.TYPE_OBJECT);
codegen.generateFromResolvedCall(resolvedSetCall.getThisObject(), TYPE_OBJECT);
}
v.load(realReceiverIndex - realReceiverType.getSize(), realReceiverType);
}
@@ -791,7 +794,7 @@ public abstract class StackValue {
// restoring original
if (thisIndex != -1) {
v.load(thisIndex - 1, JetTypeMapper.TYPE_OBJECT);
v.load(thisIndex - 1, TYPE_OBJECT);
}
if (receiverIndex != -1) {
@@ -803,7 +806,7 @@ public abstract class StackValue {
index = firstTypeParamIndex;
for (int i = 0; i != typeParameters.size(); ++i) {
if (typeParameters.get(i).isReified()) {
v.load(index - 1, JetTypeMapper.TYPE_OBJECT);
v.load(index - 1, TYPE_OBJECT);
index--;
}
}
@@ -817,7 +820,9 @@ public abstract class StackValue {
index -= sz;
}
frame.leaveTemp(size);
for (int i = 0; i < size; i++) {
frame.leaveTemp(TYPE_OBJECT);
}
}
}
@@ -1017,7 +1022,7 @@ public abstract class StackValue {
@Override
public void put(Type type, InstructionAdapter v) {
v.load(index, JetTypeMapper.TYPE_OBJECT);
v.load(index, TYPE_OBJECT);
Type refType = refType(this.type);
Type sharedType = sharedTypeForType(this.type);
v.visitFieldInsn(Opcodes.GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
@@ -1025,13 +1030,13 @@ public abstract class StackValue {
coerce(this.type, type, v);
if (isReleaseOnPut) {
v.aconst(null);
v.store(index, JetTypeMapper.TYPE_OBJECT);
v.store(index, TYPE_OBJECT);
}
}
@Override
public void store(Type topOfStackType, InstructionAdapter v) {
v.load(index, JetTypeMapper.TYPE_OBJECT);
v.load(index, TYPE_OBJECT);
v.swap();
Type refType = refType(this.type);
Type sharedType = sharedTypeForType(this.type);
@@ -1076,7 +1081,7 @@ public abstract class StackValue {
public static Type refType(Type type) {
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
return JetTypeMapper.TYPE_OBJECT;
return TYPE_OBJECT;
}
return type;
@@ -1136,7 +1141,7 @@ public abstract class StackValue {
@Override
public void store(Type topOfStackType, InstructionAdapter v) {
prefix.put(JetTypeMapper.TYPE_OBJECT, v);
prefix.put(TYPE_OBJECT, v);
suffix.store(topOfStackType, v);
}
}
@@ -1146,7 +1151,7 @@ public abstract class StackValue {
private ClassDescriptor descriptor;
public ThisOuter(ExpressionCodegen codegen, ClassDescriptor descriptor) {
super(JetTypeMapper.TYPE_OBJECT);
super(TYPE_OBJECT);
this.codegen = codegen;
this.descriptor = descriptor;
}