diff options
Diffstat (limited to 'src/compiler_llvm')
| -rw-r--r-- | src/compiler_llvm/dalvik_reg.cc | 4 | ||||
| -rw-r--r-- | src/compiler_llvm/inferred_reg_category_map.cc | 10 | ||||
| -rw-r--r-- | src/compiler_llvm/inferred_reg_category_map.h | 5 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 43 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.h | 5 |
5 files changed, 52 insertions, 15 deletions
diff --git a/src/compiler_llvm/dalvik_reg.cc b/src/compiler_llvm/dalvik_reg.cc index ab5cc40a7a..84da907bdc 100644 --- a/src/compiler_llvm/dalvik_reg.cc +++ b/src/compiler_llvm/dalvik_reg.cc @@ -246,9 +246,7 @@ DalvikLocalVarReg::~DalvikLocalVarReg() { void DalvikLocalVarReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) { DalvikReg::SetValue(jty, space, value); - if (jty == kObject) { - DCHECK_NE(reg_shadow_frame_, static_cast<llvm::Value*>(NULL)) - << "Didn't allocate shadow frame entry."; + if (jty == kObject && reg_shadow_frame_ != NULL) { irb_.CreateStore(value, reg_shadow_frame_, kTBAAShadowFrame); } } diff --git a/src/compiler_llvm/inferred_reg_category_map.cc b/src/compiler_llvm/inferred_reg_category_map.cc index 04acd6fd9e..2403750cf3 100644 --- a/src/compiler_llvm/inferred_reg_category_map.cc +++ b/src/compiler_llvm/inferred_reg_category_map.cc @@ -28,7 +28,7 @@ namespace compiler_llvm { InferredRegCategoryMap::InferredRegCategoryMap(uint32_t insns_size, uint8_t regs_size) -: registers_size_(regs_size), lines_(insns_size, NULL) { +: registers_size_(regs_size), lines_(insns_size, NULL), can_be_object_(regs_size) { } InferredRegCategoryMap::~InferredRegCategoryMap() { @@ -55,6 +55,14 @@ void InferredRegCategoryMap::SetRegCategory(uint32_t dex_pc, } } +bool InferredRegCategoryMap::IsRegCanBeObject(uint16_t reg_idx) const { + return can_be_object_[reg_idx]; +} + +void InferredRegCategoryMap::SetRegCanBeObject(uint16_t reg_idx) { + can_be_object_[reg_idx] = true; +} + bool InferredRegCategoryMap:: operator==(InferredRegCategoryMap const& rhs) const { diff --git a/src/compiler_llvm/inferred_reg_category_map.h b/src/compiler_llvm/inferred_reg_category_map.h index 7b3501b40a..7f4082dcc6 100644 --- a/src/compiler_llvm/inferred_reg_category_map.h +++ b/src/compiler_llvm/inferred_reg_category_map.h @@ -67,6 +67,9 @@ class InferredRegCategoryMap { RegCategory GetRegCategory(uint32_t dex_pc, uint16_t reg_idx) const; void SetRegCategory(uint32_t dex_pc, uint16_t reg_idx, RegCategory cat); + bool IsRegCanBeObject(uint16_t reg_idx) const; + void SetRegCanBeObject(uint16_t reg_idx); + bool operator==(InferredRegCategoryMap const& rhs) const; bool operator!=(InferredRegCategoryMap const& rhs) const; @@ -75,6 +78,8 @@ class InferredRegCategoryMap { std::vector<RegCategoryLine*> lines_; + std::vector<bool> can_be_object_; + DISALLOW_COPY_AND_ASSIGN(InferredRegCategoryMap); }; diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc index c5606c794f..3f3e0ad581 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc @@ -60,7 +60,11 @@ MethodCompiler::MethodCompiler(CompilationUnit* cunit, access_flags_(oat_compilation_unit->access_flags_), module_(cunit->GetModule()), context_(cunit->GetLLVMContext()), - irb_(*cunit->GetIRBuilder()), func_(NULL), retval_reg_(NULL), + irb_(*cunit->GetIRBuilder()), + func_(NULL), + regs_(code_item_->registers_size_), + reg_to_shadow_frame_index_(code_item_->registers_size_, -1), + retval_reg_(NULL), basic_block_stack_overflow_(NULL), basic_block_reg_alloca_(NULL), basic_block_shadow_frame_alloca_(NULL), basic_block_reg_arg_init_(NULL), @@ -165,7 +169,7 @@ void MethodCompiler::EmitPrologue() { // Create register array for (uint16_t r = 0; r < code_item_->registers_size_; ++r) { - regs_.push_back(DalvikReg::CreateLocalVarReg(*this, r)); + regs_[r] = DalvikReg::CreateLocalVarReg(*this, r); } retval_reg_.reset(DalvikReg::CreateRetValReg(*this)); @@ -250,10 +254,12 @@ void MethodCompiler::EmitPrologueAllocShadowFrame() { irb_.SetInsertPoint(basic_block_shadow_frame_alloca_); // Allocate the shadow frame now! - uint32_t sirt_size = code_item_->registers_size_; - // TODO: registers_size_ is a bad approximation. Compute a - // tighter approximation at Dex verifier while performing data-flow - // analysis. + uint32_t sirt_size = 0; + for (uint32_t i = 0, num_of_regs = code_item_->registers_size_; i < num_of_regs; ++i) { + if (IsRegCanBeObject(i)) { + reg_to_shadow_frame_index_[i] = sirt_size++; + } + } llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size); shadow_frame_ = irb_.CreateAlloca(shadow_frame_type); @@ -2141,10 +2147,7 @@ void MethodCompiler::EmitInsn_UnaryConditionalBranch(uint32_t dex_pc, GetNextBasicBlock(dex_pc)); } - -RegCategory MethodCompiler::GetInferredRegCategory(uint32_t dex_pc, - uint16_t reg_idx) { - +InferredRegCategoryMap const* MethodCompiler::GetInferredRegCategoryMap() { Compiler::MethodReference mref(dex_file_, method_idx_); InferredRegCategoryMap const* map = @@ -2152,9 +2155,22 @@ RegCategory MethodCompiler::GetInferredRegCategory(uint32_t dex_pc, CHECK_NE(map, static_cast<InferredRegCategoryMap*>(NULL)); + return map; +} + +RegCategory MethodCompiler::GetInferredRegCategory(uint32_t dex_pc, + uint16_t reg_idx) { + InferredRegCategoryMap const* map = GetInferredRegCategoryMap(); + return map->GetRegCategory(dex_pc, reg_idx); } +bool MethodCompiler::IsRegCanBeObject(uint16_t reg_idx) { + InferredRegCategoryMap const* map = GetInferredRegCategoryMap(); + + return map->IsRegCanBeObject(reg_idx); +} + llvm::Value* MethodCompiler::EmitConditionResult(llvm::Value* lhs, llvm::Value* rhs, @@ -3839,6 +3855,11 @@ llvm::Value* MethodCompiler::AllocDalvikLocalVarReg(RegCategory cat, llvm::Value* MethodCompiler::AllocShadowFrameEntry(uint32_t reg_idx) { + if (reg_to_shadow_frame_index_[reg_idx] == -1) { + // This register dosen't need ShadowFrame entry + return NULL; + } + std::string reg_name; #if !defined(NDEBUG) @@ -3853,7 +3874,7 @@ llvm::Value* MethodCompiler::AllocShadowFrameEntry(uint32_t reg_idx) { llvm::Value* gep_index[] = { irb_.getInt32(0), // No pointer displacement irb_.getInt32(1), // SIRT - irb_.getInt32(reg_idx) // Pointer field + irb_.getInt32(reg_to_shadow_frame_index_[reg_idx]) // Pointer field }; llvm::Value* reg_addr = irb_.CreateGEP(shadow_frame_, gep_index, reg_name); diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h index e1465dcce6..e815e3b2e4 100644 --- a/src/compiler_llvm/method_compiler.h +++ b/src/compiler_llvm/method_compiler.h @@ -374,6 +374,10 @@ class MethodCompiler { RegCategory GetInferredRegCategory(uint32_t dex_pc, uint16_t reg); + InferredRegCategoryMap const* GetInferredRegCategoryMap(); + + bool IsRegCanBeObject(uint16_t reg_idx); + // Basic block helper functions llvm::BasicBlock* GetBasicBlock(uint32_t dex_pc); @@ -453,6 +457,7 @@ class MethodCompiler { llvm::Function* func_; std::vector<DalvikReg*> regs_; + std::vector<int32_t> reg_to_shadow_frame_index_; UniquePtr<DalvikReg> retval_reg_; llvm::BasicBlock* basic_block_stack_overflow_; |