• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4 package com.android.tools.r8.graph;
5 
6 import com.android.tools.r8.dex.IndexedItemCollection;
7 import com.android.tools.r8.errors.CompilationError;
8 import com.android.tools.r8.naming.NamingLens;
9 
10 public class DexMethod extends Descriptor<DexEncodedMethod, DexMethod>
11     implements PresortedComparable<DexMethod> {
12 
13   public final DexType holder;
14   public final DexProto proto;
15   public final DexString name;
16 
17   // Caches used during processing.
18   private DexEncodedMethod singleTargetCache;
19 
DexMethod(DexType holder, DexProto proto, DexString name)20   DexMethod(DexType holder, DexProto proto, DexString name) {
21     this.holder = holder;
22     this.proto = proto;
23     this.name = name;
24     if (!name.isValidMethodName()) {
25       throw new CompilationError(
26           "Method name '" + name.toString() + "' cannot be represented in dex format.");
27     }
28   }
29 
30   @Override
toString()31   public String toString() {
32     return "Method " + holder + "." + name + " " + proto.toString();
33   }
34 
35   @Override
collectIndexedItems(IndexedItemCollection indexedItems)36   public void collectIndexedItems(IndexedItemCollection indexedItems) {
37     if (indexedItems.addMethod(this)) {
38       holder.collectIndexedItems(indexedItems);
39       proto.collectIndexedItems(indexedItems);
40       indexedItems.getRenamedName(this).collectIndexedItems(indexedItems);
41     }
42   }
43 
44   @Override
getOffset(ObjectToOffsetMapping mapping)45   public int getOffset(ObjectToOffsetMapping mapping) {
46     return mapping.getOffsetFor(this);
47   }
48 
computeHashCode()49   public int computeHashCode() {
50     return holder.hashCode()
51         + proto.hashCode() * 7
52         + name.hashCode() * 31;
53   }
54 
computeEquals(Object other)55   public boolean computeEquals(Object other) {
56     if (other instanceof DexMethod) {
57       DexMethod o = (DexMethod) other;
58       return holder.equals(o.holder)
59           && name.equals(o.name)
60           && proto.equals(o.proto);
61     }
62     return false;
63   }
64 
65   @Override
compareTo(DexMethod other)66   public int compareTo(DexMethod other) {
67     return sortedCompareTo(other.getSortedIndex());
68   }
69 
70   @Override
slowCompareTo(DexMethod other)71   public int slowCompareTo(DexMethod other) {
72     int result = holder.slowCompareTo(other.holder);
73     if (result != 0) {
74       return result;
75     }
76     result = name.slowCompareTo(other.name);
77     if (result != 0) {
78       return result;
79     }
80     return proto.slowCompareTo(other.proto);
81   }
82 
83   @Override
slowCompareTo(DexMethod other, NamingLens namingLens)84   public int slowCompareTo(DexMethod other, NamingLens namingLens) {
85     int result = holder.slowCompareTo(other.holder, namingLens);
86     if (result != 0) {
87       return result;
88     }
89     result = namingLens.lookupName(this).slowCompareTo(namingLens.lookupName(other));
90     if (result != 0) {
91       return result;
92     }
93     return proto.slowCompareTo(other.proto, namingLens);
94   }
95 
96   @Override
layeredCompareTo(DexMethod other, NamingLens namingLens)97   public int layeredCompareTo(DexMethod other, NamingLens namingLens) {
98     int result = holder.compareTo(other.holder);
99     if (result != 0) {
100       return result;
101     }
102     result = namingLens.lookupName(this).compareTo(namingLens.lookupName(other));
103     if (result != 0) {
104       return result;
105     }
106     return proto.compareTo(other.proto);
107   }
108 
109   @Override
match(DexEncodedMethod entry)110   public boolean match(DexEncodedMethod entry) {
111     return entry.method.name == name && entry.method.proto == proto;
112   }
113 
114   @Override
getHolder()115   public DexType getHolder() {
116     return holder;
117   }
118 
qualifiedName()119   public String qualifiedName() {
120     return holder + "." + name;
121   }
122 
toSmaliString()123   public String toSmaliString() {
124     return holder.toSmaliString() + "->" + name + proto.toSmaliString();
125   }
126 
toSourceString()127   public String toSourceString() {
128     StringBuilder builder = new StringBuilder();
129     builder.append(proto.returnType.toSourceString());
130     builder.append(" ");
131     builder.append(holder.toSourceString());
132     builder.append(".");
133     builder.append(name);
134     builder.append("(");
135     for (int i = 0; i < proto.parameters.values.length; i++) {
136       if (i != 0) {
137         builder.append(", ");
138       }
139       builder.append(proto.parameters.values[i].toSourceString());
140     }
141     builder.append(")");
142     return builder.toString();
143   }
144 
setSingleVirtualMethodCache(DexEncodedMethod method)145   synchronized public void setSingleVirtualMethodCache(DexEncodedMethod method) {
146     singleTargetCache = method == null ? DexEncodedMethod.SENTINEL : method;
147   }
148 
isSingleVirtualMethodCached()149   synchronized public boolean isSingleVirtualMethodCached() {
150     return singleTargetCache != null;
151   }
152 
getSingleVirtualMethodCache()153   synchronized public DexEncodedMethod getSingleVirtualMethodCache() {
154     assert isSingleVirtualMethodCached();
155     return singleTargetCache == DexEncodedMethod.SENTINEL ? null : singleTargetCache;
156   }
157 }
158