1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
|
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
#define ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
#include <memory>
#include <ostream>
#include <string>
#include <vector>
#include "base/globals.h"
#include "base/hash_set.h"
#include "base/macros.h"
#include "base/utils.h"
#include "compiler_filter.h"
#include "optimizing/register_allocator.h"
namespace art {
namespace jit {
class JitCompiler;
} // namespace jit
namespace verifier {
class VerifierDepsTest;
} // namespace verifier
namespace linker {
class Arm64RelativePatcherTest;
} // namespace linker
class DexFile;
enum class InstructionSet;
class InstructionSetFeatures;
class ProfileCompilationInfo;
class VerificationResults;
class VerifiedMethod;
// Enum for CheckProfileMethodsCompiled. Outside CompilerOptions so it can be forward-declared.
enum class ProfileMethodsCheck : uint8_t {
kNone,
kLog,
kAbort,
};
class CompilerOptions final {
public:
// Guide heuristics to determine whether to compile method if profile data not available.
static const size_t kDefaultHugeMethodThreshold = 10000;
static const size_t kDefaultLargeMethodThreshold = 600;
static const size_t kDefaultNumDexMethodsThreshold = 900;
static constexpr double kDefaultTopKProfileThreshold = 90.0;
static const bool kDefaultGenerateDebugInfo = false;
static const bool kDefaultGenerateMiniDebugInfo = false;
static const size_t kDefaultInlineMaxCodeUnits = 32;
static constexpr size_t kUnsetInlineMaxCodeUnits = -1;
enum class ImageType : uint8_t {
kNone, // JIT or AOT app compilation producing only an oat file but no image.
kBootImage, // Creating boot image.
kBootImageExtension, // Creating boot image extension.
kAppImage, // Creating app image.
};
CompilerOptions();
~CompilerOptions();
CompilerFilter::Filter GetCompilerFilter() const {
return compiler_filter_;
}
void SetCompilerFilter(CompilerFilter::Filter compiler_filter) {
compiler_filter_ = compiler_filter;
}
bool IsAotCompilationEnabled() const {
return CompilerFilter::IsAotCompilationEnabled(compiler_filter_);
}
bool IsJniCompilationEnabled() const {
return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
}
bool IsQuickeningCompilationEnabled() const {
return CompilerFilter::IsQuickeningCompilationEnabled(compiler_filter_);
}
bool IsVerificationEnabled() const {
return CompilerFilter::IsVerificationEnabled(compiler_filter_);
}
bool AssumeDexFilesAreVerified() const {
return compiler_filter_ == CompilerFilter::kAssumeVerified;
}
bool AssumeClassesAreVerified() const {
return compiler_filter_ == CompilerFilter::kAssumeVerified;
}
bool VerifyAtRuntime() const {
return compiler_filter_ == CompilerFilter::kExtract;
}
bool IsAnyCompilationEnabled() const {
return CompilerFilter::IsAnyCompilationEnabled(compiler_filter_);
}
size_t GetHugeMethodThreshold() const {
return huge_method_threshold_;
}
size_t GetLargeMethodThreshold() const {
return large_method_threshold_;
}
bool IsHugeMethod(size_t num_dalvik_instructions) const {
return num_dalvik_instructions > huge_method_threshold_;
}
bool IsLargeMethod(size_t num_dalvik_instructions) const {
return num_dalvik_instructions > large_method_threshold_;
}
size_t GetNumDexMethodsThreshold() const {
return num_dex_methods_threshold_;
}
size_t GetInlineMaxCodeUnits() const {
return inline_max_code_units_;
}
void SetInlineMaxCodeUnits(size_t units) {
inline_max_code_units_ = units;
}
double GetTopKProfileThreshold() const {
return top_k_profile_threshold_;
}
bool GetDebuggable() const {
return debuggable_;
}
void SetDebuggable(bool value) {
debuggable_ = value;
}
bool GetNativeDebuggable() const {
return GetDebuggable() && GetGenerateDebugInfo();
}
// This flag controls whether the compiler collects debugging information.
// The other flags control how the information is written to disk.
bool GenerateAnyDebugInfo() const {
return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo();
}
bool GetGenerateDebugInfo() const {
return generate_debug_info_;
}
bool GetGenerateMiniDebugInfo() const {
return generate_mini_debug_info_;
}
// Should run-time checks be emitted in debug mode?
bool EmitRunTimeChecksInDebugMode() const;
bool GetGenerateBuildId() const {
return generate_build_id_;
}
bool GetImplicitNullChecks() const {
return implicit_null_checks_;
}
bool GetImplicitStackOverflowChecks() const {
return implicit_so_checks_;
}
bool GetImplicitSuspendChecks() const {
return implicit_suspend_checks_;
}
bool IsGeneratingImage() const {
return IsBootImage() || IsBootImageExtension() || IsAppImage();
}
// Are we compiling a boot image?
bool IsBootImage() const {
return image_type_ == ImageType::kBootImage;
}
// Are we compiling a boot image extension?
bool IsBootImageExtension() const {
return image_type_ == ImageType::kBootImageExtension;
}
bool IsBaseline() const {
return baseline_;
}
// Are we compiling an app image?
bool IsAppImage() const {
return image_type_ == ImageType::kAppImage;
}
// Returns whether we are compiling against a "core" image, which
// is an indicative we are running tests. The compiler will use that
// information for checking invariants.
bool CompilingWithCoreImage() const {
return compiling_with_core_image_;
}
// Should the code be compiled as position independent?
bool GetCompilePic() const {
return compile_pic_;
}
const ProfileCompilationInfo* GetProfileCompilationInfo() const {
return profile_compilation_info_;
}
bool HasVerboseMethods() const {
return !verbose_methods_.empty();
}
bool IsVerboseMethod(const std::string& pretty_method) const {
for (const std::string& cur_method : verbose_methods_) {
if (pretty_method.find(cur_method) != std::string::npos) {
return true;
}
}
return false;
}
std::ostream* GetInitFailureOutput() const {
return init_failure_output_.get();
}
bool AbortOnHardVerifierFailure() const {
return abort_on_hard_verifier_failure_;
}
bool AbortOnSoftVerifierFailure() const {
return abort_on_soft_verifier_failure_;
}
InstructionSet GetInstructionSet() const {
return instruction_set_;
}
const InstructionSetFeatures* GetInstructionSetFeatures() const {
return instruction_set_features_.get();
}
const std::vector<const DexFile*>& GetNoInlineFromDexFile() const {
return no_inline_from_;
}
const std::vector<const DexFile*>& GetDexFilesForOatFile() const {
return dex_files_for_oat_file_;
}
const HashSet<std::string>& GetImageClasses() const {
return image_classes_;
}
bool IsImageClass(const char* descriptor) const;
const VerificationResults* GetVerificationResults() const;
const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const;
// Checks if the specified method has been verified without failures. Returns
// false if the method is not in the verification results (GetVerificationResults).
bool IsMethodVerifiedWithoutFailures(uint32_t method_idx,
uint16_t class_def_idx,
const DexFile& dex_file) const;
bool ParseCompilerOptions(const std::vector<std::string>& options,
bool ignore_unrecognized,
std::string* error_msg);
void SetNonPic() {
compile_pic_ = false;
}
const std::string& GetDumpCfgFileName() const {
return dump_cfg_file_name_;
}
bool GetDumpCfgAppend() const {
return dump_cfg_append_;
}
bool IsForceDeterminism() const {
return force_determinism_;
}
bool DeduplicateCode() const {
return deduplicate_code_;
}
RegisterAllocator::Strategy GetRegisterAllocationStrategy() const {
return register_allocation_strategy_;
}
const std::vector<std::string>* GetPassesToRun() const {
return passes_to_run_;
}
bool GetDumpTimings() const {
return dump_timings_;
}
bool GetDumpPassTimings() const {
return dump_pass_timings_;
}
bool GetDumpStats() const {
return dump_stats_;
}
bool CountHotnessInCompiledCode() const {
return count_hotness_in_compiled_code_;
}
bool ResolveStartupConstStrings() const {
return resolve_startup_const_strings_;
}
ProfileMethodsCheck CheckProfiledMethodsCompiled() const {
return check_profiled_methods_;
}
uint32_t MaxImageBlockSize() const {
return max_image_block_size_;
}
void SetMaxImageBlockSize(uint32_t size) {
max_image_block_size_ = size;
}
bool InitializeAppImageClasses() const {
return initialize_app_image_classes_;
}
// Is `boot_image_filename` the name of a core image (small boot
// image used for ART testing only)?
static bool IsCoreImageFilename(const std::string& boot_image_filename);
private:
bool ParseDumpInitFailures(const std::string& option, std::string* error_msg);
bool ParseRegisterAllocationStrategy(const std::string& option, std::string* error_msg);
CompilerFilter::Filter compiler_filter_;
size_t huge_method_threshold_;
size_t large_method_threshold_;
size_t num_dex_methods_threshold_;
size_t inline_max_code_units_;
InstructionSet instruction_set_;
std::unique_ptr<const InstructionSetFeatures> instruction_set_features_;
// Dex files from which we should not inline code. Does not own the dex files.
// This is usually a very short list (i.e. a single dex file), so we
// prefer vector<> over a lookup-oriented container, such as set<>.
std::vector<const DexFile*> no_inline_from_;
// List of dex files associated with the oat file, empty for JIT.
std::vector<const DexFile*> dex_files_for_oat_file_;
// Image classes, specifies the classes that will be included in the image if creating an image.
// Must not be empty for real boot image, only for tests pretending to compile boot image.
HashSet<std::string> image_classes_;
// Results of AOT verification.
const VerificationResults* verification_results_;
ImageType image_type_;
bool compiling_with_core_image_;
bool baseline_;
bool debuggable_;
bool generate_debug_info_;
bool generate_mini_debug_info_;
bool generate_build_id_;
bool implicit_null_checks_;
bool implicit_so_checks_;
bool implicit_suspend_checks_;
bool compile_pic_;
bool dump_timings_;
bool dump_pass_timings_;
bool dump_stats_;
// When using a profile file only the top K% of the profiled samples will be compiled.
double top_k_profile_threshold_;
// Info for profile guided compilation.
const ProfileCompilationInfo* profile_compilation_info_;
// Vector of methods to have verbose output enabled for.
std::vector<std::string> verbose_methods_;
// Abort compilation with an error if we find a class that fails verification with a hard
// failure.
bool abort_on_hard_verifier_failure_;
// Same for soft failures.
bool abort_on_soft_verifier_failure_;
// Log initialization of initialization failures to this stream if not null.
std::unique_ptr<std::ostream> init_failure_output_;
std::string dump_cfg_file_name_;
bool dump_cfg_append_;
// Whether the compiler should trade performance for determinism to guarantee exactly reproducible
// outcomes.
bool force_determinism_;
// Whether code should be deduplicated.
bool deduplicate_code_;
// Whether compiled code should increment the hotness count of ArtMethod. Note that the increments
// won't be atomic for performance reasons, so we accept races, just like in interpreter.
bool count_hotness_in_compiled_code_;
// Whether we eagerly resolve all of the const strings that are loaded from startup methods in the
// profile.
bool resolve_startup_const_strings_;
// Whether we attempt to run class initializers for app image classes.
bool initialize_app_image_classes_;
// When running profile-guided compilation, check that methods intended to be compiled end
// up compiled and are not punted.
ProfileMethodsCheck check_profiled_methods_;
// Maximum solid block size in the generated image.
uint32_t max_image_block_size_;
RegisterAllocator::Strategy register_allocation_strategy_;
// If not null, specifies optimization passes which will be run instead of defaults.
// Note that passes_to_run_ is not checked for correctness and providing an incorrect
// list of passes can lead to unexpected compiler behaviour. This is caused by dependencies
// between passes. Failing to satisfy them can for example lead to compiler crashes.
// Passing pass names which are not recognized by the compiler will result in
// compiler-dependant behavior.
const std::vector<std::string>* passes_to_run_;
friend class Dex2Oat;
friend class DexToDexDecompilerTest;
friend class CommonCompilerDriverTest;
friend class CommonCompilerTest;
friend class jit::JitCompiler;
friend class verifier::VerifierDepsTest;
friend class linker::Arm64RelativePatcherTest;
template <class Base>
friend bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string* error_msg);
DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
};
} // namespace art
#endif // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
|