1418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
2418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// for details. All rights reserved. Use of this source code is governed by a
3418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// BSD-style license that can be found in the LICENSE file.
4418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerpackage com.android.tools.r8.ir.code;
5418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
6418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.code.InvokeVirtualRange;
7418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.AppInfoWithSubtyping;
8418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.DexEncodedMethod;
9418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.graph.DexMethod;
10418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.ir.conversion.DexBuilder;
11418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.ir.optimize.Inliner.InlineAction;
12418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.ir.optimize.InliningOracle;
13418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.List;
14418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
1582e83bfe2977f0b1171e994b263f25ceefa6ca1cLars Bakpublic class InvokeVirtual extends InvokeMethodWithReceiver {
16418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
17418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  public InvokeVirtual(DexMethod target, Value result, List<Value> arguments) {
18418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    super(target, result, arguments);
19418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  }
20418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
21418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  @Override
22418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  public Type getType() {
23418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    return Type.VIRTUAL;
24418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  }
25418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
26418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  @Override
27418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  protected String getTypeString() {
28418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    return "Virtual";
29418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  }
30418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
31418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  @Override
32418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  public DexEncodedMethod computeSingleTarget(AppInfoWithSubtyping appInfo) {
33418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    return appInfo.lookupSingleVirtualTarget(getInvokedMethod());
34418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  }
35418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
36418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  @Override
37418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  public void buildDex(DexBuilder builder) {
38418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    com.android.tools.r8.code.Instruction instruction;
39418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    int argumentRegisters = requiredArgumentRegisters();
40418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    builder.requestOutgoingRegisters(argumentRegisters);
419fda6c5a9126db4d01576f623d86efddbceaabd3Mads Ager    if (needsRangedInvoke(builder)) {
42418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager      assert argumentsConsecutive(builder);
43418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager      int firstRegister = argumentRegisterValue(0, builder);
44418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager      instruction = new InvokeVirtualRange(firstRegister, argumentRegisters, getInvokedMethod());
45418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    } else {
46418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager      int[] individualArgumentRegisters = new int[5];
47418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager      int argumentRegistersCount = fillArgumentRegisters(builder, individualArgumentRegisters);
48418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager      instruction = new com.android.tools.r8.code.InvokeVirtual(
49418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager          argumentRegistersCount,
50418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager          getInvokedMethod(),
51418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager          individualArgumentRegisters[0],  // C
52418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager          individualArgumentRegisters[1],  // D
53418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager          individualArgumentRegisters[2],  // E
54418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager          individualArgumentRegisters[3],  // F
55418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager          individualArgumentRegisters[4]); // G
56418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    }
57418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    addInvokeAndMoveResult(instruction, builder);
58418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  }
59418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
60418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  @Override
61418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  public boolean identicalNonValueParts(Instruction other) {
62418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    if (!other.isInvokeVirtual()) {
63418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager      return false;
64418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    }
65418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    return super.identicalNonValueParts(other);
66418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  }
67418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
68418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  @Override
69418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  public boolean isInvokeVirtual() {
70418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    return true;
71418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  }
72418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
73418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  @Override
74418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  public InvokeVirtual asInvokeVirtual() {
75418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    return this;
76418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  }
77418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager
78418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  @Override
79418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  public InlineAction computeInlining(InliningOracle decider) {
80418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager    return decider.computeForInvokeVirtual(this);
81418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager  }
82418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager}
83