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>();
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 size = 0;
@@ -432,7 +432,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
Type[] types = Type.getArgumentTypes(constructorDesc);
for (Type type : types) {
LambdaInfo info = indexToLambda.get(constructorParamBuilder.getNextValueParameterIndex());
LambdaInfo info = indexToLambda.get(constructorParamBuilder.getNextParameterOffset());
ParameterInfo parameterInfo = constructorParamBuilder.addNextParameter(type, info != null);
parameterInfo.setLambda(info);
if (capturedParams.contains(parameterInfo.getIndex())) {
@@ -26,7 +26,7 @@ public class CapturedParamInfo extends ParameterInfo {
private final boolean skipInConstructor;
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.newFieldName = newFieldName;
this.skipInConstructor = false;
@@ -38,9 +38,10 @@ public class CapturedParamInfo extends ParameterInfo {
boolean skipped,
int index,
@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.newFieldName = newFieldName;
this.skipInConstructor = skipInConstructor;
@@ -57,13 +58,10 @@ public class CapturedParamInfo extends ParameterInfo {
}
@NotNull
public CapturedParamInfo newIndex(int newIndex) {
return clone(newIndex, getRemapValue());
}
@NotNull
private CapturedParamInfo clone(int newIndex, @Nullable StackValue newRemapIndex) {
CapturedParamInfo result = new CapturedParamInfo(desc, newFieldName, isSkipped, newIndex, newRemapIndex, skipInConstructor);
public CapturedParamInfo cloneWithNewDeclarationIndex(int newDeclarationIndex) {
CapturedParamInfo result = new CapturedParamInfo(
desc, newFieldName, isSkipped, getIndex(), getRemapValue(), skipInConstructor, newDeclarationIndex
);
result.setLambda(getLambda());
return result;
}
@@ -726,7 +726,7 @@ public class InlineCodegen extends CallGenerator {
}
invocationParamBuilder.markValueParametersStart();
List<ParameterInfo> hiddenParameters = invocationParamBuilder.buildParameters().getReal();
List<ParameterInfo> hiddenParameters = invocationParamBuilder.buildParameters().getParameters();
recordParameterValueInLocalVal(hiddenParameters.toArray(new ParameterInfo[hiddenParameters.size()]));
}
@@ -488,7 +488,7 @@ public class InlineCodegenUtil {
public static int calcMarkerShift(@NotNull Parameters parameters, @NotNull MethodNode node) {
int markerShiftTemp = getIndexAfterLastMarker(node);
return markerShiftTemp - parameters.getRealArgsSizeOnStack() + parameters.getArgsSizeOnStack();
return markerShiftTemp - parameters.getRealParametersSizeOnStack() + parameters.getArgsSizeOnStack();
}
private static int getIndexAfterLastMarker(@NotNull MethodNode node) {
@@ -340,8 +340,8 @@ public class MethodInliner {
@NotNull
private MethodNode prepareNode(@NotNull MethodNode node, int finallyDeepShift) {
final int capturedParamsSize = parameters.getCapturedArgsSizeOnStack();
final int realParametersSize = parameters.getRealArgsSizeOnStack();
final int capturedParamsSize = parameters.getCapturedParametersSizeOnStack();
final int realParametersSize = parameters.getRealParametersSizeOnStack();
Type[] types = Type.getArgumentTypes(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 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 paramToDeclByteCodeIndex: HashMap<ParameterInfo, Int> = hashMapOf()
val realArgsSizeOnStack = real.sumBy { it.type.size }
val capturedArgsSizeOnStack = captured.sumBy { it.type.size }
val argsSizeOnStack = parameters.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 {
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 {
return real.getOrNull(index) ?: captured[index - real.size]
return parameters[index]
}
override fun iterator(): Iterator<ParameterInfo> {
return (real + captured).iterator()
return parameters.iterator()
}
val capturedTypes: List<Type>
get() = captured.map {
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.org.objectweb.asm.Type
import java.util.*
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 var nextCaptured = 0
private var nextValueParameterIndex = 0
fun addThis(type: Type, skipped: Boolean): ParameterInfo {
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1, valueAndHiddenParams.size)
addParameter(info)
return info
return addParameter(ParameterInfo(type, skipped, nextParameterOffset, -1, nextValueParameterIndex))
}
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 {
return addParameter(ParameterInfo(
type, skipped, nextValueParameterIndex, remapValue,
if (parameterIndex == -1) valueAndHiddenParams.size else parameterIndex + valueParamStart
type, skipped, nextParameterOffset, remapValue,
if (parameterIndex == -1) nextValueParameterIndex else parameterIndex + valueParamFirstIndex
))
}
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
return addCapturedParameter(info)
return addParameter(info)
}
private fun nextCapturedIndex(): Int = nextCaptured
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 {
return addCapturedParameter(copyFrom.newIndex(nextCapturedIndex()))
return addParameter(copyFrom.cloneWithNewDeclarationIndex(-1))
}
fun addCapturedParam(
@@ -72,41 +68,48 @@ internal class ParametersBuilder private constructor() {
original: ParameterInfo?
): 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) {
info.lambda = original.lambda
}
return addCapturedParameter(info)
return addParameter(info)
}
private fun addParameter(info: ParameterInfo): ParameterInfo {
valueAndHiddenParams.add(info)
nextValueParameterIndex += info.getType().size
return info
}
private fun addCapturedParameter(info: CapturedParamInfo): CapturedParamInfo {
capturedParams.add(info)
nextCaptured += info.getType().size
private fun <T: ParameterInfo> addParameter(info: T): T {
params.add(info)
nextParameterOffset += info.getType().size
if (info !is CapturedParamInfo) {
nextValueParameterIndex++
}
return info
}
fun markValueParametersStart() {
this.valueParamStart = valueAndHiddenParams.size
this.valueParamFirstIndex = params.size
this.nextValueParameterIndex = valueParamFirstIndex
}
fun listCaptured(): List<CapturedParamInfo> {
return Collections.unmodifiableList(capturedParams)
return params.filterIsInstance<CapturedParamInfo>()
}
/*TODO use Parameters instead*/
fun listAllParams(): List<ParameterInfo> {
return valueAndHiddenParams + capturedParams
return params
}
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 {