summaryrefslogtreecommitdiff
path: root/src/compiler_llvm/method_compiler.cc
diff options
context:
space:
mode:
author Shih-wei Liao <sliao@google.com> 2012-05-03 02:35:42 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2012-05-03 02:35:42 -0700
commit1ecce9487a1b3aac6b656f5704cf86a961ab0481 (patch)
treed7ad598d6649d96ae4ab9817767a084d780c4a55 /src/compiler_llvm/method_compiler.cc
parentd2bbf03ebb75699d754c88ab2edc58758c0d23d7 (diff)
parent86f5067d92f380e3a167d9c786b5f5c15d8dd0db (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.cc68
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));