Merge "Change to implement fill-array-data with runtime function." into ics-mr1-plus-art
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll
index 6d4b56b..a2da2b6 100644
--- a/src/compiler_llvm/art_module.ll
+++ b/src/compiler_llvm/art_module.ll
@@ -144,6 +144,10 @@
%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 1237ec0..b3963ef 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 2c0fef1..e444811 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -1893,65 +1893,31 @@
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 7a51b90..5cf2374 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 bdfd222..d0f6e8c 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 @@
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
//----------------------------------------------------------------------------