Don't generate default arguments for inline call

This commit is contained in:
Mikhael Bogdanov
2017-04-27 15:38:11 +02:00
parent 7690a8bc3e
commit a7c9e14805
13 changed files with 81 additions and 62 deletions
@@ -64,7 +64,7 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
@Override
protected void generateDefault(int i, @NotNull DefaultValueArgument argument) {
callGenerator.putValueIfNeeded(valueParameterTypes.get(i), createDefaulValue(valueParameterTypes.get(i)));
callGenerator.putValueIfNeeded(valueParameterTypes.get(i), createDefaulValue(valueParameterTypes.get(i)), ValueKind.DEFAULT_PARAMETER);
}
@Override
@@ -23,8 +23,10 @@ import org.jetbrains.org.objectweb.asm.Type
enum class ValueKind {
GENERAL,
DEFAULT_PARAMETER,
DEFAULT_MASK,
METHOD_HANDLE_IN_DEFAULT
METHOD_HANDLE_IN_DEFAULT,
CAPTURED
}
abstract class CallGenerator {
@@ -414,7 +414,7 @@ public class InlineCodegen extends CallGenerator {
defaultSourceMapper.setCallSiteMarker(new CallSiteMarker(codegen.getLastLineNumber()));
MethodNode node = nodeAndSmap.getNode();
if (callDefault) {
MethodInlinerUtilKt.expandMaskConditions(node, maskStartIndex, maskValues, methodHandleInDefaultMethodIndex);
MethodInlinerUtilKt.expandMaskConditionsAndUpdateVariableNodes(node, maskStartIndex, maskValues, methodHandleInDefaultMethodIndex);
}
ReifiedTypeParametersUsages reificationResult = reifiedTypeInliner.reifyInstructions(node);
generateClosuresBodies();
@@ -674,11 +674,17 @@ public class InlineCodegen extends CallGenerator {
@NotNull Type type,
@NotNull StackValue stackValue,
int capturedParamIndex,
int parameterIndex
int parameterIndex,
@NotNull ValueKind kind
) {
boolean isDefaultParameter = kind == ValueKind.DEFAULT_PARAMETER;
if (!isDefaultParameter && shouldPutGeneralValue(type, stackValue)) {
stackValue.put(type, codegen.v);
}
if (!asFunctionInline && Type.VOID_TYPE != type) {
//TODO remap only inlinable closure => otherwise we could get a lot of problem
boolean couldBeRemapped = !shouldPutGeneralValue(type, stackValue);
boolean couldBeRemapped = !shouldPutGeneralValue(type, stackValue) && kind != ValueKind.DEFAULT_PARAMETER;
StackValue remappedValue = couldBeRemapped ? stackValue : null;
ParameterInfo info;
@@ -691,7 +697,7 @@ public class InlineCodegen extends CallGenerator {
info = invocationParamBuilder.addNextValueParameter(type, false, remappedValue, parameterIndex);
}
recordParameterValueInLocalVal(false, info);
recordParameterValueInLocalVal(false, isDefaultParameter, info);
}
}
@@ -725,7 +731,7 @@ public class InlineCodegen extends CallGenerator {
return true;
}
private Runnable recordParameterValueInLocalVal(boolean delayedWritingToLocals, @NotNull ParameterInfo... infos) {
private Runnable recordParameterValueInLocalVal(boolean delayedWritingToLocals, boolean skipStore, @NotNull ParameterInfo... infos) {
int[] index = new int[infos.length];
for (int i = 0; i < infos.length; i++) {
ParameterInfo info = infos[i];
@@ -743,7 +749,9 @@ public class InlineCodegen extends CallGenerator {
if (!info.isSkippedOrRemapped()) {
Type type = info.type;
StackValue.Local local = StackValue.local(index[i], type);
local.store(StackValue.onStack(type), codegen.v);
if (!skipStore) {
local.store(StackValue.onStack(type), codegen.v);
}
if (info instanceof CapturedParamInfo) {
info.setRemapValue(local);
((CapturedParamInfo) info).setSynthetic(true);
@@ -773,7 +781,7 @@ public class InlineCodegen extends CallGenerator {
invocationParamBuilder.markValueParametersStart();
List<ParameterInfo> hiddenParameters = invocationParamBuilder.buildParameters().getParameters();
delayedHiddenWriting = recordParameterValueInLocalVal(justProcess, hiddenParameters.toArray(new ParameterInfo[hiddenParameters.size()]));
delayedHiddenWriting = recordParameterValueInLocalVal(justProcess, false, hiddenParameters.toArray(new ParameterInfo[hiddenParameters.size()]));
}
private void leaveTemps() {
@@ -924,11 +932,7 @@ public class InlineCodegen extends CallGenerator {
assert maskValues.isEmpty() : "Additional default call arguments should be last ones, but " + value;
if (shouldPutGeneralValue(parameterType, value)) {
value.put(parameterType, codegen.v);
}
putArgumentOrCapturedToLocalVal(parameterType, value, -1, index);
putArgumentOrCapturedToLocalVal(parameterType, value, -1, index, kind);
}
private boolean processDefaultMaskOrMethodHandler(@NotNull StackValue value, @NotNull ValueKind kind) {
@@ -953,10 +957,7 @@ public class InlineCodegen extends CallGenerator {
@Override
public void putCapturedValueOnStack(@NotNull StackValue stackValue, @NotNull Type valueType, int paramIndex) {
if (shouldPutGeneralValue(stackValue.type, stackValue)) {
stackValue.put(stackValue.type, codegen.v);
}
putArgumentOrCapturedToLocalVal(stackValue.type, stackValue, paramIndex, paramIndex);
putArgumentOrCapturedToLocalVal(stackValue.type, stackValue, paramIndex, paramIndex, ValueKind.CAPTURED);
}
private void generateAndInsertFinallyBlocks(
@@ -89,14 +89,17 @@ private fun MethodInliner.getLambdaIfExistsAndMarkInstructions(
fun SourceValue.singleOrNullInsn() = insns.singleOrNull()
fun expandMaskConditions(node: MethodNode, maskStartIndex: Int, masks: List<Int>, methodHandlerIndex: Int) {
class Condition(mask: Int, constant: Int, val maskInstruction: VarInsnNode, val jumpInstruction: JumpInsnNode) {
fun expandMaskConditionsAndUpdateVariableNodes(node: MethodNode, maskStartIndex: Int, masks: List<Int>, methodHandlerIndex: Int) {
class Condition(mask: Int, constant: Int, val maskInstruction: VarInsnNode, val jumpInstruction: JumpInsnNode, val varIndex: Int) {
val expandNotDelete = mask and constant != 0
}
fun isMaskIndex(varIndex: Int): Boolean {
return maskStartIndex <= varIndex && varIndex < maskStartIndex + masks.size
}
val maskProcessingHeader = node.instructions.asSequence().takeWhile {
if (it is VarInsnNode) {
if (isMaskIndex(it, maskStartIndex, masks)) {
if (isMaskIndex(it.`var`)) {
/*if slot for default mask is updated than we occurred in actual function body*/
return@takeWhile it.opcode == Opcodes.ILOAD
}
@@ -108,14 +111,16 @@ fun expandMaskConditions(node: MethodNode, maskStartIndex: Int, masks: List<Int>
}
val conditions = maskProcessingHeader.filterIsInstance<VarInsnNode>().mapNotNull {
if (isMaskIndex(it, maskStartIndex, masks) &&
if (isMaskIndex(it.`var`) &&
it.next?.next?.opcode == Opcodes.IAND &&
it.next.next.next?.opcode == Opcodes.IFEQ) {
val jumpInstruction = it.next?.next?.next as JumpInsnNode
Condition(
masks[it.`var` - maskStartIndex],
InlineCodegenUtil.getConstant(it.next),
it,
it.next?.next?.next as JumpInsnNode
jumpInstruction,
(jumpInstruction.label.previous as VarInsnNode).`var`
)
}
else if (isMethodHandleIndex(methodHandlerIndex, it) &&
@@ -123,17 +128,23 @@ fun expandMaskConditions(node: MethodNode, maskStartIndex: Int, masks: List<Int>
it.next.next?.opcode == Opcodes.NEW) {
//Always delete method handle for now
//This logic should be updated when method handles would be supported
Condition(0, 0, it,it.next as JumpInsnNode)
Condition(0, 0, it,it.next as JumpInsnNode, -1)
}
else null
}
val indexToVarNode = node.localVariables?.filter { it.index < maskStartIndex }?.associateBy { it.index } ?: emptyMap()
val toDelete = arrayListOf<AbstractInsnNode>()
conditions.forEach {
val jumpInstruction = it.jumpInstruction
InsnSequence(it.maskInstruction, (if (it.expandNotDelete) jumpInstruction.next else jumpInstruction.label)).forEach {
toDelete.add(it)
}
if (it.expandNotDelete) {
indexToVarNode[it.varIndex]?.let { varNode ->
varNode.start = it.jumpInstruction.label
}
}
}
toDelete.forEach {
@@ -141,10 +152,4 @@ fun expandMaskConditions(node: MethodNode, maskStartIndex: Int, masks: List<Int>
}
}
private fun isMethodHandleIndex(methodHandlerIndex: Int, it: VarInsnNode) = methodHandlerIndex == it.`var`
private fun isMaskIndex(variable: VarInsnNode, maskStartIndex: Int, masks: List<Int>): Boolean {
val varIndex = variable.`var`
return maskStartIndex <= varIndex && varIndex < maskStartIndex + masks.size
}
private fun isMethodHandleIndex(methodHandlerIndex: Int, it: VarInsnNode) = methodHandlerIndex == it.`var`