diff options
| -rw-r--r-- | src/compiler_llvm/art_module.ll | 4 | ||||
| -rw-r--r-- | src/compiler_llvm/generated/art_module.cc | 57 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 68 | ||||
| -rw-r--r-- | src/compiler_llvm/runtime_support_func_list.h | 1 | ||||
| -rw-r--r-- | src/compiler_llvm/runtime_support_llvm.cc | 38 |
5 files changed, 99 insertions, 69 deletions
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll index 6d4b56b6a1..a2da2b6376 100644 --- a/src/compiler_llvm/art_module.ll +++ b/src/compiler_llvm/art_module.ll @@ -144,6 +144,10 @@ declare %JavaObject* @art_decode_jobject_in_thread(%JavaObject*, %JavaObject*) +declare void @art_fill_array_data_from_code(%JavaObject*, i32, + %JavaObject*, i32) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Type Checking, in the nature of casting ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/compiler_llvm/generated/art_module.cc b/src/compiler_llvm/generated/art_module.cc index 1237ec05be..b3963ef8dd 100644 --- a/src/compiler_llvm/generated/art_module.cc +++ b/src/compiler_llvm/generated/art_module.cc @@ -1,4 +1,4 @@ -// Generated with tools/gen_art_module_cc.sh +// Generated with ../tools/gen_art_module_cc.sh #pragma GCC diagnostic ignored "-Wframe-larger-than=" @@ -278,52 +278,62 @@ FunctionType* FuncTy_28 = FunctionType::get( std::vector<Type*>FuncTy_29_args; FuncTy_29_args.push_back(PointerTy_1); +FuncTy_29_args.push_back(IntegerType::get(mod->getContext(), 32)); FuncTy_29_args.push_back(PointerTy_1); +FuncTy_29_args.push_back(IntegerType::get(mod->getContext(), 32)); FunctionType* FuncTy_29 = FunctionType::get( - /*Result=*/IntegerType::get(mod->getContext(), 32), + /*Result=*/Type::getVoidTy(mod->getContext()), /*Params=*/FuncTy_29_args, /*isVarArg=*/false); std::vector<Type*>FuncTy_30_args; -FuncTy_30_args.push_back(Type::getDoubleTy(mod->getContext())); +FuncTy_30_args.push_back(PointerTy_1); +FuncTy_30_args.push_back(PointerTy_1); FunctionType* FuncTy_30 = FunctionType::get( - /*Result=*/IntegerType::get(mod->getContext(), 64), + /*Result=*/IntegerType::get(mod->getContext(), 32), /*Params=*/FuncTy_30_args, /*isVarArg=*/false); std::vector<Type*>FuncTy_31_args; FuncTy_31_args.push_back(Type::getDoubleTy(mod->getContext())); FunctionType* FuncTy_31 = FunctionType::get( - /*Result=*/IntegerType::get(mod->getContext(), 32), + /*Result=*/IntegerType::get(mod->getContext(), 64), /*Params=*/FuncTy_31_args, /*isVarArg=*/false); std::vector<Type*>FuncTy_32_args; -FuncTy_32_args.push_back(Type::getFloatTy(mod->getContext())); +FuncTy_32_args.push_back(Type::getDoubleTy(mod->getContext())); FunctionType* FuncTy_32 = FunctionType::get( - /*Result=*/IntegerType::get(mod->getContext(), 64), + /*Result=*/IntegerType::get(mod->getContext(), 32), /*Params=*/FuncTy_32_args, /*isVarArg=*/false); std::vector<Type*>FuncTy_33_args; FuncTy_33_args.push_back(Type::getFloatTy(mod->getContext())); FunctionType* FuncTy_33 = FunctionType::get( - /*Result=*/IntegerType::get(mod->getContext(), 32), + /*Result=*/IntegerType::get(mod->getContext(), 64), /*Params=*/FuncTy_33_args, /*isVarArg=*/false); std::vector<Type*>FuncTy_34_args; -FuncTy_34_args.push_back(PointerTy_1); +FuncTy_34_args.push_back(Type::getFloatTy(mod->getContext())); FunctionType* FuncTy_34 = FunctionType::get( - /*Result=*/PointerTy_1, + /*Result=*/IntegerType::get(mod->getContext(), 32), /*Params=*/FuncTy_34_args, /*isVarArg=*/false); std::vector<Type*>FuncTy_35_args; FuncTy_35_args.push_back(PointerTy_1); FunctionType* FuncTy_35 = FunctionType::get( - /*Result=*/Type::getVoidTy(mod->getContext()), + /*Result=*/PointerTy_1, /*Params=*/FuncTy_35_args, + /*isVarArg=*/false); + +std::vector<Type*>FuncTy_36_args; +FuncTy_36_args.push_back(PointerTy_1); +FunctionType* FuncTy_36 = FunctionType::get( + /*Result=*/Type::getVoidTy(mod->getContext()), + /*Params=*/FuncTy_36_args, /*isVarArg=*/true); @@ -857,10 +867,21 @@ func_art_decode_jobject_in_thread->setCallingConv(CallingConv::C); AttrListPtr func_art_decode_jobject_in_thread_PAL; func_art_decode_jobject_in_thread->setAttributes(func_art_decode_jobject_in_thread_PAL); +Function* func_art_fill_array_data_from_code = mod->getFunction("art_fill_array_data_from_code"); +if (!func_art_fill_array_data_from_code) { +func_art_fill_array_data_from_code = Function::Create( + /*Type=*/FuncTy_29, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"art_fill_array_data_from_code", mod); // (external, no body) +func_art_fill_array_data_from_code->setCallingConv(CallingConv::C); +} +AttrListPtr func_art_fill_array_data_from_code_PAL; +func_art_fill_array_data_from_code->setAttributes(func_art_fill_array_data_from_code_PAL); + Function* func_art_is_assignable_from_code = mod->getFunction("art_is_assignable_from_code"); if (!func_art_is_assignable_from_code) { func_art_is_assignable_from_code = Function::Create( - /*Type=*/FuncTy_29, + /*Type=*/FuncTy_30, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"art_is_assignable_from_code", mod); // (external, no body) func_art_is_assignable_from_code->setCallingConv(CallingConv::C); @@ -893,7 +914,7 @@ func_art_check_put_array_element_from_code->setAttributes(func_art_check_put_arr Function* func_D2L = mod->getFunction("D2L"); if (!func_D2L) { func_D2L = Function::Create( - /*Type=*/FuncTy_30, + /*Type=*/FuncTy_31, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"D2L", mod); // (external, no body) func_D2L->setCallingConv(CallingConv::C); @@ -904,7 +925,7 @@ func_D2L->setAttributes(func_D2L_PAL); Function* func_D2I = mod->getFunction("D2I"); if (!func_D2I) { func_D2I = Function::Create( - /*Type=*/FuncTy_31, + /*Type=*/FuncTy_32, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"D2I", mod); // (external, no body) func_D2I->setCallingConv(CallingConv::C); @@ -915,7 +936,7 @@ func_D2I->setAttributes(func_D2I_PAL); Function* func_F2L = mod->getFunction("F2L"); if (!func_F2L) { func_F2L = Function::Create( - /*Type=*/FuncTy_32, + /*Type=*/FuncTy_33, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"F2L", mod); // (external, no body) func_F2L->setCallingConv(CallingConv::C); @@ -926,7 +947,7 @@ func_F2L->setAttributes(func_F2L_PAL); Function* func_F2I = mod->getFunction("F2I"); if (!func_F2I) { func_F2I = Function::Create( - /*Type=*/FuncTy_33, + /*Type=*/FuncTy_34, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"F2I", mod); // (external, no body) func_F2I->setCallingConv(CallingConv::C); @@ -948,7 +969,7 @@ func_art_mark_gc_card_from_code->setAttributes(func_art_mark_gc_card_from_code_P Function* func_art_fix_stub_from_code = mod->getFunction("art_fix_stub_from_code"); if (!func_art_fix_stub_from_code) { func_art_fix_stub_from_code = Function::Create( - /*Type=*/FuncTy_34, + /*Type=*/FuncTy_35, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"art_fix_stub_from_code", mod); // (external, no body) func_art_fix_stub_from_code->setCallingConv(CallingConv::C); @@ -959,7 +980,7 @@ func_art_fix_stub_from_code->setAttributes(func_art_fix_stub_from_code_PAL); Function* func_art_proxy_invoke_handler_from_code = mod->getFunction("art_proxy_invoke_handler_from_code"); if (!func_art_proxy_invoke_handler_from_code) { func_art_proxy_invoke_handler_from_code = Function::Create( - /*Type=*/FuncTy_35, + /*Type=*/FuncTy_36, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"art_proxy_invoke_handler_from_code", mod); // (external, no body) func_art_proxy_invoke_handler_from_code->setCallingConv(CallingConv::C); 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)); diff --git a/src/compiler_llvm/runtime_support_func_list.h b/src/compiler_llvm/runtime_support_func_list.h index 7a51b90f89..5cf237401d 100644 --- a/src/compiler_llvm/runtime_support_func_list.h +++ b/src/compiler_llvm/runtime_support_func_list.h @@ -59,6 +59,7 @@ V(Get64Instance, art_get64_instance_from_code) \ V(GetObjectInstance, art_get_obj_instance_from_code) \ V(InitializeStaticStorage, art_initialize_static_storage_from_code) \ + V(FillArrayData, art_fill_array_data_from_code) \ V(IsExceptionPending, art_is_exception_pending_from_code) \ V(FindCatchBlock, art_find_catch_block_from_code) \ V(MarkGCCard, art_mark_gc_card_from_code) \ diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc index bdfd222a44..d0f6e8c7ed 100644 --- a/src/compiler_llvm/runtime_support_llvm.cc +++ b/src/compiler_llvm/runtime_support_llvm.cc @@ -15,6 +15,8 @@ */ #include "class_linker.h" +#include "dex_file.h" +#include "dex_instruction.h" #include "nth_caller_visitor.h" #include "object.h" #include "object_utils.h" @@ -496,6 +498,42 @@ Object* art_decode_jobject_in_thread(Thread* thread, jobject obj) { return thread->DecodeJObject(obj); } +void art_fill_array_data_from_code(Method* method, uint32_t dex_pc, + Array* array, uint32_t payload_offset) { + // Test: Is array equal to null? (Guard NullPointerException) + if (UNLIKELY(array == NULL)) { + art_throw_null_pointer_exception_from_code(dex_pc); + return; + } + + // Find the payload from the CodeItem + MethodHelper mh(method); + const DexFile::CodeItem* code_item = mh.GetCodeItem(); + + DCHECK_GT(code_item->insns_size_in_code_units_, payload_offset); + + const Instruction::ArrayDataPayload* payload = + reinterpret_cast<const Instruction::ArrayDataPayload*>( + code_item->insns_ + payload_offset); + + DCHECK_EQ(payload->ident, + static_cast<uint16_t>(Instruction::kArrayDataSignature)); + + // Test: Is array big enough? + uint32_t array_len = static_cast<uint32_t>(array->GetLength()); + if (UNLIKELY(array_len < payload->element_count)) { + int32_t last_index = payload->element_count - 1; + art_throw_array_bounds_from_code(array_len, last_index); + return; + } + + // Copy the data + size_t size = payload->element_width * payload->element_count; + memcpy(array->GetRawData(payload->element_width), payload->data, size); +} + + + //---------------------------------------------------------------------------- // Type checking, in the nature of casting //---------------------------------------------------------------------------- |