summaryrefslogtreecommitdiff
path: root/compiler/driver
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2017-09-11 14:15:52 +0100
committer Nicolas Geoffray <ngeoffray@google.com> 2017-09-15 12:45:28 +0100
commit486dda03900a215650f71a9068759978aa77c699 (patch)
tree1f2a1331d3ec474c979db5f9a35dd11f453abc25 /compiler/driver
parentb072ec25f8a71420ee77b068a28a2669420f6150 (diff)
Add support for registering classpath classes status.
By doing class unloading after each dex file compilation, we are loosing away verification done on classpath classes. This change introduces a new table for keeping around class status of classpath classes. Multidex quickening compilation improved by ~5% by not re-verifying classpath classes. Bug: 63467744 test: test.py test: golem successfully compiles FB Change-Id: I629c0a7d86519bbc516f5e59f7cd92ca6ca842eb
Diffstat (limited to 'compiler/driver')
-rw-r--r--compiler/driver/compiler_driver.cc34
-rw-r--r--compiler/driver/compiler_driver.h3
2 files changed, 27 insertions, 10 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 18b54eefba..b9c0314cb1 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2900,6 +2900,14 @@ bool CompilerDriver::GetCompiledClass(ClassReference ref, mirror::Class::Status*
return true;
}
+mirror::Class::Status CompilerDriver::GetClassStatus(ClassReference ref) const {
+ mirror::Class::Status status = ClassStatus::kStatusNotReady;
+ if (!GetCompiledClass(ref, &status)) {
+ classpath_classes_.Get(DexFileReference(ref.first, ref.second), &status);
+ }
+ return status;
+}
+
void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status status) {
switch (status) {
case mirror::Class::kStatusErrorResolved:
@@ -2918,11 +2926,12 @@ void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status
}
ClassStateTable::InsertResult result;
+ ClassStateTable* table = &compiled_classes_;
do {
DexFileReference dex_ref(ref.first, ref.second);
mirror::Class::Status existing = mirror::Class::kStatusNotReady;
- if (!compiled_classes_.Get(dex_ref, &existing)) {
- // Probably a uses library class, bail.
+ if (!table->Get(dex_ref, &existing)) {
+ // A classpath class.
if (kIsDebugBuild) {
// Check to make sure it's not a dex file for an oat file we are compiling since these
// should always succeed. These do not include classes in for used libraries.
@@ -2930,7 +2939,12 @@ void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status
CHECK_NE(dex_ref.dex_file, dex_file) << dex_ref.dex_file->GetLocation();
}
}
- return;
+ if (!classpath_classes_.HaveDexFile(ref.first)) {
+ // Boot classpath dex file.
+ return;
+ }
+ table = &classpath_classes_;
+ table->Get(dex_ref, &existing);
}
if (existing >= status) {
// Existing status is already better than we expect, break.
@@ -2938,8 +2952,8 @@ void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status
}
// Update the status if we now have a greater one. This happens with vdex,
// which records a class is verified, but does not resolve it.
- result = compiled_classes_.Insert(dex_ref, existing, status);
- CHECK(result != ClassStateTable::kInsertResultInvalidDexFile);
+ result = table->Insert(dex_ref, existing, status);
+ CHECK(result != ClassStateTable::kInsertResultInvalidDexFile) << ref.first->GetLocation();
} while (result != ClassStateTable::kInsertResultSuccess);
}
@@ -3046,11 +3060,11 @@ void CompilerDriver::FreeThreadPools() {
void CompilerDriver::SetDexFilesForOatFile(const std::vector<const DexFile*>& dex_files) {
dex_files_for_oat_file_ = dex_files;
- for (const DexFile* dex_file : dex_files) {
- if (!compiled_classes_.HaveDexFile(dex_file)) {
- compiled_classes_.AddDexFile(dex_file, dex_file->NumClassDefs());
- }
- }
+ compiled_classes_.AddDexFiles(dex_files);
+}
+
+void CompilerDriver::SetClasspathDexFiles(const std::vector<const DexFile*>& dex_files) {
+ classpath_classes_.AddDexFiles(dex_files);
}
} // namespace art
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index d08d9d7940..19fae695b5 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -106,6 +106,7 @@ class CompilerDriver {
// Set dex files that will be stored in the oat file after being compiled.
void SetDexFilesForOatFile(const std::vector<const DexFile*>& dex_files);
+ void SetClasspathDexFiles(const std::vector<const DexFile*>& dex_files);
// Get dex file that will be stored in the oat file after being compiled.
ArrayRef<const DexFile* const> GetDexFilesForOatFile() const {
@@ -152,6 +153,7 @@ class CompilerDriver {
std::unique_ptr<const std::vector<uint8_t>> CreateQuickToInterpreterBridge() const;
bool GetCompiledClass(ClassReference ref, mirror::Class::Status* status) const;
+ mirror::Class::Status GetClassStatus(ClassReference ref) const;
CompiledMethod* GetCompiledMethod(MethodReference ref) const;
size_t GetNonRelativeLinkerPatchCount() const;
@@ -488,6 +490,7 @@ class CompilerDriver {
// All class references that this compiler has compiled. Indexed by class defs.
using ClassStateTable = AtomicDexRefMap<mirror::Class::Status>;
ClassStateTable compiled_classes_;
+ ClassStateTable classpath_classes_;
typedef AtomicDexRefMap<CompiledMethod*> MethodTable;