diff options
| -rw-r--r-- | compiler/driver/compiler_driver-inl.h | 30 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 14 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.h | 7 | ||||
| -rw-r--r-- | compiler/driver/compiler_options.h | 17 | ||||
| -rw-r--r-- | dex2oat/dex2oat.cc | 6 |
5 files changed, 57 insertions, 17 deletions
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index 4d5d253b4a..332556853c 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -243,8 +243,14 @@ inline int CompilerDriver::IsFastInvoke( CHECK(referrer_class->GetDexCache()->GetResolvedMethod(target_method->dex_method_index) == resolved_method) << PrettyMethod(resolved_method); int stats_flags = kFlagMethodResolved; - GetCodeAndMethodForDirectCall(invoke_type, kDirect, false, referrer_class, resolved_method, - &stats_flags, target_method, direct_code, direct_method); + GetCodeAndMethodForDirectCall(/*out*/invoke_type, + kDirect, // Sharp type + false, // The dex cache is guaranteed to be available + referrer_class, resolved_method, + /*out*/&stats_flags, + target_method, + /*out*/direct_code, + /*out*/direct_method); DCHECK_NE(*invoke_type, kSuper) << PrettyMethod(resolved_method); if (*invoke_type == kDirect) { stats_flags |= kFlagsMethodResolvedVirtualMadeDirect; @@ -273,8 +279,14 @@ inline int CompilerDriver::IsFastInvoke( CHECK(called_method != NULL); CHECK(!called_method->IsAbstract()); int stats_flags = kFlagMethodResolved; - GetCodeAndMethodForDirectCall(invoke_type, kDirect, true, referrer_class, called_method, - &stats_flags, target_method, direct_code, direct_method); + GetCodeAndMethodForDirectCall(/*out*/invoke_type, + kDirect, // Sharp type + true, // The dex cache may not be available + referrer_class, called_method, + /*out*/&stats_flags, + target_method, + /*out*/direct_code, + /*out*/direct_method); DCHECK_NE(*invoke_type, kSuper); if (*invoke_type == kDirect) { stats_flags |= kFlagsMethodResolvedPreciseTypeDevirtualization; @@ -289,8 +301,14 @@ inline int CompilerDriver::IsFastInvoke( // Sharpening failed so generate a regular resolved method dispatch. int stats_flags = kFlagMethodResolved; - GetCodeAndMethodForDirectCall(invoke_type, *invoke_type, false, referrer_class, resolved_method, - &stats_flags, target_method, direct_code, direct_method); + GetCodeAndMethodForDirectCall(/*out*/invoke_type, + *invoke_type, // Sharp type + false, // The dex cache is guaranteed to be available + referrer_class, resolved_method, + /*out*/&stats_flags, + target_method, + /*out*/direct_code, + /*out*/direct_method); return stats_flags; } diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index fb648fc532..e604c219a3 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -920,6 +920,10 @@ bool CompilerDriver::CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_i if (resolved_class == nullptr) { return false; } + if (GetCompilerOptions().GetCompilePic()) { + // Do not allow a direct class pointer to be used when compiling for position-independent + return false; + } *out_is_finalizable = resolved_class->IsFinalizable(); const bool compiling_boot = Runtime::Current()->GetHeap()->IsCompilingBoot(); const bool support_boot_image_fixup = GetSupportBootImageFixup(); @@ -1112,7 +1116,7 @@ bool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompila void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type, bool no_guarantee_of_dex_cache_entry, - mirror::Class* referrer_class, + const mirror::Class* referrer_class, mirror::ArtMethod* method, int* stats_flags, MethodReference* target_method, @@ -1124,7 +1128,7 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType // invoked, so this can be passed to the out-of-line runtime support code. *direct_code = 0; *direct_method = 0; - bool use_dex_cache = false; + bool use_dex_cache = GetCompilerOptions().GetCompilePic(); // Off by default const bool compiling_boot = Runtime::Current()->GetHeap()->IsCompilingBoot(); // TODO This is somewhat hacky. We should refactor all of this invoke codepath. const bool force_relocations = (compiling_boot || @@ -1139,7 +1143,7 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType return; } // TODO: support patching on all architectures. - use_dex_cache = force_relocations && !support_boot_image_fixup_; + use_dex_cache = use_dex_cache || (force_relocations && !support_boot_image_fixup_); } bool method_code_in_boot = (method->GetDeclaringClass()->GetClassLoader() == nullptr); if (!use_dex_cache) { @@ -2002,6 +2006,10 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t ++non_relative_linker_patch_count; } } + bool compile_pic = GetCompilerOptions().GetCompilePic(); // Off by default + // When compiling with PIC, there should be zero non-relative linker patches + CHECK(!compile_pic || non_relative_linker_patch_count == 0u); + MethodReference ref(&dex_file, method_idx); DCHECK(GetCompiledMethod(ref) == nullptr) << PrettyMethod(method_idx, dex_file); { diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index c445683500..c41f7f2e44 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -400,11 +400,12 @@ class CompilerDriver { public: // TODO make private or eliminate. // Compute constant code and method pointers when possible. - void GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type, + void GetCodeAndMethodForDirectCall(/*out*/InvokeType* type, + InvokeType sharp_type, bool no_guarantee_of_dex_cache_entry, - mirror::Class* referrer_class, + const mirror::Class* referrer_class, mirror::ArtMethod* method, - int* stats_flags, + /*out*/int* stats_flags, MethodReference* target_method, uintptr_t* direct_code, uintptr_t* direct_method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index eb3de975d2..3a50bfdb83 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -28,7 +28,7 @@ class CompilerOptions { kBalanced, // Try to get the best performance return on compilation investment. kSpeed, // Maximize runtime performance. kEverything, // Force compilation (Note: excludes compilation of class initializers). - kTime // Compile methods, but minimize compilation time. + kTime, // Compile methods, but minimize compilation time. }; // Guide heuristics to determine whether to compile method if profile data not available. @@ -59,7 +59,8 @@ class CompilerOptions { include_debug_symbols_(kDefaultIncludeDebugSymbols), implicit_null_checks_(false), implicit_so_checks_(false), - implicit_suspend_checks_(false) + implicit_suspend_checks_(false), + compile_pic_(false) #ifdef ART_SEA_IR_MODE , sea_ir_mode_(false) #endif @@ -77,7 +78,8 @@ class CompilerOptions { bool include_debug_symbols, bool implicit_null_checks, bool implicit_so_checks, - bool implicit_suspend_checks + bool implicit_suspend_checks, + bool compile_pic #ifdef ART_SEA_IR_MODE , bool sea_ir_mode #endif @@ -94,7 +96,8 @@ class CompilerOptions { include_debug_symbols_(include_debug_symbols), implicit_null_checks_(implicit_null_checks), implicit_so_checks_(implicit_so_checks), - implicit_suspend_checks_(implicit_suspend_checks) + implicit_suspend_checks_(implicit_suspend_checks), + compile_pic_(compile_pic) #ifdef ART_SEA_IR_MODE , sea_ir_mode_(sea_ir_mode) #endif @@ -197,6 +200,11 @@ class CompilerOptions { return include_patch_information_; } + // Should the code be compiled as position independent? + bool GetCompilePic() const { + return compile_pic_; + } + private: CompilerFilter compiler_filter_; size_t huge_method_threshold_; @@ -212,6 +220,7 @@ class CompilerOptions { bool implicit_null_checks_; bool implicit_so_checks_; bool implicit_suspend_checks_; + bool compile_pic_; #ifdef ART_SEA_IR_MODE bool sea_ir_mode_; #endif diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 7be4349067..7f62bad4b2 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -848,6 +848,7 @@ static int dex2oat(int argc, char** argv) { ? Compiler::kPortable : Compiler::kQuick; const char* compiler_filter_string = nullptr; + bool compile_pic = false; int huge_method_threshold = CompilerOptions::kDefaultHugeMethodThreshold; int large_method_threshold = CompilerOptions::kDefaultLargeMethodThreshold; int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold; @@ -975,6 +976,8 @@ static int dex2oat(int argc, char** argv) { } } else if (option.starts_with("--compiler-filter=")) { compiler_filter_string = option.substr(strlen("--compiler-filter=")).data(); + } else if (option == "--compile-pic") { + compile_pic = true; } else if (option.starts_with("--huge-method-max=")) { const char* threshold = option.substr(strlen("--huge-method-max=")).data(); if (!ParseInt(threshold, &huge_method_threshold)) { @@ -1225,7 +1228,8 @@ static int dex2oat(int argc, char** argv) { include_debug_symbols, implicit_null_checks, implicit_so_checks, - implicit_suspend_checks + implicit_suspend_checks, + compile_pic #ifdef ART_SEA_IR_MODE , compiler_options.sea_ir_ = true; |