dex2oat: Add a --compile-pic option
(cherry-picked from AOSP master
83c5612e69fa05610baf4f4d237fe0995a79cde5)
Bug: 18035729
(cherry picked from commit 643b5df2b065ccf5bb19a183573da691e9d0311f)
Change-Id: I14edee7c7cb996bc388d89b4c5274db2caf91004
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 022ec6b..d278884 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -242,8 +242,14 @@
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;
@@ -272,8 +278,14 @@
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;
@@ -288,8 +300,14 @@
// 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 fa2a560..9a44ade 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -934,6 +934,10 @@
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();
@@ -1089,7 +1093,7 @@
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,
@@ -1101,7 +1105,7 @@
// 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 ||
@@ -1116,7 +1120,7 @@
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) {
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index a165901..598e196 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -633,11 +633,12 @@
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 c0f91d16..03b9371 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -27,7 +27,7 @@
kSpace, // Maximize space savings.
kBalanced, // Try to get the best performance return on compilation investment.
kSpeed, // Maximize runtime performance.
- kEverything // Force compilation (Note: excludes compilaton of class initializers).
+ kEverything, // Force compilation (Note: excludes compilaton of class initializers).
};
// Guide heuristics to determine whether to compile method if profile data not available.
@@ -58,7 +58,8 @@
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
@@ -76,7 +77,8 @@
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
@@ -93,7 +95,8 @@
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
@@ -196,6 +199,11 @@
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_;
@@ -211,6 +219,7 @@
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 869bf89..4f2d512 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -838,6 +838,7 @@
? 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;
@@ -964,6 +965,8 @@
}
} 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)) {
@@ -1203,7 +1206,8 @@
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;