ParameterBuilder refactoring: allow to generate captured parameter between value ones

This commit is contained in:
Michael Bogdanov
2016-06-28 13:13:05 +03:00
parent 7f07890f6a
commit 439431e923
7 changed files with 64 additions and 61 deletions
@@ -251,7 +251,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
List<Type> descTypes = new ArrayList<Type>(); List<Type> descTypes = new ArrayList<Type>();
Parameters constructorParams = constructorInlineBuilder.buildParameters(); Parameters constructorParams = constructorInlineBuilder.buildParameters();
int[] capturedIndexes = new int[constructorParams.getReal().size() + constructorParams.getCaptured().size()]; int[] capturedIndexes = new int[constructorParams.getParameters().size()];
int index = 0; int index = 0;
int size = 0; int size = 0;
@@ -432,7 +432,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
Type[] types = Type.getArgumentTypes(constructorDesc); Type[] types = Type.getArgumentTypes(constructorDesc);
for (Type type : types) { for (Type type : types) {
LambdaInfo info = indexToLambda.get(constructorParamBuilder.getNextValueParameterIndex()); LambdaInfo info = indexToLambda.get(constructorParamBuilder.getNextParameterOffset());
ParameterInfo parameterInfo = constructorParamBuilder.addNextParameter(type, info != null); ParameterInfo parameterInfo = constructorParamBuilder.addNextParameter(type, info != null);
parameterInfo.setLambda(info); parameterInfo.setLambda(info);
if (capturedParams.contains(parameterInfo.getIndex())) { if (capturedParams.contains(parameterInfo.getIndex())) {
@@ -26,7 +26,7 @@ public class CapturedParamInfo extends ParameterInfo {
private final boolean skipInConstructor; private final boolean skipInConstructor;
public CapturedParamInfo(@NotNull CapturedParamDesc desc, @NotNull String newFieldName, boolean skipped, int index, int remapIndex) { public CapturedParamInfo(@NotNull CapturedParamDesc desc, @NotNull String newFieldName, boolean skipped, int index, int remapIndex) {
super(desc.getType(), skipped, index, remapIndex, index); super(desc.getType(), skipped, index, remapIndex, -1);
this.desc = desc; this.desc = desc;
this.newFieldName = newFieldName; this.newFieldName = newFieldName;
this.skipInConstructor = false; this.skipInConstructor = false;
@@ -38,9 +38,10 @@ public class CapturedParamInfo extends ParameterInfo {
boolean skipped, boolean skipped,
int index, int index,
@Nullable StackValue remapIndex, @Nullable StackValue remapIndex,
boolean skipInConstructor boolean skipInConstructor,
int declarationIndex
) { ) {
super(desc.getType(), skipped, index, remapIndex, index); super(desc.getType(), skipped, index, remapIndex, declarationIndex);
this.desc = desc; this.desc = desc;
this.newFieldName = newFieldName; this.newFieldName = newFieldName;
this.skipInConstructor = skipInConstructor; this.skipInConstructor = skipInConstructor;
@@ -57,13 +58,10 @@ public class CapturedParamInfo extends ParameterInfo {
} }
@NotNull @NotNull
public CapturedParamInfo newIndex(int newIndex) { public CapturedParamInfo cloneWithNewDeclarationIndex(int newDeclarationIndex) {
return clone(newIndex, getRemapValue()); CapturedParamInfo result = new CapturedParamInfo(
} desc, newFieldName, isSkipped, getIndex(), getRemapValue(), skipInConstructor, newDeclarationIndex
);
@NotNull
private CapturedParamInfo clone(int newIndex, @Nullable StackValue newRemapIndex) {
CapturedParamInfo result = new CapturedParamInfo(desc, newFieldName, isSkipped, newIndex, newRemapIndex, skipInConstructor);
result.setLambda(getLambda()); result.setLambda(getLambda());
return result; return result;
} }
@@ -726,7 +726,7 @@ public class InlineCodegen extends CallGenerator {
} }
invocationParamBuilder.markValueParametersStart(); invocationParamBuilder.markValueParametersStart();
List<ParameterInfo> hiddenParameters = invocationParamBuilder.buildParameters().getReal(); List<ParameterInfo> hiddenParameters = invocationParamBuilder.buildParameters().getParameters();
recordParameterValueInLocalVal(hiddenParameters.toArray(new ParameterInfo[hiddenParameters.size()])); recordParameterValueInLocalVal(hiddenParameters.toArray(new ParameterInfo[hiddenParameters.size()]));
} }
@@ -488,7 +488,7 @@ public class InlineCodegenUtil {
public static int calcMarkerShift(@NotNull Parameters parameters, @NotNull MethodNode node) { public static int calcMarkerShift(@NotNull Parameters parameters, @NotNull MethodNode node) {
int markerShiftTemp = getIndexAfterLastMarker(node); int markerShiftTemp = getIndexAfterLastMarker(node);
return markerShiftTemp - parameters.getRealArgsSizeOnStack() + parameters.getArgsSizeOnStack(); return markerShiftTemp - parameters.getRealParametersSizeOnStack() + parameters.getArgsSizeOnStack();
} }
private static int getIndexAfterLastMarker(@NotNull MethodNode node) { private static int getIndexAfterLastMarker(@NotNull MethodNode node) {
@@ -340,8 +340,8 @@ public class MethodInliner {
@NotNull @NotNull
private MethodNode prepareNode(@NotNull MethodNode node, int finallyDeepShift) { private MethodNode prepareNode(@NotNull MethodNode node, int finallyDeepShift) {
final int capturedParamsSize = parameters.getCapturedArgsSizeOnStack(); final int capturedParamsSize = parameters.getCapturedParametersSizeOnStack();
final int realParametersSize = parameters.getRealArgsSizeOnStack(); final int realParametersSize = parameters.getRealParametersSizeOnStack();
Type[] types = Type.getArgumentTypes(node.desc); Type[] types = Type.getArgumentTypes(node.desc);
Type returnType = Type.getReturnType(node.desc); Type returnType = Type.getReturnType(node.desc);
@@ -19,15 +19,23 @@ package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import java.util.* import java.util.*
internal class Parameters(val real: List<ParameterInfo>, val captured: List<CapturedParamInfo>) : Iterable<ParameterInfo> { internal class Parameters(val parameters: List<ParameterInfo>) : Iterable<ParameterInfo> {
private val actualDeclShifts: Array<ParameterInfo?> private val actualDeclShifts: Array<ParameterInfo?>
private val paramToDeclByteCodeIndex: HashMap<ParameterInfo, Int> = hashMapOf() private val paramToDeclByteCodeIndex: HashMap<ParameterInfo, Int> = hashMapOf()
val realArgsSizeOnStack = real.sumBy { it.type.size } val argsSizeOnStack = parameters.sumBy { it.type.size }
val capturedArgsSizeOnStack = captured.sumBy { it.type.size }
val argsSizeOnStack = realArgsSizeOnStack + capturedArgsSizeOnStack val realParametersSizeOnStack: Int
get() = argsSizeOnStack - capturedParametersSizeOnStack
val capturedParametersSizeOnStack by lazy {
captured.sumBy { it.type.size }
}
val captured by lazy {
parameters.filterIsInstance<CapturedParamInfo>()
}
init { init {
val declIndexesToActual = arrayOfNulls<Int>(argsSizeOnStack) val declIndexesToActual = arrayOfNulls<Int>(argsSizeOnStack)
@@ -54,21 +62,15 @@ internal class Parameters(val real: List<ParameterInfo>, val captured: List<Capt
} }
private fun get(index: Int): ParameterInfo { private fun get(index: Int): ParameterInfo {
return real.getOrNull(index) ?: captured[index - real.size] return parameters[index]
} }
override fun iterator(): Iterator<ParameterInfo> { override fun iterator(): Iterator<ParameterInfo> {
return (real + captured).iterator() return parameters.iterator()
} }
val capturedTypes: List<Type> val capturedTypes: List<Type>
get() = captured.map { get() = captured.map {
it.getType() it.getType()
} }
companion object {
fun shift(capturedParams: List<CapturedParamInfo>, realSize: Int): List<CapturedParamInfo> {
return capturedParams.withIndex().map { it.value.newIndex(it.index + realSize) }
}
}
} }
@@ -18,49 +18,45 @@ package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import java.util.*
internal class ParametersBuilder private constructor() { internal class ParametersBuilder private constructor() {
private val valueAndHiddenParams = arrayListOf<ParameterInfo>()
private val capturedParams = arrayListOf<CapturedParamInfo>()
private var valueParamStart = 0
var nextValueParameterIndex = 0 private val params = arrayListOf<ParameterInfo>()
private var valueParamFirstIndex = 0
var nextParameterOffset = 0
private set private set
private var nextCaptured = 0 private var nextValueParameterIndex = 0
fun addThis(type: Type, skipped: Boolean): ParameterInfo { fun addThis(type: Type, skipped: Boolean): ParameterInfo {
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1, valueAndHiddenParams.size) return addParameter(ParameterInfo(type, skipped, nextParameterOffset, -1, nextValueParameterIndex))
addParameter(info)
return info
} }
fun addNextParameter(type: Type, skipped: Boolean): ParameterInfo { fun addNextParameter(type: Type, skipped: Boolean): ParameterInfo {
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, null, valueAndHiddenParams.size)) return addParameter(ParameterInfo(type, skipped, nextParameterOffset, null, nextValueParameterIndex))
} }
fun addNextValueParameter(type: Type, skipped: Boolean, remapValue: StackValue?, parameterIndex: Int): ParameterInfo { fun addNextValueParameter(type: Type, skipped: Boolean, remapValue: StackValue?, parameterIndex: Int): ParameterInfo {
return addParameter(ParameterInfo( return addParameter(ParameterInfo(
type, skipped, nextValueParameterIndex, remapValue, type, skipped, nextParameterOffset, remapValue,
if (parameterIndex == -1) valueAndHiddenParams.size else parameterIndex + valueParamStart if (parameterIndex == -1) nextValueParameterIndex else parameterIndex + valueParamFirstIndex
)) ))
} }
fun addCapturedParam(original: CapturedParamInfo, newFieldName: String): CapturedParamInfo { fun addCapturedParam(original: CapturedParamInfo, newFieldName: String): CapturedParamInfo {
val info = CapturedParamInfo(original.desc, newFieldName, original.isSkipped, nextCapturedIndex(), original.index) val info = CapturedParamInfo(original.desc, newFieldName, original.isSkipped, nextParameterOffset, original.index)
info.lambda = original.lambda info.lambda = original.lambda
return addCapturedParameter(info) return addParameter(info)
} }
private fun nextCapturedIndex(): Int = nextCaptured
fun addCapturedParam(desc: CapturedParamDesc, newFieldName: String, skipInConstructor: Boolean): CapturedParamInfo { fun addCapturedParam(desc: CapturedParamDesc, newFieldName: String, skipInConstructor: Boolean): CapturedParamInfo {
return addCapturedParameter(CapturedParamInfo(desc, newFieldName, false, nextCapturedIndex(), null, skipInConstructor)) return addParameter(CapturedParamInfo(desc, newFieldName, false, nextParameterOffset, null, skipInConstructor, -1))
} }
fun addCapturedParamCopy(copyFrom: CapturedParamInfo): CapturedParamInfo { fun addCapturedParamCopy(copyFrom: CapturedParamInfo): CapturedParamInfo {
return addCapturedParameter(copyFrom.newIndex(nextCapturedIndex())) return addParameter(copyFrom.cloneWithNewDeclarationIndex(-1))
} }
fun addCapturedParam( fun addCapturedParam(
@@ -72,41 +68,48 @@ internal class ParametersBuilder private constructor() {
original: ParameterInfo? original: ParameterInfo?
): CapturedParamInfo { ): CapturedParamInfo {
val info = CapturedParamInfo( val info = CapturedParamInfo(
CapturedParamDesc(containingLambdaType, fieldName, type), newFieldName, skipped, nextCapturedIndex(), original?.index ?: -1 CapturedParamDesc(containingLambdaType, fieldName, type), newFieldName, skipped, nextParameterOffset, original?.index ?: -1
) )
if (original != null) { if (original != null) {
info.lambda = original.lambda info.lambda = original.lambda
} }
return addCapturedParameter(info) return addParameter(info)
} }
private fun addParameter(info: ParameterInfo): ParameterInfo { private fun <T: ParameterInfo> addParameter(info: T): T {
valueAndHiddenParams.add(info) params.add(info)
nextValueParameterIndex += info.getType().size nextParameterOffset += info.getType().size
return info if (info !is CapturedParamInfo) {
} nextValueParameterIndex++
}
private fun addCapturedParameter(info: CapturedParamInfo): CapturedParamInfo {
capturedParams.add(info)
nextCaptured += info.getType().size
return info return info
} }
fun markValueParametersStart() { fun markValueParametersStart() {
this.valueParamStart = valueAndHiddenParams.size this.valueParamFirstIndex = params.size
this.nextValueParameterIndex = valueParamFirstIndex
} }
fun listCaptured(): List<CapturedParamInfo> { fun listCaptured(): List<CapturedParamInfo> {
return Collections.unmodifiableList(capturedParams) return params.filterIsInstance<CapturedParamInfo>()
} }
/*TODO use Parameters instead*/ /*TODO use Parameters instead*/
fun listAllParams(): List<ParameterInfo> { fun listAllParams(): List<ParameterInfo> {
return valueAndHiddenParams + capturedParams return params
} }
fun buildParameters(): Parameters { fun buildParameters(): Parameters {
return Parameters(Collections.unmodifiableList(valueAndHiddenParams), Parameters.shift(listCaptured(), nextValueParameterIndex)) var nextDeclarationIndex = (params.maxBy { it.declarationIndex }?.declarationIndex ?: -1) + 1
return Parameters(params.map { param ->
if (param is CapturedParamInfo) {
param.cloneWithNewDeclarationIndex(nextDeclarationIndex++)
}
else {
param
}
})
} }
companion object { companion object {