diff options
| author | 2016-06-01 18:38:43 +0100 | |
|---|---|---|
| committer | 2016-06-03 10:52:22 +0100 | |
| commit | 492a7fa6df3b197a24099a50f5abf624164f3842 (patch) | |
| tree | 1c02e48c0a16c8ff91f189946a39a3f14c1048dc /compiler/driver/compiler_driver.h | |
| parent | f7e1ab5224e16a47a410a788915422c73abfffac (diff) | |
Delay dex-to-dex compilation until Optimizing is done.
This fixes a race between inlining in the Optimizing
backend and dex-to-dex quickening where the Optimizing can
read the non-quickened opcode and then the quickened field
index or vtable index and look up the wrong field or method.
Even if we such tearing of the dex instruction does not
happen, the possible reordering of dex-to-dex and Optimizing
compilation makes the final oat file non-deterministic.
Also, remove VerificationResults::RemoveVerifiedMethod() as
we have only the Optimizing backend now and as such it was
dead code and would have interfered with this change.
Bug: 29043547
Bug: 29089975
Change-Id: I8389927d35dcacaf2f99c2153f055857036c8129
Diffstat (limited to 'compiler/driver/compiler_driver.h')
| -rw-r--r-- | compiler/driver/compiler_driver.h | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 19a1ecc494..2dd46514e7 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -52,6 +52,7 @@ namespace verifier { class MethodVerifier; } // namespace verifier +class BitVector; class CompiledClass; class CompiledMethod; class CompilerOptions; @@ -120,12 +121,12 @@ class CompilerDriver { void CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files, TimingLogger* timings) - REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_); + REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_, !dex_to_dex_references_lock_); // Compile a single Method. void CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings) SHARED_REQUIRES(Locks::mutator_lock_) - REQUIRES(!compiled_methods_lock_, !compiled_classes_lock_); + REQUIRES(!compiled_methods_lock_, !compiled_classes_lock_, !dex_to_dex_references_lock_); VerificationResults* GetVerificationResults() const { DCHECK(Runtime::Current()->IsAotCompiler()); @@ -475,6 +476,13 @@ class CompilerDriver { return true; } + void MarkForDexToDexCompilation(Thread* self, const MethodReference& method_ref) + REQUIRES(!dex_to_dex_references_lock_); + + const BitVector* GetCurrentDexToDexMethods() const { + return current_dex_to_dex_methods_; + } + private: // Return whether the declaring class of `resolved_member` is // available to `referrer_class` for read or write access using two @@ -601,7 +609,7 @@ class CompilerDriver { void Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files, - TimingLogger* timings); + TimingLogger* timings) REQUIRES(!dex_to_dex_references_lock_); void CompileDexFile(jobject class_loader, const DexFile& dex_file, const std::vector<const DexFile*>& dex_files, @@ -702,6 +710,16 @@ class CompilerDriver { const ProfileCompilationInfo* const profile_compilation_info_; size_t max_arena_alloc_; + + // Data for delaying dex-to-dex compilation. + Mutex dex_to_dex_references_lock_; + // In the first phase, dex_to_dex_references_ collects methods for dex-to-dex compilation. + class DexFileMethodSet; + std::vector<DexFileMethodSet> dex_to_dex_references_ GUARDED_BY(dex_to_dex_references_lock_); + // In the second phase, current_dex_to_dex_methods_ points to the BitVector with method + // indexes for dex-to-dex compilation in the current dex file. + const BitVector* current_dex_to_dex_methods_; + friend class CompileClassVisitor; DISALLOW_COPY_AND_ASSIGN(CompilerDriver); }; |