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