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