1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "compiler_filter.h"
18 
19 #include <ostream>
20 
21 #include "base/utils.h"
22 
23 namespace art {
24 
IsAotCompilationEnabled(Filter filter)25 bool CompilerFilter::IsAotCompilationEnabled(Filter filter) {
26   switch (filter) {
27     case CompilerFilter::kAssumeVerified:
28     case CompilerFilter::kExtract:
29     case CompilerFilter::kVerify:
30     case CompilerFilter::kQuicken: return false;
31 
32     case CompilerFilter::kSpaceProfile:
33     case CompilerFilter::kSpace:
34     case CompilerFilter::kSpeedProfile:
35     case CompilerFilter::kSpeed:
36     case CompilerFilter::kEverythingProfile:
37     case CompilerFilter::kEverything: return true;
38   }
39   UNREACHABLE();
40 }
41 
IsJniCompilationEnabled(Filter filter)42 bool CompilerFilter::IsJniCompilationEnabled(Filter filter) {
43   switch (filter) {
44     case CompilerFilter::kAssumeVerified:
45     case CompilerFilter::kExtract:
46     case CompilerFilter::kVerify: return false;
47 
48     case CompilerFilter::kQuicken:
49     case CompilerFilter::kSpaceProfile:
50     case CompilerFilter::kSpace:
51     case CompilerFilter::kSpeedProfile:
52     case CompilerFilter::kSpeed:
53     case CompilerFilter::kEverythingProfile:
54     case CompilerFilter::kEverything: return true;
55   }
56   UNREACHABLE();
57 }
58 
IsQuickeningCompilationEnabled(Filter filter)59 bool CompilerFilter::IsQuickeningCompilationEnabled(Filter filter) {
60   switch (filter) {
61     case CompilerFilter::kAssumeVerified:
62     case CompilerFilter::kExtract:
63     case CompilerFilter::kVerify: return false;
64 
65     case CompilerFilter::kQuicken:
66     case CompilerFilter::kSpaceProfile:
67     case CompilerFilter::kSpace:
68     case CompilerFilter::kSpeedProfile:
69     case CompilerFilter::kSpeed:
70     case CompilerFilter::kEverythingProfile:
71     case CompilerFilter::kEverything: return true;
72   }
73   UNREACHABLE();
74 }
75 
IsAnyCompilationEnabled(Filter filter)76 bool CompilerFilter::IsAnyCompilationEnabled(Filter filter) {
77   return IsJniCompilationEnabled(filter) ||
78       IsQuickeningCompilationEnabled(filter) ||
79       IsAotCompilationEnabled(filter);
80 }
81 
IsVerificationEnabled(Filter filter)82 bool CompilerFilter::IsVerificationEnabled(Filter filter) {
83   switch (filter) {
84     case CompilerFilter::kAssumeVerified:
85     case CompilerFilter::kExtract: return false;
86 
87     case CompilerFilter::kVerify:
88     case CompilerFilter::kQuicken:
89     case CompilerFilter::kSpaceProfile:
90     case CompilerFilter::kSpace:
91     case CompilerFilter::kSpeedProfile:
92     case CompilerFilter::kSpeed:
93     case CompilerFilter::kEverythingProfile:
94     case CompilerFilter::kEverything: return true;
95   }
96   UNREACHABLE();
97 }
98 
DependsOnImageChecksum(Filter filter)99 bool CompilerFilter::DependsOnImageChecksum(Filter filter) {
100   // We run dex2dex with verification, so the oat file will depend on the
101   // image checksum if verification is enabled.
102   return IsVerificationEnabled(filter);
103 }
104 
DependsOnProfile(Filter filter)105 bool CompilerFilter::DependsOnProfile(Filter filter) {
106   switch (filter) {
107     case CompilerFilter::kAssumeVerified:
108     case CompilerFilter::kExtract:
109     case CompilerFilter::kVerify:
110     case CompilerFilter::kQuicken:
111     case CompilerFilter::kSpace:
112     case CompilerFilter::kSpeed:
113     case CompilerFilter::kEverything: return false;
114 
115     case CompilerFilter::kSpaceProfile:
116     case CompilerFilter::kSpeedProfile:
117     case CompilerFilter::kEverythingProfile: return true;
118   }
119   UNREACHABLE();
120 }
121 
GetNonProfileDependentFilterFrom(Filter filter)122 CompilerFilter::Filter CompilerFilter::GetNonProfileDependentFilterFrom(Filter filter) {
123   switch (filter) {
124     case CompilerFilter::kAssumeVerified:
125     case CompilerFilter::kExtract:
126     case CompilerFilter::kVerify:
127     case CompilerFilter::kQuicken:
128     case CompilerFilter::kSpace:
129     case CompilerFilter::kSpeed:
130     case CompilerFilter::kEverything:
131       return filter;
132 
133     case CompilerFilter::kSpaceProfile:
134       return CompilerFilter::kSpace;
135 
136     case CompilerFilter::kSpeedProfile:
137       return CompilerFilter::kSpeed;
138 
139     case CompilerFilter::kEverythingProfile:
140       return CompilerFilter::kEverything;
141   }
142   UNREACHABLE();
143 }
144 
GetSafeModeFilterFrom(Filter filter)145 CompilerFilter::Filter CompilerFilter::GetSafeModeFilterFrom(Filter filter) {
146   // For safe mode, we should not return a filter that generates AOT compiled
147   // code.
148   switch (filter) {
149     case CompilerFilter::kAssumeVerified:
150     case CompilerFilter::kExtract:
151     case CompilerFilter::kVerify:
152     case CompilerFilter::kQuicken:
153       return filter;
154 
155     case CompilerFilter::kSpace:
156     case CompilerFilter::kSpeed:
157     case CompilerFilter::kEverything:
158     case CompilerFilter::kSpaceProfile:
159     case CompilerFilter::kSpeedProfile:
160     case CompilerFilter::kEverythingProfile:
161       return CompilerFilter::kQuicken;
162   }
163   UNREACHABLE();
164 }
165 
IsAsGoodAs(Filter current,Filter target)166 bool CompilerFilter::IsAsGoodAs(Filter current, Filter target) {
167   return current >= target;
168 }
169 
IsBetter(Filter current,Filter target)170 bool CompilerFilter::IsBetter(Filter current, Filter target) {
171   return current > target;
172 }
173 
NameOfFilter(Filter filter)174 std::string CompilerFilter::NameOfFilter(Filter filter) {
175   switch (filter) {
176     case CompilerFilter::kAssumeVerified: return "assume-verified";
177     case CompilerFilter::kExtract: return "extract";
178     case CompilerFilter::kVerify: return "verify";
179     case CompilerFilter::kQuicken: return "quicken";
180     case CompilerFilter::kSpaceProfile: return "space-profile";
181     case CompilerFilter::kSpace: return "space";
182     case CompilerFilter::kSpeedProfile: return "speed-profile";
183     case CompilerFilter::kSpeed: return "speed";
184     case CompilerFilter::kEverythingProfile: return "everything-profile";
185     case CompilerFilter::kEverything: return "everything";
186   }
187   UNREACHABLE();
188 }
189 
ParseCompilerFilter(const char * option,Filter * filter)190 bool CompilerFilter::ParseCompilerFilter(const char* option, Filter* filter) {
191   CHECK(filter != nullptr);
192 
193   if (strcmp(option, "verify-none") == 0) {
194     LOG(WARNING) << "'verify-none' is an obsolete compiler filter name that will be "
195                  << "removed in future releases, please use 'assume-verified' instead.";
196     *filter = kAssumeVerified;
197   } else if (strcmp(option, "interpret-only") == 0) {
198     LOG(WARNING) << "'interpret-only' is an obsolete compiler filter name that will be "
199                  << "removed in future releases, please use 'quicken' instead.";
200     *filter = kQuicken;
201   } else if (strcmp(option, "verify-profile") == 0) {
202     LOG(WARNING) << "'verify-profile' is an obsolete compiler filter name that will be "
203                  << "removed in future releases, please use 'verify' instead.";
204     *filter = kVerify;
205   } else if (strcmp(option, "verify-at-runtime") == 0) {
206     LOG(WARNING) << "'verify-at-runtime' is an obsolete compiler filter name that will be "
207                  << "removed in future releases, please use 'extract' instead.";
208     *filter = kExtract;
209   } else if (strcmp(option, "balanced") == 0) {
210     LOG(WARNING) << "'balanced' is an obsolete compiler filter name that will be "
211                  << "removed in future releases, please use 'speed' instead.";
212     *filter = kSpeed;
213   } else if (strcmp(option, "time") == 0) {
214     LOG(WARNING) << "'time' is an obsolete compiler filter name that will be "
215                  << "removed in future releases, please use 'space' instead.";
216     *filter = kSpace;
217   } else if (strcmp(option, "assume-verified") == 0) {
218     *filter = kAssumeVerified;
219   } else if (strcmp(option, "extract") == 0) {
220     *filter = kExtract;
221   } else if (strcmp(option, "verify") == 0) {
222     *filter = kVerify;
223   } else if (strcmp(option, "quicken") == 0) {
224     *filter = kQuicken;
225   } else if (strcmp(option, "space") == 0) {
226     *filter = kSpace;
227   } else if (strcmp(option, "space-profile") == 0) {
228     *filter = kSpaceProfile;
229   } else if (strcmp(option, "speed") == 0) {
230     *filter = kSpeed;
231   } else if (strcmp(option, "speed-profile") == 0) {
232     *filter = kSpeedProfile;
233   } else if (strcmp(option, "everything") == 0) {
234     *filter = kEverything;
235   } else if (strcmp(option, "everything-profile") == 0) {
236     *filter = kEverythingProfile;
237   } else {
238     return false;
239   }
240   return true;
241 }
242 
operator <<(std::ostream & os,const CompilerFilter::Filter & rhs)243 std::ostream& operator<<(std::ostream& os, const CompilerFilter::Filter& rhs) {
244   return os << CompilerFilter::NameOfFilter(rhs);
245 }
246 
247 }  // namespace art
248