Add .bss support for inlining across dexfiles within Oat
We can safely reference other dexfiles within the same oat file for cross-dex inlining.
This CL makes the OptStat#NotInlinedBss drop to less than 1% of the not-inlining cases.
Test: ART tests
Change-Id: I676d48d973abf7a6f8412cf3b7bb73afd7747f31
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index db17bda..a31be3f 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -373,6 +373,11 @@
return initialize_app_image_classes_;
}
+ bool WithinOatFile(const DexFile* dex_file) const {
+ return std::find(GetDexFilesForOatFile().begin(), GetDexFilesForOatFile().end(), dex_file) !=
+ GetDexFilesForOatFile().end();
+ }
+
private:
bool ParseDumpInitFailures(const std::string& option, std::string* error_msg);
bool ParseRegisterAllocationStrategy(const std::string& option, std::string* error_msg);
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index a323405..fe97c7f 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -281,7 +281,8 @@
InvokeRuntimeCallingConvention calling_convention;
if (must_resolve_type) {
- DCHECK(IsSameDexFile(cls_->GetDexFile(), arm64_codegen->GetGraph()->GetDexFile()));
+ DCHECK(IsSameDexFile(cls_->GetDexFile(), arm64_codegen->GetGraph()->GetDexFile()) ||
+ arm64_codegen->GetCompilerOptions().WithinOatFile(&cls_->GetDexFile()));
dex::TypeIndex type_index = cls_->GetTypeIndex();
__ Mov(calling_convention.GetRegisterAt(0).W(), type_index.index_);
if (cls_->NeedsAccessCheck()) {
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index 6d77f54..b58ef12 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -529,7 +529,8 @@
InvokeRuntimeCallingConventionARMVIXL calling_convention;
if (must_resolve_type) {
- DCHECK(IsSameDexFile(cls_->GetDexFile(), arm_codegen->GetGraph()->GetDexFile()));
+ DCHECK(IsSameDexFile(cls_->GetDexFile(), arm_codegen->GetGraph()->GetDexFile()) ||
+ arm_codegen->GetCompilerOptions().WithinOatFile(&cls_->GetDexFile()));
dex::TypeIndex type_index = cls_->GetTypeIndex();
__ Mov(calling_convention.GetRegisterAt(0), type_index.index_);
if (cls_->NeedsAccessCheck()) {
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 4008b7d..7924e56 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -288,7 +288,8 @@
InvokeRuntimeCallingConvention calling_convention;
if (must_resolve_type) {
- DCHECK(IsSameDexFile(cls_->GetDexFile(), x86_codegen->GetGraph()->GetDexFile()));
+ DCHECK(IsSameDexFile(cls_->GetDexFile(), x86_codegen->GetGraph()->GetDexFile()) ||
+ x86_codegen->GetCompilerOptions().WithinOatFile(&cls_->GetDexFile()));
dex::TypeIndex type_index = cls_->GetTypeIndex();
__ movl(calling_convention.GetRegisterAt(0), Immediate(type_index.index_));
if (cls_->NeedsAccessCheck()) {
@@ -5497,7 +5498,8 @@
size_t index = invoke->IsInvokeInterface()
? invoke->AsInvokeInterface()->GetSpecialInputIndex()
: invoke->AsInvokeStaticOrDirect()->GetSpecialInputIndex();
- DCHECK(IsSameDexFile(GetGraph()->GetDexFile(), *invoke->GetMethodReference().dex_file));
+ DCHECK(IsSameDexFile(GetGraph()->GetDexFile(), *invoke->GetMethodReference().dex_file) ||
+ GetCompilerOptions().WithinOatFile(invoke->GetMethodReference().dex_file));
HX86ComputeBaseMethodAddress* method_address =
invoke->InputAt(index)->AsX86ComputeBaseMethodAddress();
// Add the patch entry and bind its label at the end of the instruction.
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index ad81620..f737d06 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -272,7 +272,8 @@
// Custom calling convention: RAX serves as both input and output.
if (must_resolve_type) {
- DCHECK(IsSameDexFile(cls_->GetDexFile(), x86_64_codegen->GetGraph()->GetDexFile()));
+ DCHECK(IsSameDexFile(cls_->GetDexFile(), x86_64_codegen->GetGraph()->GetDexFile()) ||
+ x86_64_codegen->GetCompilerOptions().WithinOatFile(&cls_->GetDexFile()));
dex::TypeIndex type_index = cls_->GetTypeIndex();
__ movl(CpuRegister(RAX), Immediate(type_index.index_));
if (cls_->NeedsAccessCheck()) {
@@ -1228,7 +1229,8 @@
}
void CodeGeneratorX86_64::RecordMethodBssEntryPatch(HInvoke* invoke) {
- DCHECK(IsSameDexFile(GetGraph()->GetDexFile(), *invoke->GetMethodReference().dex_file));
+ DCHECK(IsSameDexFile(GetGraph()->GetDexFile(), *invoke->GetMethodReference().dex_file) ||
+ GetCompilerOptions().WithinOatFile(invoke->GetMethodReference().dex_file));
method_bss_entry_patches_.emplace_back(invoke->GetMethodReference().dex_file,
invoke->GetMethodReference().index);
__ Bind(&method_bss_entry_patches_.back().label);
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index e996512..8d0258d 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1710,6 +1710,7 @@
// JIT can always encode methods in stack maps.
return true;
}
+
const DexFile* dex_file = callee->GetDexFile();
if (IsSameDexFile(outer_dex_file, *dex_file)) {
return true;
@@ -1718,15 +1719,16 @@
// Inline across dexfiles if the callee's DexFile is:
// 1) in the bootclasspath, or
if (callee->GetDeclaringClass()->GetClassLoader() == nullptr) {
+ // There are cases in which the BCP DexFiles are within the OatFile as far as the compiler
+ // options are concerned, but they have their own OatWriter (and therefore not in the same
+ // OatFile). Then, we request the BSS check for all BCP DexFiles.
+ // TODO(solanes): Add .bss support for BCP.
*out_needs_bss_check = true;
return true;
}
- // 2) is a non-BCP dexfile with an OatDexFile.
- const std::vector<const DexFile*>& dex_files =
- codegen->GetCompilerOptions().GetDexFilesForOatFile();
- if (std::find(dex_files.begin(), dex_files.end(), dex_file) != dex_files.end()) {
- *out_needs_bss_check = true;
+ // 2) is a non-BCP dexfile with the OatFile we are compiling.
+ if (codegen->GetCompilerOptions().WithinOatFile(dex_file)) {
return true;
}