Parameters refactoring

This commit is contained in:
Michael Bogdanov
2015-09-30 18:16:35 +03:00
parent 1900ddd020
commit 466b20b0fc
7 changed files with 68 additions and 119 deletions
@@ -251,7 +251,7 @@ public class AnonymousObjectTransformer {
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.totalSize()]; int [] capturedIndexes = new int [constructorParams.getReal().size() + constructorParams.getCaptured().size()];
int index = 0; int index = 0;
int size = 0; int size = 0;
@@ -289,7 +289,7 @@ public class InlineCodegen extends CallGenerator {
}; };
List<MethodInliner.PointForExternalFinallyBlocks> infos = MethodInliner.processReturns(adapter, labelOwner, true, null); List<MethodInliner.PointForExternalFinallyBlocks> infos = MethodInliner.processReturns(adapter, labelOwner, true, null);
generateAndInsertFinallyBlocks(adapter, infos, ((StackValue.Local)remapper.remap(parameters.totalSize() + 1).value).index); generateAndInsertFinallyBlocks(adapter, infos, ((StackValue.Local)remapper.remap(parameters.getArgsSizeOnStack() + 1).value).index);
removeFinallyMarkers(adapter); removeFinallyMarkers(adapter);
adapter.accept(new InliningInstructionAdapter(codegen.v)); adapter.accept(new InliningInstructionAdapter(codegen.v));
@@ -38,18 +38,16 @@ public class LocalVarRemapper {
public LocalVarRemapper(Parameters params, int additionalShift) { public LocalVarRemapper(Parameters params, int additionalShift) {
this.additionalShift = additionalShift; this.additionalShift = additionalShift;
this.allParamsSize = params.totalSize(); this.allParamsSize = params.getArgsSizeOnStack();
this.params = params; this.params = params;
remapValues = new StackValue [params.totalSize()]; remapValues = new StackValue [params.getArgsSizeOnStack()];
Integer [] declIndexesToActual = new Integer [params.totalSize()]; Integer [] declIndexesToActual = new Integer [params.getArgsSizeOnStack()];
Integer [] actualDeclShifts = new Integer [params.totalSize()]; Integer [] actualDeclShifts = new Integer [params.getArgsSizeOnStack()];
int index = 0; int index = 0;
for (ParameterInfo param : params) { for (ParameterInfo param : params) {
if (param != ParameterInfo.STUB && param != CapturedParamInfo.STUB) { declIndexesToActual[param.declarationIndex] = index;
declIndexesToActual[param.declarationIndex] = index;
}
index++; index++;
} }
@@ -64,14 +62,12 @@ public class LocalVarRemapper {
realSize = 0; realSize = 0;
for (ParameterInfo info : params) { for (ParameterInfo info : params) {
if (info != ParameterInfo.STUB && info != CapturedParamInfo.STUB) { if (!info.isSkippedOrRemapped()) {
if (!info.isSkippedOrRemapped()) { remapValues[actualDeclShifts[info.declarationIndex]] = StackValue.local(realSize, AsmTypes.OBJECT_TYPE);
remapValues[actualDeclShifts[info.declarationIndex]] = StackValue.local(realSize, AsmTypes.OBJECT_TYPE); realSize += info.getType().getSize();
realSize += info.getType().getSize(); }
} else {
else { remapValues[actualDeclShifts[info.declarationIndex]] = info.isRemapped() ? info.getRemapValue() : null;
remapValues[actualDeclShifts[info.declarationIndex]] = info.isRemapped() ? info.getRemapValue() : null;
}
} }
} }
@@ -93,7 +89,7 @@ public class LocalVarRemapper {
remappedIndex = ((StackValue.Local)remapped).index; remappedIndex = ((StackValue.Local)remapped).index;
} }
} else { } else {
remappedIndex = actualParamsSize - params.totalSize() + index; //captured params not used directly in this inlined method, they used in closure remappedIndex = actualParamsSize - params.getArgsSizeOnStack() + index; //captured params not used directly in this inlined method, they used in closure
} }
return new RemapInfo(StackValue.local(remappedIndex + additionalShift, AsmTypes.OBJECT_TYPE), null, SHIFT); return new RemapInfo(StackValue.local(remappedIndex + additionalShift, AsmTypes.OBJECT_TYPE), null, SHIFT);
@@ -133,7 +133,7 @@ public class MethodInliner {
resultNode.visitLabel(end); resultNode.visitLabel(end);
if (inliningContext.isRoot()) { if (inliningContext.isRoot()) {
InternalFinallyBlockInliner.processInlineFunFinallyBlocks(resultNode, lambdasFinallyBlocks, ((StackValue.Local)remapper.remap(parameters.totalSize() + 1).value).index); InternalFinallyBlockInliner.processInlineFunFinallyBlocks(resultNode, lambdasFinallyBlocks, ((StackValue.Local)remapper.remap(parameters.getArgsSizeOnStack() + 1).value).index);
} }
processReturns(resultNode, labelOwner, remapReturn, end); processReturns(resultNode, labelOwner, remapReturn, end);
@@ -155,7 +155,7 @@ public class MethodInliner {
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode, RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode,
new TypeRemapper(currentTypeMapping)); new TypeRemapper(currentTypeMapping));
InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.totalSize(), sourceMapper) { InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) {
private AnonymousObjectGeneration anonymousObjectGen; private AnonymousObjectGeneration anonymousObjectGen;
private void handleAnonymousObjectGeneration() { private void handleAnonymousObjectGeneration() {
@@ -307,8 +307,8 @@ public class MethodInliner {
@NotNull @NotNull
public MethodNode prepareNode(@NotNull MethodNode node, int finallyDeepShift) { public MethodNode prepareNode(@NotNull MethodNode node, int finallyDeepShift) {
final int capturedParamsSize = parameters.getCaptured().size(); final int capturedParamsSize = parameters.getCapturedArgsSizeOnStack();
final int realParametersSize = parameters.getReal().size(); final int realParametersSize = parameters.getRealArgsSizeOnStack();
Type[] types = Type.getArgumentTypes(node.desc); Type[] types = Type.getArgumentTypes(node.desc);
Type returnType = Type.getReturnType(node.desc); Type returnType = Type.getReturnType(node.desc);
@@ -558,7 +558,7 @@ public class MethodInliner {
} }
private LambdaInfo getLambdaIfExists(int varIndex) { private LambdaInfo getLambdaIfExists(int varIndex) {
if (varIndex < parameters.totalSize()) { if (varIndex < parameters.getArgsSizeOnStack()) {
return parameters.getByByteCodeIndex(varIndex).getLambda(); return parameters.getByByteCodeIndex(varIndex).getLambda();
} }
return null; return null;
@@ -19,13 +19,10 @@ package org.jetbrains.kotlin.codegen.inline;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.StackValue; import org.jetbrains.kotlin.codegen.StackValue;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
class ParameterInfo { class ParameterInfo {
public static final ParameterInfo STUB = new ParameterInfo(AsmTypes.OBJECT_TYPE, true, -1, -1, -1);
protected final int index; protected final int index;
protected final int declarationIndex; protected final int declarationIndex;
@@ -14,115 +14,81 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.codegen.inline; package org.jetbrains.kotlin.codegen.inline
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables
import org.jetbrains.annotations.NotNull; import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.Type;
import java.util.ArrayList; import java.util.ArrayList
import java.util.Iterator;
import java.util.List;
//All parameters with gaps //All parameters with gaps
public class Parameters implements Iterable<ParameterInfo> { class Parameters(val real: List<ParameterInfo>, val captured: List<CapturedParamInfo>) : Iterable<ParameterInfo> {
private final List<ParameterInfo> real;
private final List<CapturedParamInfo> captured;
private final Integer [] declIndexesToActual; private val declIndexesToActual: Array<Int?>
private final ParameterInfo [] actualDeclShifts; private val actualDeclShifts: Array<ParameterInfo?>
public Parameters(List<ParameterInfo> real, List<CapturedParamInfo> captured) { public val realArgsSizeOnStack = real.fold(0, { a, v -> a + v.type.size})
this.real = real; public val capturedArgsSizeOnStack = captured.fold(0, { a, v -> a + v.type.size})
this.captured = captured;
declIndexesToActual = new Integer [totalSize()]; public val argsSizeOnStack = realArgsSizeOnStack + capturedArgsSizeOnStack
int index = 0; init {
for (ParameterInfo param : this) { declIndexesToActual = arrayOfNulls<Int>(argsSizeOnStack)
if (param != ParameterInfo.STUB && param != CapturedParamInfo.STUB) { withIndex().forEach { it ->
declIndexesToActual[param.declarationIndex] = index; declIndexesToActual[it.value.declarationIndex] = it.index
}
index++;
} }
actualDeclShifts = new ParameterInfo [totalSize()]; actualDeclShifts = arrayOfNulls<ParameterInfo>(argsSizeOnStack)
int realSize = 0; var realSize = 0
for (int i = 0; i < declIndexesToActual.length; i++) { for (i in declIndexesToActual.indices) {
Integer declIndexToActual = declIndexesToActual[i]; val declIndexToActual = declIndexesToActual[i]
if (declIndexToActual != null) { if (declIndexToActual != null) {
actualDeclShifts[realSize] = getByDeclarationIndex(i); val byDeclarationIndex = getByDeclarationIndex(i)
realSize += get(declIndexToActual).getType().getSize(); actualDeclShifts[realSize] = byDeclarationIndex
realSize += byDeclarationIndex.type.size
} }
} }
} }
public List<ParameterInfo> getReal() { fun getByDeclarationIndex(index: Int): ParameterInfo {
return real; if (index < realArgsSizeOnStack) {
return real.get(declIndexesToActual[index]!!)
}
return captured.get(declIndexesToActual[index]!! - real.size())
} }
public List<CapturedParamInfo> getCaptured() { fun getByByteCodeIndex(index: Int): ParameterInfo {
return captured; return actualDeclShifts[index]!!
} }
public int totalSize() { fun get(index: Int): ParameterInfo {
return real.size() + captured.size();
}
public ParameterInfo getByDeclarationIndex(int index) {
if (index < real.size()) { if (index < real.size()) {
return real.get(declIndexesToActual[index]); return real.get(index)
} }
return captured.get(index - real.size()); return captured.get(index - real.size())
} }
public ParameterInfo getByByteCodeIndex(int index) { override fun iterator(): Iterator<ParameterInfo> {
return actualDeclShifts[index]; return Iterables.concat(real, captured).iterator()
} }
public ParameterInfo get(int index) { val capturedTypes: ArrayList<Type>
if (index < real.size()) { get() {
return real.get(index); val result = ArrayList<Type>()
} for (info in captured) {
return captured.get(index - real.size()); result.add(info.getType())
}
@NotNull
@Override
public Iterator<ParameterInfo> iterator() {
return Iterables.concat(real, captured).iterator();
}
public static List<CapturedParamInfo> shiftAndAddStubs(List<CapturedParamInfo> capturedParams, int realSize) {
List<CapturedParamInfo> result = new ArrayList<CapturedParamInfo>();
for (CapturedParamInfo capturedParamInfo : capturedParams) {
CapturedParamInfo newInfo = capturedParamInfo.newIndex(result.size() + realSize);
result.add(newInfo);
if (capturedParamInfo.getType().getSize() == 2) {
result.add(CapturedParamInfo.STUB);
} }
return result
} }
return result;
}
public static List<ParameterInfo> addStubs(List<ParameterInfo> params) { companion object {
List<ParameterInfo> result = new ArrayList<ParameterInfo>(); fun shift(capturedParams: List<CapturedParamInfo>, realSize: Int): List<CapturedParamInfo> {
for (ParameterInfo newInfo : params) { val result = ArrayList<CapturedParamInfo>()
result.add(newInfo); for (capturedParamInfo in capturedParams) {
if (newInfo.getType().getSize() == 2) { val newInfo = capturedParamInfo.newIndex(result.size() + realSize)
result.add(ParameterInfo.STUB); result.add(newInfo)
} }
return result
} }
return result;
}
public ArrayList<Type> getCapturedTypes() {
ArrayList<Type> result = new ArrayList<Type>();
for (CapturedParamInfo info : captured) {
if(info != CapturedParamInfo.STUB) {
result.add(info.getType());
}
}
return result;
} }
} }
@@ -18,6 +18,7 @@ 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.lang.Deprecated
import java.util.ArrayList import java.util.ArrayList
import java.util.Collections import java.util.Collections
@@ -111,26 +112,15 @@ class ParametersBuilder private constructor(){
return Collections.unmodifiableList(capturedParams) return Collections.unmodifiableList(capturedParams)
} }
/*TODO use Parameters instead*/
fun listAllParams(): List<ParameterInfo> { fun listAllParams(): List<ParameterInfo> {
return valueAndHiddenParams + capturedParams return valueAndHiddenParams + capturedParams
} }
private fun buildWithStubs(): List<ParameterInfo> {
return Parameters.addStubs(listNotCaptured())
}
private fun buildCapturedWithStubs(): List<CapturedParamInfo> {
return Parameters.shiftAndAddStubs(listCaptured(), nextValueParameterIndex)
}
fun buildParameters(): Parameters { fun buildParameters(): Parameters {
return Parameters(buildWithStubs(), buildCapturedWithStubs()) return Parameters(listNotCaptured(), Parameters.shift(listCaptured(), nextValueParameterIndex))
} }
// public fun getValueParameter(index: Int): ParameterInfo {
// return valueAndHiddenParams[index + valueParamStart]
// }
companion object { companion object {
@JvmStatic @JvmStatic