diff options
| -rw-r--r-- | compiler/dex/quick/arm/call_arm.cc | 8 | ||||
| -rw-r--r-- | compiler/dex/quick/arm64/call_arm64.cc | 8 | ||||
| -rw-r--r-- | compiler/dex/quick/arm64/target_arm64.cc | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/gen_common.cc | 12 | ||||
| -rw-r--r-- | compiler/dex/quick/gen_invoke.cc | 4 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/target_x86.cc | 2 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.h | 42 | ||||
| -rw-r--r-- | dex2oat/dex2oat.cc | 63 |
8 files changed, 119 insertions, 22 deletions
diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc index 5466abd11d..dae6a4f715 100644 --- a/compiler/dex/quick/arm/call_arm.cc +++ b/compiler/dex/quick/arm/call_arm.cc @@ -190,7 +190,7 @@ void ArmMir2Lir::GenMonitorEnter(int opt_flags, RegLocation rl_src) { null_check_branch = nullptr; // No null check. } else { // If the null-check fails its handled by the slow-path to reduce exception related meta-data. - if (Runtime::Current()->ExplicitNullChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { null_check_branch = OpCmpImmBranch(kCondEq, rs_r0, 0, NULL); } } @@ -261,7 +261,7 @@ void ArmMir2Lir::GenMonitorExit(int opt_flags, RegLocation rl_src) { null_check_branch = nullptr; // No null check. } else { // If the null-check fails its handled by the slow-path to reduce exception related meta-data. - if (Runtime::Current()->ExplicitNullChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { null_check_branch = OpCmpImmBranch(kCondEq, rs_r0, 0, NULL); } } @@ -362,7 +362,7 @@ void ArmMir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method) { NewLIR0(kPseudoMethodEntry); bool large_frame = (static_cast<size_t>(frame_size_) > Thread::kStackOverflowReservedUsableBytes); if (!skip_overflow_check) { - if (Runtime::Current()->ExplicitStackOverflowChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitStackOverflowChecks()) { if (!large_frame) { /* Load stack limit */ LockTemp(rs_r12); @@ -401,7 +401,7 @@ void ArmMir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method) { const int spill_size = spill_count * 4; const int frame_size_without_spills = frame_size_ - spill_size; if (!skip_overflow_check) { - if (Runtime::Current()->ExplicitStackOverflowChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitStackOverflowChecks()) { class StackOverflowSlowPath : public LIRSlowPath { public: StackOverflowSlowPath(Mir2Lir* m2l, LIR* branch, bool restore_lr, size_t sp_displace) diff --git a/compiler/dex/quick/arm64/call_arm64.cc b/compiler/dex/quick/arm64/call_arm64.cc index f1748effb2..ddfec2d80f 100644 --- a/compiler/dex/quick/arm64/call_arm64.cc +++ b/compiler/dex/quick/arm64/call_arm64.cc @@ -213,7 +213,7 @@ void Arm64Mir2Lir::GenMonitorEnter(int opt_flags, RegLocation rl_src) { null_check_branch = nullptr; // No null check. } else { // If the null-check fails its handled by the slow-path to reduce exception related meta-data. - if (Runtime::Current()->ExplicitNullChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { null_check_branch = OpCmpImmBranch(kCondEq, rs_x0, 0, NULL); } } @@ -261,7 +261,7 @@ void Arm64Mir2Lir::GenMonitorExit(int opt_flags, RegLocation rl_src) { null_check_branch = nullptr; // No null check. } else { // If the null-check fails its handled by the slow-path to reduce exception related meta-data. - if (Runtime::Current()->ExplicitNullChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { null_check_branch = OpCmpImmBranch(kCondEq, rs_x0, 0, NULL); } } @@ -349,7 +349,7 @@ void Arm64Mir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method) const int frame_size_without_spills = frame_size_ - spill_size; if (!skip_overflow_check) { - if (Runtime::Current()->ExplicitStackOverflowChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitStackOverflowChecks()) { if (!large_frame) { // Load stack limit LoadWordDisp(rs_rA64_SELF, Thread::StackEndOffset<8>().Int32Value(), rs_x9); @@ -382,7 +382,7 @@ void Arm64Mir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method) } if (!skip_overflow_check) { - if (Runtime::Current()->ExplicitStackOverflowChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitStackOverflowChecks()) { class StackOverflowSlowPath: public LIRSlowPath { public: StackOverflowSlowPath(Mir2Lir* m2l, LIR* branch, size_t sp_displace) : diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc index fba368aa8c..06e1cda305 100644 --- a/compiler/dex/quick/arm64/target_arm64.cc +++ b/compiler/dex/quick/arm64/target_arm64.cc @@ -1163,7 +1163,7 @@ int Arm64Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state, call_state = next_call_insn(cu_, info, call_state, target_method, vtable_idx, direct_code, direct_method, type); if (pcrLabel) { - if (Runtime::Current()->ExplicitNullChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { *pcrLabel = GenExplicitNullCheck(TargetReg(kArg1), info->opt_flags); } else { *pcrLabel = nullptr; diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index 3b99421a6a..e36b592c74 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -173,7 +173,7 @@ LIR* Mir2Lir::GenNullCheck(RegStorage reg) { /* Perform null-check on a register. */ LIR* Mir2Lir::GenNullCheck(RegStorage m_reg, int opt_flags) { - if (Runtime::Current()->ExplicitNullChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { return GenExplicitNullCheck(m_reg, opt_flags); } return nullptr; @@ -188,7 +188,7 @@ LIR* Mir2Lir::GenExplicitNullCheck(RegStorage m_reg, int opt_flags) { } void Mir2Lir::MarkPossibleNullPointerException(int opt_flags) { - if (!Runtime::Current()->ExplicitNullChecks()) { + if (!cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { if (!(cu_->disable_opt & (1 << kNullCheckElimination)) && (opt_flags & MIR_IGNORE_NULL_CHECK)) { return; } @@ -197,13 +197,13 @@ void Mir2Lir::MarkPossibleNullPointerException(int opt_flags) { } void Mir2Lir::MarkPossibleStackOverflowException() { - if (!Runtime::Current()->ExplicitStackOverflowChecks()) { + if (!cu_->compiler_driver->GetCompilerOptions().GetExplicitStackOverflowChecks()) { MarkSafepointPC(last_lir_insn_); } } void Mir2Lir::ForceImplicitNullCheck(RegStorage reg, int opt_flags) { - if (!Runtime::Current()->ExplicitNullChecks()) { + if (!cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { if (!(cu_->disable_opt & (1 << kNullCheckElimination)) && (opt_flags & MIR_IGNORE_NULL_CHECK)) { return; } @@ -2171,7 +2171,7 @@ class SuspendCheckSlowPath : public Mir2Lir::LIRSlowPath { /* Check if we need to check for pending suspend request */ void Mir2Lir::GenSuspendTest(int opt_flags) { - if (Runtime::Current()->ExplicitSuspendChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitSuspendChecks()) { if (NO_SUSPEND || (opt_flags & MIR_IGNORE_SUSPEND_CHECK)) { return; } @@ -2191,7 +2191,7 @@ void Mir2Lir::GenSuspendTest(int opt_flags) { /* Check if we need to check for pending suspend request */ void Mir2Lir::GenSuspendTestAndBranch(int opt_flags, LIR* target) { - if (Runtime::Current()->ExplicitSuspendChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitSuspendChecks()) { if (NO_SUSPEND || (opt_flags & MIR_IGNORE_SUSPEND_CHECK)) { OpUnconditionalBranch(target); return; diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index 641579f354..b3fac77c14 100644 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -977,7 +977,7 @@ int Mir2Lir::GenDalvikArgsNoRange(CallInfo* info, type, skip_this); if (pcrLabel) { - if (Runtime::Current()->ExplicitNullChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { *pcrLabel = GenExplicitNullCheck(TargetReg(kArg1), info->opt_flags); } else { *pcrLabel = nullptr; @@ -1204,7 +1204,7 @@ int Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state, call_state = next_call_insn(cu_, info, call_state, target_method, vtable_idx, direct_code, direct_method, type); if (pcrLabel) { - if (Runtime::Current()->ExplicitNullChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { *pcrLabel = GenExplicitNullCheck(TargetReg(kArg1), info->opt_flags); } else { *pcrLabel = nullptr; diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc index 483d8cf257..2948e566f6 100644 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -2177,7 +2177,7 @@ int X86Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state, call_state = next_call_insn(cu_, info, call_state, target_method, vtable_idx, direct_code, direct_method, type); if (pcrLabel) { - if (Runtime::Current()->ExplicitNullChecks()) { + if (cu_->compiler_driver->GetCompilerOptions().GetExplicitNullChecks()) { *pcrLabel = GenExplicitNullCheck(TargetReg(kArg1), info->opt_flags); } else { *pcrLabel = nullptr; diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index 5d1c5dadaf..fb3341ba71 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -53,7 +53,10 @@ class CompilerOptions { num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold), generate_gdb_information_(false), top_k_profile_threshold_(kDefaultTopKProfileThreshold), - include_debug_symbols_(kDefaultIncludeDebugSymbols) + include_debug_symbols_(kDefaultIncludeDebugSymbols), + explicit_null_checks_(true), + explicit_so_checks_(true), + explicit_suspend_checks_(true) #ifdef ART_SEA_IR_MODE , sea_ir_mode_(false) #endif @@ -67,7 +70,10 @@ class CompilerOptions { size_t num_dex_methods_threshold, bool generate_gdb_information, double top_k_profile_threshold, - bool include_debug_symbols + bool include_debug_symbols, + bool explicit_null_checks, + bool explicit_so_checks, + bool explicit_suspend_checks #ifdef ART_SEA_IR_MODE , bool sea_ir_mode #endif @@ -80,7 +86,10 @@ class CompilerOptions { num_dex_methods_threshold_(num_dex_methods_threshold), generate_gdb_information_(generate_gdb_information), top_k_profile_threshold_(top_k_profile_threshold), - include_debug_symbols_(include_debug_symbols) + include_debug_symbols_(include_debug_symbols), + explicit_null_checks_(explicit_null_checks), + explicit_so_checks_(explicit_so_checks), + explicit_suspend_checks_(explicit_suspend_checks) #ifdef ART_SEA_IR_MODE , sea_ir_mode_(sea_ir_mode) #endif @@ -147,6 +156,30 @@ class CompilerOptions { return include_debug_symbols_; } + bool GetExplicitNullChecks() const { + return explicit_null_checks_; + } + + void SetExplicitNullChecks(bool new_val) { + explicit_null_checks_ = new_val; + } + + bool GetExplicitStackOverflowChecks() const { + return explicit_so_checks_; + } + + void SetExplicitStackOverflowChecks(bool new_val) { + explicit_so_checks_ = new_val; + } + + bool GetExplicitSuspendChecks() const { + return explicit_suspend_checks_; + } + + void SetExplicitSuspendChecks(bool new_val) { + explicit_suspend_checks_ = new_val; + } + #ifdef ART_SEA_IR_MODE bool GetSeaIrMode(); #endif @@ -166,6 +199,9 @@ class CompilerOptions { // When using a profile file only the top K% of the profiled samples will be compiled. double top_k_profile_threshold_; bool include_debug_symbols_; + bool explicit_null_checks_; + bool explicit_so_checks_; + bool explicit_suspend_checks_; #ifdef ART_SEA_IR_MODE bool sea_ir_mode_; #endif diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index c3f20828cc..d7b34dc47d 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -744,6 +744,19 @@ void ParseDouble(const std::string& option, char after_char, *parsed_value = value; } +void CheckExplicitCheckOptions(InstructionSet isa, bool* explicit_null_checks, + bool* explicit_so_checks, bool* explicit_suspend_checks) { + switch (isa) { + case kArm: + break; // All checks implemented, leave as is. + + default: // No checks implemented, reset all to explicit checks. + *explicit_null_checks = true; + *explicit_so_checks = true; + *explicit_suspend_checks = true; + } +} + static int dex2oat(int argc, char** argv) { #if defined(__linux__) && defined(__arm__) int major, minor; @@ -825,6 +838,11 @@ static int dex2oat(int argc, char** argv) { bool watch_dog_enabled = !kIsTargetBuild; bool generate_gdb_information = kIsDebugBuild; + bool explicit_null_checks = true; + bool explicit_so_checks = true; + bool explicit_suspend_checks = true; + bool has_explicit_checks_options = false; + for (int i = 0; i < argc; i++) { const StringPiece option(argv[i]); const bool log_options = false; @@ -998,6 +1016,31 @@ static int dex2oat(int argc, char** argv) { } else if (option.starts_with("--dump-cfg-passes=")) { std::string dump_passes = option.substr(strlen("--dump-cfg-passes=")).data(); PassDriverMEOpts::SetDumpPassList(dump_passes); + } else if (option.starts_with("--implicit-checks=")) { + std::string checks = option.substr(strlen("--implicit-checks=")).data(); + std::vector<std::string> checkvec; + Split(checks, ',', checkvec); + for (auto& str : checkvec) { + std::string val = Trim(str); + if (val == "none") { + explicit_null_checks = true; + explicit_so_checks = true; + explicit_suspend_checks = true; + } else if (val == "null") { + explicit_null_checks = false; + } else if (val == "suspend") { + explicit_suspend_checks = false; + } else if (val == "stack") { + explicit_so_checks = false; + } else if (val == "all") { + explicit_null_checks = false; + explicit_so_checks = false; + explicit_suspend_checks = false; + } else { + Usage("--implicit-checks passed non-recognized value %s", val.c_str()); + } + has_explicit_checks_options = true; + } } else { Usage("Unknown argument %s", option.data()); } @@ -1126,6 +1169,9 @@ static int dex2oat(int argc, char** argv) { Usage("Unknown --compiler-filter value %s", compiler_filter_string); } + CheckExplicitCheckOptions(instruction_set, &explicit_null_checks, &explicit_so_checks, + &explicit_suspend_checks); + CompilerOptions compiler_options(compiler_filter, huge_method_threshold, large_method_threshold, @@ -1134,7 +1180,10 @@ static int dex2oat(int argc, char** argv) { num_dex_methods_threshold, generate_gdb_information, top_k_profile_threshold, - include_debug_symbols + include_debug_symbols, + explicit_null_checks, + explicit_so_checks, + explicit_suspend_checks #ifdef ART_SEA_IR_MODE , compiler_options.sea_ir_ = true; #endif @@ -1205,6 +1254,18 @@ static int dex2oat(int argc, char** argv) { return EXIT_FAILURE; } std::unique_ptr<Dex2Oat> dex2oat(p_dex2oat); + + // TODO: Not sure whether it's a good idea to allow anything else but the runtime option in + // this case at all, as we'll have to throw away produced code for a mismatch. + if (!has_explicit_checks_options) { + if (instruction_set == kRuntimeISA) { + Runtime* runtime = Runtime::Current(); + compiler_options.SetExplicitNullChecks(runtime->ExplicitNullChecks()); + compiler_options.SetExplicitStackOverflowChecks(runtime->ExplicitStackOverflowChecks()); + compiler_options.SetExplicitSuspendChecks(runtime->ExplicitSuspendChecks()); + } + } + // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start, // give it away now so that we don't starve GC. Thread* self = Thread::Current(); |