summaryrefslogtreecommitdiff
path: root/compiler/compiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/compiler.cc')
-rw-r--r--compiler/compiler.cc199
1 files changed, 31 insertions, 168 deletions
diff --git a/compiler/compiler.cc b/compiler/compiler.cc
index a832c310eb..223affad82 100644
--- a/compiler/compiler.cc
+++ b/compiler/compiler.cc
@@ -15,186 +15,49 @@
*/
#include "compiler.h"
-#include "compilers.h"
-#include "driver/compiler_driver.h"
-#include "mirror/art_method-inl.h"
-#ifdef ART_USE_PORTABLE_COMPILER
-#include "dex/portable/mir_to_gbc.h"
-#include "elf_writer_mclinker.h"
-#endif
+#include "base/logging.h"
+#include "dex/quick/quick_compiler_factory.h"
+#include "driver/compiler_driver.h"
+#include "optimizing/optimizing_compiler.h"
+#include "utils.h"
namespace art {
-#ifdef ART_SEA_IR_MODE
-extern "C" art::CompiledMethod* SeaIrCompileMethod(const art::DexFile::CodeItem* code_item,
- uint32_t access_flags,
- art::InvokeType invoke_type,
- uint16_t class_def_idx,
- uint32_t method_idx,
- jobject class_loader,
- const art::DexFile& dex_file);
-#endif
+Compiler* Compiler::Create(CompilerDriver* driver, Compiler::Kind kind) {
+ switch (kind) {
+ case kQuick:
+ return CreateQuickCompiler(driver);
+ case kOptimizing:
+ return CreateOptimizingCompiler(driver);
-CompiledMethod* Compiler::TryCompileWithSeaIR(const art::DexFile::CodeItem* code_item,
- uint32_t access_flags,
- art::InvokeType invoke_type,
- uint16_t class_def_idx,
- uint32_t method_idx,
- jobject class_loader,
- const art::DexFile& dex_file) {
-#ifdef ART_SEA_IR_MODE
- bool use_sea = (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
- if (use_sea) {
- LOG(INFO) << "Using SEA IR to compile..." << std::endl;
- return SeaIrCompileMethod(code_item,
- access_flags,
- invoke_type,
- class_def_idx,
- method_idx,
- class_loader,
- dex_file);
+ default:
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
}
-#endif
- return nullptr;
}
-
-#ifdef ART_USE_PORTABLE_COMPILER
-
-extern "C" void ArtInitCompilerContext(art::CompilerDriver* driver);
-
-extern "C" void ArtUnInitCompilerContext(art::CompilerDriver* driver);
-
-extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver* driver,
- const art::DexFile::CodeItem* code_item,
- uint32_t access_flags,
- art::InvokeType invoke_type,
- uint16_t class_def_idx,
- uint32_t method_idx,
- jobject class_loader,
- const art::DexFile& dex_file);
-
-extern "C" art::CompiledMethod* ArtLLVMJniCompileMethod(art::CompilerDriver* driver,
- uint32_t access_flags, uint32_t method_idx,
- const art::DexFile& dex_file);
-
-extern "C" void compilerLLVMSetBitcodeFileName(art::CompilerDriver* driver,
- std::string const& filename);
-
-
-class LLVMCompiler FINAL : public Compiler {
- public:
- explicit LLVMCompiler(CompilerDriver* driver) : Compiler(driver, 1000) {}
-
- void Init() const OVERRIDE {
- ArtInitCompilerContext(GetCompilerDriver());
- }
-
- void UnInit() const OVERRIDE {
- ArtUnInitCompilerContext(GetCompilerDriver());
- }
-
- CompiledMethod* Compile(const DexFile::CodeItem* code_item,
- uint32_t access_flags,
- InvokeType invoke_type,
- uint16_t class_def_idx,
- uint32_t method_idx,
- jobject class_loader,
- const DexFile& dex_file) const OVERRIDE {
- CompiledMethod* method = TryCompileWithSeaIR(code_item,
- access_flags,
- invoke_type,
- class_def_idx,
- method_idx,
- class_loader,
- dex_file);
- if (method != nullptr) {
- return method;
- }
-
- return ArtCompileMethod(GetCompilerDriver(),
- code_item,
- access_flags,
- invoke_type,
- class_def_idx,
- method_idx,
- class_loader,
- dex_file);
- }
-
- CompiledMethod* JniCompile(uint32_t access_flags,
- uint32_t method_idx,
- const DexFile& dex_file) const OVERRIDE {
- return ArtLLVMJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file);
- }
-
- uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const {
- return reinterpret_cast<uintptr_t>(method->GetEntryPointFromPortableCompiledCode());
- }
-
- bool WriteElf(art::File* file,
- OatWriter* oat_writer,
- const std::vector<const art::DexFile*>& dex_files,
- const std::string& android_root,
- bool is_host, const CompilerDriver& driver) const
- OVERRIDE
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return art::ElfWriterMclinker::Create(
- file, oat_writer, dex_files, android_root, is_host, driver);
- }
-
- Backend* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const {
- return PortableCodeGenerator(
- cu, cu->mir_graph.get(), &cu->arena,
- reinterpret_cast<art::llvm::LlvmCompilationUnit*>(compilation_unit));
- }
-
- void InitCompilationUnit(CompilationUnit& cu) const {
- // Fused long branches not currently useful in bitcode.
- cu.disable_opt |=
- (1 << kBranchFusing) |
- (1 << kSuppressExceptionEdges);
- }
-
- bool IsPortable() const OVERRIDE {
+bool Compiler::IsPathologicalCase(const DexFile::CodeItem& code_item,
+ uint32_t method_idx,
+ const DexFile& dex_file) {
+ /*
+ * Skip compilation for pathologically large methods - either by instruction count or num vregs.
+ * Dalvik uses 16-bit uints for instruction and register counts. We'll limit to a quarter
+ * of that, which also guarantees we cannot overflow our 16-bit internal Quick SSA name space.
+ */
+ if (code_item.insns_size_in_code_units_ >= UINT16_MAX / 4) {
+ LOG(INFO) << "Method exceeds compiler instruction limit: "
+ << code_item.insns_size_in_code_units_
+ << " in " << PrettyMethod(method_idx, dex_file);
return true;
}
-
- void SetBitcodeFileName(const CompilerDriver& driver, const std::string& filename) {
- typedef void (*SetBitcodeFileNameFn)(const CompilerDriver&, const std::string&);
-
- SetBitcodeFileNameFn set_bitcode_file_name =
- reinterpret_cast<SetBitcodeFileNameFn>(compilerLLVMSetBitcodeFileName);
-
- set_bitcode_file_name(driver, filename);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(LLVMCompiler);
-};
-#endif
-
-Compiler* Compiler::Create(CompilerDriver* driver, Compiler::Kind kind) {
- switch (kind) {
- case kQuick:
- return new QuickCompiler(driver);
- break;
- case kOptimizing:
- return new OptimizingCompiler(driver);
- break;
- case kPortable:
-#ifdef ART_USE_PORTABLE_COMPILER
- return new LLVMCompiler(driver);
-#else
- LOG(FATAL) << "Portable compiler not compiled";
-#endif
- break;
- default:
- LOG(FATAL) << "UNREACHABLE";
+ if (code_item.registers_size_ >= UINT16_MAX / 4) {
+ LOG(INFO) << "Method exceeds compiler virtual register limit: "
+ << code_item.registers_size_ << " in " << PrettyMethod(method_idx, dex_file);
+ return true;
}
- return nullptr;
+ return false;
}
} // namespace art