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 "utils.h"
20 
21 namespace art {
22 
IsAotCompilationEnabled(Filter filter)23 bool CompilerFilter::IsAotCompilationEnabled(Filter filter) {
24   switch (filter) {
25     case CompilerFilter::kAssumeVerified:
26     case CompilerFilter::kExtract:
27     case CompilerFilter::kVerify:
28     case CompilerFilter::kQuicken: return false;
29 
30     case CompilerFilter::kSpaceProfile:
31     case CompilerFilter::kSpace:
32     case CompilerFilter::kSpeedProfile:
33     case CompilerFilter::kSpeed:
34     case CompilerFilter::kEverythingProfile:
35     case CompilerFilter::kEverything: return true;
36   }
37   UNREACHABLE();
38 }
39 
IsJniCompilationEnabled(Filter filter)40 bool CompilerFilter::IsJniCompilationEnabled(Filter filter) {
41   switch (filter) {
42     case CompilerFilter::kAssumeVerified:
43     case CompilerFilter::kExtract:
44     case CompilerFilter::kVerify: return false;
45 
46     case CompilerFilter::kQuicken:
47     case CompilerFilter::kSpaceProfile:
48     case CompilerFilter::kSpace:
49     case CompilerFilter::kSpeedProfile:
50     case CompilerFilter::kSpeed:
51     case CompilerFilter::kEverythingProfile:
52     case CompilerFilter::kEverything: return true;
53   }
54   UNREACHABLE();
55 }
56 
IsQuickeningCompilationEnabled(Filter filter)57 bool CompilerFilter::IsQuickeningCompilationEnabled(Filter filter) {
58   switch (filter) {
59     case CompilerFilter::kAssumeVerified:
60     case CompilerFilter::kExtract:
61     case CompilerFilter::kVerify: return false;
62 
63     case CompilerFilter::kQuicken:
64     case CompilerFilter::kSpaceProfile:
65     case CompilerFilter::kSpace:
66     case CompilerFilter::kSpeedProfile:
67     case CompilerFilter::kSpeed:
68     case CompilerFilter::kEverythingProfile:
69     case CompilerFilter::kEverything: return true;
70   }
71   UNREACHABLE();
72 }
73 
IsAnyCompilationEnabled(Filter filter)74 bool CompilerFilter::IsAnyCompilationEnabled(Filter filter) {
75   return IsJniCompilationEnabled(filter) ||
76       IsQuickeningCompilationEnabled(filter) ||
77       IsAotCompilationEnabled(filter);
78 }
79 
IsVerificationEnabled(Filter filter)80 bool CompilerFilter::IsVerificationEnabled(Filter filter) {
81   switch (filter) {
82     case CompilerFilter::kAssumeVerified:
83     case CompilerFilter::kExtract: return false;
84 
85     case CompilerFilter::kVerify:
86     case CompilerFilter::kQuicken:
87     case CompilerFilter::kSpaceProfile:
88     case CompilerFilter::kSpace:
89     case CompilerFilter::kSpeedProfile:
90     case CompilerFilter::kSpeed:
91     case CompilerFilter::kEverythingProfile:
92     case CompilerFilter::kEverything: return true;
93   }
94   UNREACHABLE();
95 }
96 
DependsOnImageChecksum(Filter filter)97 bool CompilerFilter::DependsOnImageChecksum(Filter filter) {
98   // We run dex2dex with verification, so the oat file will depend on the
99   // image checksum if verification is enabled.
100   return IsVerificationEnabled(filter);
101 }
102 
DependsOnProfile(Filter filter)103 bool CompilerFilter::DependsOnProfile(Filter filter) {
104   switch (filter) {
105     case CompilerFilter::kAssumeVerified:
106     case CompilerFilter::kExtract:
107     case CompilerFilter::kVerify:
108     case CompilerFilter::kQuicken:
109     case CompilerFilter::kSpace:
110     case CompilerFilter::kSpeed:
111     case CompilerFilter::kEverything: return false;
112 
113     case CompilerFilter::kSpaceProfile:
114     case CompilerFilter::kSpeedProfile:
115     case CompilerFilter::kEverythingProfile: return true;
116   }
117   UNREACHABLE();
118 }
119 
GetNonProfileDependentFilterFrom(Filter filter)120 CompilerFilter::Filter CompilerFilter::GetNonProfileDependentFilterFrom(Filter filter) {
121   switch (filter) {
122     case CompilerFilter::kAssumeVerified:
123     case CompilerFilter::kExtract:
124     case CompilerFilter::kVerify:
125     case CompilerFilter::kQuicken:
126     case CompilerFilter::kSpace:
127     case CompilerFilter::kSpeed:
128     case CompilerFilter::kEverything:
129       return filter;
130 
131     case CompilerFilter::kSpaceProfile:
132       return CompilerFilter::kSpace;
133 
134     case CompilerFilter::kSpeedProfile:
135       return CompilerFilter::kSpeed;
136 
137     case CompilerFilter::kEverythingProfile:
138       return CompilerFilter::kEverything;
139   }
140   UNREACHABLE();
141 }
142 
GetSafeModeFilterFrom(Filter filter)143 CompilerFilter::Filter CompilerFilter::GetSafeModeFilterFrom(Filter filter) {
144   // For safe mode, we should not return a filter that generates AOT compiled
145   // code.
146   switch (filter) {
147     case CompilerFilter::kAssumeVerified:
148     case CompilerFilter::kExtract:
149     case CompilerFilter::kVerify:
150     case CompilerFilter::kQuicken:
151       return filter;
152 
153     case CompilerFilter::kSpace:
154     case CompilerFilter::kSpeed:
155     case CompilerFilter::kEverything:
156     case CompilerFilter::kSpaceProfile:
157     case CompilerFilter::kSpeedProfile:
158     case CompilerFilter::kEverythingProfile:
159       return CompilerFilter::kQuicken;
160   }
161   UNREACHABLE();
162 }
163 
IsAsGoodAs(Filter current,Filter target)164 bool CompilerFilter::IsAsGoodAs(Filter current, Filter target) {
165   return current >= target;
166 }
167 
NameOfFilter(Filter filter)168 std::string CompilerFilter::NameOfFilter(Filter filter) {
169   switch (filter) {
170     case CompilerFilter::kAssumeVerified: return "assume-verified";
171     case CompilerFilter::kExtract: return "extract";
172     case CompilerFilter::kVerify: return "verify";
173     case CompilerFilter::kQuicken: return "quicken";
174     case CompilerFilter::kSpaceProfile: return "space-profile";
175     case CompilerFilter::kSpace: return "space";
176     case CompilerFilter::kSpeedProfile: return "speed-profile";
177     case CompilerFilter::kSpeed: return "speed";
178     case CompilerFilter::kEverythingProfile: return "everything-profile";
179     case CompilerFilter::kEverything: return "everything";
180   }
181   UNREACHABLE();
182 }
183 
ParseCompilerFilter(const char * option,Filter * filter)184 bool CompilerFilter::ParseCompilerFilter(const char* option, Filter* filter) {
185   CHECK(filter != nullptr);
186 
187   if (strcmp(option, "verify-none") == 0) {
188     LOG(WARNING) << "'verify-none' is an obsolete compiler filter name that will be "
189                  << "removed in future releases, please use 'assume-verified' instead.";
190     *filter = kAssumeVerified;
191   } else if (strcmp(option, "interpret-only") == 0) {
192     LOG(WARNING) << "'interpret-only' is an obsolete compiler filter name that will be "
193                  << "removed in future releases, please use 'quicken' instead.";
194     *filter = kQuicken;
195   } else if (strcmp(option, "verify-profile") == 0) {
196     LOG(WARNING) << "'verify-profile' is an obsolete compiler filter name that will be "
197                  << "removed in future releases, please use 'verify' instead.";
198     *filter = kVerify;
199   } else if (strcmp(option, "verify-at-runtime") == 0) {
200     LOG(WARNING) << "'verify-at-runtime' is an obsolete compiler filter name that will be "
201                  << "removed in future releases, please use 'extract' instead.";
202     *filter = kExtract;
203   } else if (strcmp(option, "balanced") == 0) {
204     LOG(WARNING) << "'balanced' is an obsolete compiler filter name that will be "
205                  << "removed in future releases, please use 'speed' instead.";
206     *filter = kSpeed;
207   } else if (strcmp(option, "time") == 0) {
208     LOG(WARNING) << "'time' is an obsolete compiler filter name that will be "
209                  << "removed in future releases, please use 'space' instead.";
210     *filter = kSpace;
211   } else if (strcmp(option, "assume-verified") == 0) {
212     *filter = kAssumeVerified;
213   } else if (strcmp(option, "extract") == 0) {
214     *filter = kExtract;
215   } else if (strcmp(option, "verify") == 0) {
216     *filter = kVerify;
217   } else if (strcmp(option, "quicken") == 0) {
218     *filter = kQuicken;
219   } else if (strcmp(option, "space") == 0) {
220     *filter = kSpace;
221   } else if (strcmp(option, "space-profile") == 0) {
222     *filter = kSpaceProfile;
223   } else if (strcmp(option, "speed") == 0) {
224     *filter = kSpeed;
225   } else if (strcmp(option, "speed-profile") == 0) {
226     *filter = kSpeedProfile;
227   } else if (strcmp(option, "everything") == 0) {
228     *filter = kEverything;
229   } else if (strcmp(option, "everything-profile") == 0) {
230     *filter = kEverythingProfile;
231   } else {
232     return false;
233   }
234   return true;
235 }
236 
operator <<(std::ostream & os,const CompilerFilter::Filter & rhs)237 std::ostream& operator<<(std::ostream& os, const CompilerFilter::Filter& rhs) {
238   return os << CompilerFilter::NameOfFilter(rhs);
239 }
240 
241 }  // namespace art
242