diff options
| author | 2012-05-03 02:35:42 -0700 | |
|---|---|---|
| committer | 2012-05-03 02:35:42 -0700 | |
| commit | 1ecce9487a1b3aac6b656f5704cf86a961ab0481 (patch) | |
| tree | d7ad598d6649d96ae4ab9817767a084d780c4a55 /src/compiler_llvm/method_compiler.cc | |
| parent | d2bbf03ebb75699d754c88ab2edc58758c0d23d7 (diff) | |
| parent | 86f5067d92f380e3a167d9c786b5f5c15d8dd0db (diff) | |
Merge "Change to implement fill-array-data with runtime function." into ics-mr1-plus-art
Diffstat (limited to 'src/compiler_llvm/method_compiler.cc')
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 68 | 
1 files changed, 17 insertions, 51 deletions
| diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc index 2c0fef146e..e44481182f 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc @@ -1893,65 +1893,31 @@ void MethodCompiler::EmitInsn_FillArrayData(uint32_t dex_pc,      reinterpret_cast<const Instruction::ArrayDataPayload*>(          code_item_->insns_ + payload_offset); -  uint32_t size_in_bytes = payload->element_width * payload->element_count; - -  // Load and check the array +  // Load array object    llvm::Value* array_addr = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate); -  EmitGuard_NullPointerException(dex_pc, array_addr); +  if (payload->element_count == 0) { +    // When the number of the elements in the payload is zero, we don't have +    // to copy any numbers.  However, we should check whether the array object +    // address is equal to null or not. +    EmitGuard_NullPointerException(dex_pc, array_addr); +  } else { +    // To save the code size, we are going to call the runtime function to +    // copy the content from DexFile. -  if (payload->element_count > 0) { -    // Test: Is array length big enough? -    llvm::Constant* last_index = irb_.getJInt(payload->element_count - 1); +    // NOTE: We will check for the NullPointerException in the runtime. -    EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, last_index); +    llvm::Function* runtime_func = irb_.GetRuntime(FillArrayData); -    // Get array data field -    llvm::Value* data_field_offset_value = -      irb_.getPtrEquivInt(Array::DataOffset(payload->element_width).Int32Value()); +    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); -    llvm::Value* data_field_addr = -      irb_.CreatePtrDisp(array_addr, data_field_offset_value, -                         irb_.getInt8Ty()->getPointerTo()); +    EmitUpdateDexPC(dex_pc); -    // Emit payload to bitcode constant pool -    std::vector<llvm::Constant*> const_pool_data; -    for (uint32_t i = 0; i < size_in_bytes; ++i) { -      const_pool_data.push_back(irb_.getInt8(payload->data[i])); -    } +    irb_.CreateCall4(runtime_func, +                     method_object_addr, irb_.getInt32(dex_pc), +                     array_addr, irb_.getInt32(payload_offset)); -    llvm::Constant* const_pool_data_array_value = llvm::ConstantArray::get( -      llvm::ArrayType::get(irb_.getInt8Ty(), size_in_bytes), const_pool_data); - -    llvm::Value* const_pool_data_array_addr = -      new llvm::GlobalVariable(*module_, -                               const_pool_data_array_value->getType(), -                               false, llvm::GlobalVariable::InternalLinkage, -                               const_pool_data_array_value, -                               "array_data_payload"); - -    // Find the memcpy intrinsic -    llvm::Type* memcpy_arg_types[] = { -      llvm::Type::getInt8Ty(*context_)->getPointerTo(), -      llvm::Type::getInt8Ty(*context_)->getPointerTo(), -      llvm::Type::getInt32Ty(*context_) -    }; - -    llvm::Function* memcpy_intrinsic = -      llvm::Intrinsic::getDeclaration(module_, -                                      llvm::Intrinsic::memcpy, -                                      memcpy_arg_types); - -    // Copy now! -    llvm::Value *args[] = { -      data_field_addr, -      irb_.CreateConstGEP2_32(const_pool_data_array_addr, 0, 0), -      irb_.getInt32(size_in_bytes), -      irb_.getInt32(0), // alignment: no guarantee -      irb_.getFalse() // is_volatile: false -    }; - -    irb_.CreateCall(memcpy_intrinsic, args); +    EmitGuard_ExceptionLandingPad(dex_pc);    }    irb_.CreateBr(GetNextBasicBlock(dex_pc)); |