optimizing_compiler.cc revision 622d9c31febd950255b36a48b47e1f630197c5fe
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdint.h> 18 19#include "builder.h" 20#include "code_generator.h" 21#include "compilers.h" 22#include "driver/compiler_driver.h" 23#include "driver/dex_compilation_unit.h" 24#include "nodes.h" 25#include "ssa_liveness_analysis.h" 26#include "utils/arena_allocator.h" 27 28namespace art { 29 30/** 31 * Used by the code generator, to allocate the code in a vector. 32 */ 33class CodeVectorAllocator FINAL : public CodeAllocator { 34 public: 35 CodeVectorAllocator() { } 36 37 virtual uint8_t* Allocate(size_t size) { 38 size_ = size; 39 memory_.resize(size); 40 return &memory_[0]; 41 } 42 43 size_t GetSize() const { return size_; } 44 const std::vector<uint8_t>& GetMemory() const { return memory_; } 45 46 private: 47 std::vector<uint8_t> memory_; 48 size_t size_; 49 50 DISALLOW_COPY_AND_ASSIGN(CodeVectorAllocator); 51}; 52 53 54CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_item, 55 uint32_t access_flags, 56 InvokeType invoke_type, 57 uint16_t class_def_idx, 58 uint32_t method_idx, 59 jobject class_loader, 60 const DexFile& dex_file) const { 61 DexCompilationUnit dex_compilation_unit( 62 nullptr, class_loader, art::Runtime::Current()->GetClassLinker(), dex_file, code_item, 63 class_def_idx, method_idx, access_flags, 64 GetCompilerDriver()->GetVerifiedMethod(&dex_file, method_idx)); 65 66 // For testing purposes, we put a special marker on method names that should be compiled 67 // with this compiler. This makes sure we're not regressing. 68 bool shouldCompile = dex_compilation_unit.GetSymbol().find("00024opt_00024") != std::string::npos; 69 70 ArenaPool pool; 71 ArenaAllocator arena(&pool); 72 HGraphBuilder builder(&arena, &dex_compilation_unit, &dex_file); 73 HGraph* graph = builder.BuildGraph(*code_item); 74 if (graph == nullptr) { 75 if (shouldCompile) { 76 LOG(FATAL) << "Could not build graph in optimizing compiler"; 77 } 78 return nullptr; 79 } 80 81 InstructionSet instruction_set = GetCompilerDriver()->GetInstructionSet(); 82 // The optimizing compiler currently does not have a Thumb2 assembler. 83 if (instruction_set == kThumb2) { 84 instruction_set = kArm; 85 } 86 CodeGenerator* codegen = CodeGenerator::Create(&arena, graph, instruction_set); 87 if (codegen == nullptr) { 88 if (shouldCompile) { 89 LOG(FATAL) << "Could not find code generator for optimizing compiler"; 90 } 91 return nullptr; 92 } 93 94 CodeVectorAllocator allocator; 95 codegen->Compile(&allocator); 96 97 std::vector<uint8_t> mapping_table; 98 codegen->BuildMappingTable(&mapping_table); 99 std::vector<uint8_t> vmap_table; 100 codegen->BuildVMapTable(&vmap_table); 101 std::vector<uint8_t> gc_map; 102 codegen->BuildNativeGCMap(&gc_map, dex_compilation_unit); 103 104 // Run these phases to get some test coverage. 105 graph->BuildDominatorTree(); 106 graph->TransformToSSA(); 107 graph->FindNaturalLoops(); 108 SsaLivenessAnalysis(*graph).Analyze(); 109 110 return new CompiledMethod(GetCompilerDriver(), 111 instruction_set, 112 allocator.GetMemory(), 113 codegen->GetFrameSize(), 114 codegen->GetCoreSpillMask(), 115 0, /* FPR spill mask, unused */ 116 mapping_table, 117 vmap_table, 118 gc_map, 119 nullptr); 120} 121 122} // namespace art 123