blob: 7d8a82638ee4a758ae7df08b63a109998c741481 [file] [log] [blame]
// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.horizontalclassmerging.code;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClasspathMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadataProvider;
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.graph.proto.RewrittenPrototypeDescription;
import com.android.tools.r8.horizontalclassmerging.ConstructorEntryPoint;
import com.android.tools.r8.horizontalclassmerging.HorizontalClassMergerGraphLens;
import com.android.tools.r8.horizontalclassmerging.IncompleteHorizontalClassMergerCode;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.ir.conversion.IRToLirFinalizer;
import com.android.tools.r8.ir.conversion.MethodConversionOptions;
import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
import com.android.tools.r8.ir.conversion.SourceCode;
import com.android.tools.r8.lightir.LirCode;
import com.android.tools.r8.utils.RetracerForCodePrinting;
import com.android.tools.r8.utils.Timing;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
public class ConstructorEntryPointSynthesizedCode extends IncompleteHorizontalClassMergerCode {
private final DexField classIdField;
private int numberOfUnusedArguments;
private final Int2ReferenceSortedMap<DexMethod> typeConstructors;
public ConstructorEntryPointSynthesizedCode(
Int2ReferenceSortedMap<DexMethod> typeConstructors,
DexField classIdField,
int numberOfUnusedArguments) {
this.typeConstructors = typeConstructors;
this.classIdField = classIdField;
this.numberOfUnusedArguments = numberOfUnusedArguments;
}
@Override
public void addExtraUnusedArguments(int numberOfUnusedArguments) {
this.numberOfUnusedArguments += numberOfUnusedArguments;
}
private void registerReachableDefinitions(UseRegistry<?> registry) {
assert registry.getTraversalContinuation().shouldContinue();
for (DexMethod typeConstructor : typeConstructors.values()) {
registry.registerInvokeDirect(typeConstructor);
if (registry.getTraversalContinuation().shouldBreak()) {
return;
}
}
}
@Override
public boolean hasExplicitCodeLens() {
return true;
}
@Override
public GraphLens getCodeLens(AppView<?> appView) {
return appView
.graphLens()
.asNonIdentityLens()
.find(GraphLens::isHorizontalClassMergerGraphLens);
}
@Override
public LirCode<Integer> toLirCode(
AppView<? extends AppInfoWithClassHierarchy> appView,
ProgramMethod method,
HorizontalClassMergerGraphLens lens) {
for (Int2ReferenceMap.Entry<DexMethod> entry : typeConstructors.int2ReferenceEntrySet()) {
entry.setValue(lens.getNextMethodSignature(entry.getValue()));
}
IRCode irCode = buildIR(method, appView);
LirCode<Integer> lirCode =
new IRToLirFinalizer(appView)
.finalizeCode(irCode, BytecodeMetadataProvider.empty(), Timing.empty());
return new LirCode<>(lirCode) {
@Override
public boolean hasExplicitCodeLens() {
return true;
}
@Override
public GraphLens getCodeLens(AppView<?> appView) {
return lens;
}
};
}
@Override
public final boolean isEmptyVoidMethod() {
return false;
}
@Override
public final IRCode buildIR(
ProgramMethod method,
AppView<?> appView,
MutableMethodConversionOptions conversionOptions) {
SyntheticPosition position =
SyntheticPosition.builder()
.setLine(0)
.setMethod(method.getReference())
.setIsD8R8Synthesized(true)
.build();
SourceCode sourceCode =
new ConstructorEntryPoint(
typeConstructors, method, classIdField, numberOfUnusedArguments, position);
return IRBuilder.create(method, appView, sourceCode).build(method, conversionOptions);
}
@Override
public final IRCode buildInliningIR(
ProgramMethod context,
ProgramMethod method,
AppView<?> appView,
GraphLens codeLens,
NumberGenerator valueNumberGenerator,
Position callerPosition,
RewrittenPrototypeDescription protoChanges) {
SourceCode sourceCode =
new ConstructorEntryPoint(
typeConstructors, method, classIdField, numberOfUnusedArguments, callerPosition);
return IRBuilder.createForInlining(
method, appView, codeLens, sourceCode, valueNumberGenerator, protoChanges)
.build(context, MethodConversionOptions.nonConverting());
}
@Override
public final String toString() {
return toString(null, RetracerForCodePrinting.empty());
}
@Override
public final void registerCodeReferences(ProgramMethod method, UseRegistry registry) {
registerReachableDefinitions(registry);
}
@Override
public final void registerCodeReferencesForDesugaring(
ClasspathMethod method, UseRegistry registry) {
registerReachableDefinitions(registry);
}
@Override
protected final int computeHashCode() {
throw new Unreachable();
}
@Override
protected final boolean computeEquals(Object other) {
throw new Unreachable();
}
@Override
public final String toString(DexEncodedMethod method, RetracerForCodePrinting retracer) {
return this.getClass().getSimpleName();
}
@Override
public final int estimatedDexCodeSizeUpperBoundInBytes() {
return Integer.MAX_VALUE;
}
}