blob: 7cc7830b93beaf940974eb0f5ccae92ca2d2c794 [file] [log] [blame]
// Copyright (c) 2021, 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.graph;
import com.android.tools.r8.dex.CodeToKeep;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexCode.Try;
import com.android.tools.r8.graph.DexCode.TryHandler;
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
import com.android.tools.r8.utils.structural.CompareToVisitor;
import com.android.tools.r8.utils.structural.HashingVisitor;
import java.nio.ShortBuffer;
public interface DexWritableCode {
enum DexWritableCodeKind {
DEFAULT,
DEFAULT_INSTANCE_INITIALIZER,
THROW_NULL,
THROW_EXCEPTION
}
boolean isThrowExceptionCode();
ThrowExceptionCode asThrowExceptionCode();
default int acceptCompareTo(DexWritableCode code, CompareToVisitor visitor) {
DexWritableCodeKind kind = getDexWritableCodeKind();
DexWritableCodeKind otherKind = code.getDexWritableCodeKind();
if (kind != otherKind) {
return kind.compareTo(otherKind);
}
switch (kind) {
case DEFAULT:
return asDexCode().acceptCompareTo(code.asDexCode(), visitor);
case DEFAULT_INSTANCE_INITIALIZER:
return 0;
case THROW_NULL:
return 0;
case THROW_EXCEPTION:
assert isThrowExceptionCode();
return asThrowExceptionCode().acceptCompareTo(code.asThrowExceptionCode(), visitor);
default:
throw new Unreachable();
}
}
void acceptHashing(HashingVisitor visitor);
int codeSizeInBytes();
void collectIndexedItems(
AppView<?> appView,
GraphLens codeLens,
IndexedItemCollection indexedItems,
ProgramMethod context,
LensCodeRewriterUtils rewriter);
void collectMixedSectionItems(MixedSectionCollection mixedItems);
void writeKeepRulesForDesugaredLibrary(CodeToKeep codeToKeep);
GraphLens getCodeLens(AppView<?> appView);
DexDebugInfoForWriting getDebugInfoForWriting();
DexWritableCodeKind getDexWritableCodeKind();
DexString getHighestSortingString();
TryHandler[] getHandlers();
Try[] getTries();
int getRegisterSize(ProgramMethod method);
int getIncomingRegisterSize(ProgramMethod method);
int getOutgoingRegisterSize();
Code asCode();
default boolean isDexCode() {
return false;
}
default DexCode asDexCode() {
return null;
}
DexWritableCacheKey getCacheLookupKey(ProgramMethod method, DexItemFactory factory);
/** Rewrites the code to have JumboString bytecode if required by mapping. */
DexWritableCode rewriteCodeWithJumboStrings(
ProgramMethod method, ObjectToOffsetMapping mapping, AppView<?> appView, boolean force);
void setCallSiteContexts(ProgramMethod method);
void writeDex(
ShortBuffer shortBuffer,
ProgramMethod context,
GraphLens graphLens,
GraphLens codeLens,
LensCodeRewriterUtils lensCodeRewriter,
ObjectToOffsetMapping mapping);
interface DexWritableCacheKey {}
class DexWritableCodeKey implements DexWritableCacheKey {
private final DexWritableCode code;
private final int incomingRegisterSize;
private final int registerSize;
public DexWritableCodeKey(DexWritableCode code, int incomingRegisterSize, int registerSize) {
this.code = code;
this.incomingRegisterSize = incomingRegisterSize;
this.registerSize = registerSize;
}
@Override
public int hashCode() {
return code.hashCode() + incomingRegisterSize * 13 + registerSize * 17;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof DexWritableCodeKey)) {
return false;
}
DexWritableCodeKey that = (DexWritableCodeKey) other;
return code.equals(that.code)
&& incomingRegisterSize == that.incomingRegisterSize
&& registerSize == that.registerSize;
}
}
class AmendedDexWritableCodeKey<S> extends DexWritableCodeKey {
private final S extra;
public AmendedDexWritableCodeKey(
DexWritableCode code, S extra, int incomingRegisterSize, int registerSize) {
super(code, incomingRegisterSize, registerSize);
this.extra = extra;
}
@Override
public int hashCode() {
return super.hashCode() + extra.hashCode() * 7;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AmendedDexWritableCodeKey)) {
return false;
}
AmendedDexWritableCodeKey that = (AmendedDexWritableCodeKey) other;
return super.equals(other) && extra.equals(that.extra);
}
}
}