dex2oat: Add a --compile-pic option
Change-Id: I80e03613e3b6ac079bcbc7e068bbaae760c364c9
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 4d5d253..3325568 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -243,8 +243,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;
@@ -273,8 +279,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;
@@ -289,8 +301,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 fb648fc..e604c21 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -920,6 +920,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();
@@ -1112,7 +1116,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,
@@ -1124,7 +1128,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 ||
@@ -1139,7 +1143,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) {
@@ -2002,6 +2006,10 @@
++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 c445683..c41f7f2 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -400,11 +400,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 eb3de97..3a50bfd 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -28,7 +28,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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