Optimized iteration over primitive range expression.
This commit is contained in:
@@ -55,6 +55,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
@@ -478,9 +479,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// todo: Only IntRange optimized so far
|
if (RangeCodegenUtil.isRange(loopRangeType)) {
|
||||||
if (RangeCodegenUtil.isIntRange(loopRangeType)) {
|
generateForLoop(new ForInRangeInstanceLoopGenerator(forExpression));
|
||||||
generateForLoop(new ForInIntRangeInstanceLoopGenerator(forExpression));
|
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -909,49 +909,30 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ForInIntRangeInstanceLoopGenerator extends AbstractForLoopGenerator {
|
private class ForInRangeInstanceLoopGenerator extends AbstractForInRangeLoopGenerator {
|
||||||
private int endVar;
|
private ForInRangeInstanceLoopGenerator(@NotNull JetForExpression forExpression) {
|
||||||
|
|
||||||
private ForInIntRangeInstanceLoopGenerator(
|
|
||||||
@NotNull JetForExpression forExpression
|
|
||||||
) {
|
|
||||||
super(forExpression);
|
super(forExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeLoop() {
|
protected void storeRangeStartAndEnd() {
|
||||||
super.beforeLoop();
|
|
||||||
|
|
||||||
JetType loopRangeType = bindingContext.get(EXPRESSION_TYPE, forExpression.getLoopRange());
|
JetType loopRangeType = bindingContext.get(EXPRESSION_TYPE, forExpression.getLoopRange());
|
||||||
assert loopRangeType != null;
|
assert loopRangeType != null;
|
||||||
Type asmLoopRangeType = asmType(loopRangeType);
|
Type asmLoopRangeType = asmType(loopRangeType);
|
||||||
gen(forExpression.getLoopRange(), asmLoopRangeType);
|
gen(forExpression.getLoopRange(), asmLoopRangeType);
|
||||||
v.dup();
|
v.dup();
|
||||||
|
|
||||||
v.invokevirtual(JET_INT_RANGE_TYPE.getInternalName(), "getStart", "()Ljava/lang/Integer;");
|
JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(asmElementType);
|
||||||
StackValue.coerce(Type.getType("Ljava/lang/Integer;"), Type.INT_TYPE, v);
|
assert primitiveType != null : asmElementType;
|
||||||
v.store(loopParameterVar, Type.INT_TYPE);
|
Type asmWrapperType = primitiveType.getWrapper().getAsmType();
|
||||||
|
|
||||||
endVar = createLoopTempVariable(Type.INT_TYPE);
|
v.invokevirtual(asmLoopRangeType.getInternalName(), "getStart", "()" + asmWrapperType.getDescriptor());
|
||||||
v.invokevirtual(JET_INT_RANGE_TYPE.getInternalName(), "getEnd", "()Ljava/lang/Integer;");
|
StackValue.coerce(asmWrapperType, asmElementType, v);
|
||||||
StackValue.coerce(Type.getType("Ljava/lang/Integer;"), Type.INT_TYPE, v);
|
v.store(loopParameterVar, asmElementType);
|
||||||
v.store(endVar, Type.INT_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
v.invokevirtual(asmLoopRangeType.getInternalName(), "getEnd", "()" + asmWrapperType.getDescriptor());
|
||||||
public void conditionAndJump(@NotNull Label loopExit) {
|
StackValue.coerce(asmWrapperType, asmElementType, v);
|
||||||
v.load(loopParameterVar, Type.INT_TYPE);
|
v.store(endVar, asmElementType);
|
||||||
v.load(endVar, Type.INT_TYPE);
|
|
||||||
v.ificmpgt(loopExit);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void assignToLoopParameter() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void increment() {
|
|
||||||
v.iinc(loopParameterVar, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,9 +42,8 @@ public class RangeCodegenUtil {
|
|||||||
|
|
||||||
private RangeCodegenUtil() {}
|
private RangeCodegenUtil() {}
|
||||||
|
|
||||||
public static boolean isIntRange(JetType rangeType) {
|
public static boolean isRange(JetType rangeType) {
|
||||||
return !rangeType.isNullable()
|
return !rangeType.isNullable() && getPrimitiveRangeElementType(rangeType) != null;
|
||||||
&& KotlinBuiltIns.getInstance().getIntType().equals(getPrimitiveRangeElementType(rangeType));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
Reference in New Issue
Block a user