/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ART_DEX2OAT_DEX_DEX_TO_DEX_COMPILER_H_ #define ART_DEX2OAT_DEX_DEX_TO_DEX_COMPILER_H_ #include <set> #include <unordered_map> #include <unordered_set> #include "base/bit_vector.h" #include "base/mutex.h" #include "dex/invoke_type.h" #include "dex/method_reference.h" #include "handle.h" #include "quicken_info.h" namespace art { class CompiledMethod; class CompilerDriver; class DexCompilationUnit; class DexFile; namespace dex { struct CodeItem; } // namespace dex namespace mirror { class ClassLoader; } // namespace mirror namespace optimizer { class DexToDexCompiler { public: enum class CompilationLevel { kDontDexToDexCompile, // Only meaning wrt image time interpretation. kOptimize // Perform peep-hole optimizations. }; explicit DexToDexCompiler(CompilerDriver* driver); CompiledMethod* CompileMethod(const dex::CodeItem* code_item, uint32_t access_flags, InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, const CompilationLevel compilation_level) WARN_UNUSED; void MarkForCompilation(Thread* self, const MethodReference& method_ref); void ClearState(); // Unquicken all methods that have conflicting quicken info. This is not done during the // quickening process to avoid race conditions. void UnquickenConflictingMethods(); CompilerDriver* GetDriver() { return driver_; } bool ShouldCompileMethod(const MethodReference& ref); // Return the number of code items to quicken. size_t NumCodeItemsToQuicken(Thread* self) const; void SetDexFiles(const std::vector<const DexFile*>& dex_files); private: // Holds the state for compiling a single method. struct CompilationState; // Quicken state for a code item, may be referenced by multiple methods. struct QuickenState { std::vector<MethodReference> methods_; std::vector<uint8_t> quicken_data_; bool optimized_return_void_ = false; bool conflict_ = false; }; BitVector* GetOrAddBitVectorForDex(const DexFile* dex_file) REQUIRES(lock_); CompilerDriver* const driver_; // State for adding methods (should this be in its own class?). const DexFile* active_dex_file_ = nullptr; BitVector* active_bit_vector_ = nullptr; // Lock that guards duplicate code items and the bitmap. mutable Mutex lock_; // Record what method references are going to get quickened. std::unordered_map<const DexFile*, BitVector> should_quicken_; // Guarded by lock_ during writing, accessed without a lock during quickening. // This is safe because no thread is adding to the shared code items during the quickening phase. std::unordered_set<const dex::CodeItem*> shared_code_items_; // Blacklisted code items are unquickened in UnquickenConflictingMethods. std::unordered_map<const dex::CodeItem*, QuickenState> shared_code_item_quicken_info_ GUARDED_BY(lock_); // Number of added code items. size_t num_code_items_ GUARDED_BY(lock_) = 0u; }; std::ostream& operator<<(std::ostream& os, const DexToDexCompiler::CompilationLevel& rhs); } // namespace optimizer } // namespace art #endif // ART_DEX2OAT_DEX_DEX_TO_DEX_COMPILER_H_