Fix IGET/IPUT slow path code generation.
Two bugs are fixed in this commit:
1. IGET instructions is calling Set*Instance runtime
function, which should be changed to Get*Instance.
2. We should pass the object address to the runtime
function for IGET and IPUT.
Change-Id: I10c317e5c2d093966d8a0f2fd422f9bb5d2b34ba
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll
index 4ac2916..274d575 100644
--- a/src/compiler_llvm/art_module.ll
+++ b/src/compiler_llvm/art_module.ll
@@ -101,13 +101,32 @@
declare i64 @art_get64_static_from_code(i32, %JavaObject*)
declare %JavaObject* @art_get_obj_static_from_code(i32, %JavaObject*)
-declare i32 @art_set32_instance_from_code(i32, %JavaObject*, i32)
-declare i32 @art_set64_instance_from_code(i32, %JavaObject*, i64)
-declare i32 @art_set_obj_instance_from_code(i32, %JavaObject*, %JavaObject*)
+declare i32 @art_set32_instance_from_code(i32,
+ %JavaObject*,
+ %JavaObject*,
+ i32)
-declare i32 @art_get32_instance_from_code(i32, %JavaObject*)
-declare i64 @art_get64_instance_from_code(i32, %JavaObject*)
-declare %JavaObject* @art_get_obj_instance_from_code(i32, %JavaObject*)
+declare i32 @art_set64_instance_from_code(i32,
+ %JavaObject*,
+ %JavaObject*,
+ i64)
+
+declare i32 @art_set_obj_instance_from_code(i32,
+ %JavaObject*,
+ %JavaObject*,
+ %JavaObject*)
+
+declare i32 @art_get32_instance_from_code(i32,
+ %JavaObject*,
+ %JavaObject*)
+
+declare i64 @art_get64_instance_from_code(i32,
+ %JavaObject*,
+ %JavaObject*)
+
+declare %JavaObject* @art_get_obj_instance_from_code(i32,
+ %JavaObject*,
+ %JavaObject*)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/src/compiler_llvm/generated/art_module.cc b/src/compiler_llvm/generated/art_module.cc
index a58e62d..22a12fa 100644
--- a/src/compiler_llvm/generated/art_module.cc
+++ b/src/compiler_llvm/generated/art_module.cc
@@ -193,21 +193,69 @@
/*isVarArg=*/false);
std::vector<Type*>FuncTy_20_args;
+FuncTy_20_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_20_args.push_back(PointerTy_1);
FuncTy_20_args.push_back(PointerTy_1);
+FuncTy_20_args.push_back(IntegerType::get(mod->getContext(), 32));
FunctionType* FuncTy_20 = FunctionType::get(
/*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_20_args,
/*isVarArg=*/false);
std::vector<Type*>FuncTy_21_args;
+FuncTy_21_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_21_args.push_back(PointerTy_1);
FuncTy_21_args.push_back(PointerTy_1);
+FuncTy_21_args.push_back(IntegerType::get(mod->getContext(), 64));
FunctionType* FuncTy_21 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
+ /*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_21_args,
/*isVarArg=*/false);
+std::vector<Type*>FuncTy_22_args;
+FuncTy_22_args.push_back(IntegerType::get(mod->getContext(), 32));
+FuncTy_22_args.push_back(PointerTy_1);
+FuncTy_22_args.push_back(PointerTy_1);
+FuncTy_22_args.push_back(PointerTy_1);
+FunctionType* FuncTy_22 = FunctionType::get(
+ /*Result=*/IntegerType::get(mod->getContext(), 32),
+ /*Params=*/FuncTy_22_args,
+ /*isVarArg=*/false);
+
+std::vector<Type*>FuncTy_23_args;
+FuncTy_23_args.push_back(IntegerType::get(mod->getContext(), 32));
+FuncTy_23_args.push_back(PointerTy_1);
+FuncTy_23_args.push_back(PointerTy_1);
+FunctionType* FuncTy_23 = FunctionType::get(
+ /*Result=*/IntegerType::get(mod->getContext(), 64),
+ /*Params=*/FuncTy_23_args,
+ /*isVarArg=*/false);
+
+std::vector<Type*>FuncTy_24_args;
+FuncTy_24_args.push_back(IntegerType::get(mod->getContext(), 32));
+FuncTy_24_args.push_back(PointerTy_1);
+FuncTy_24_args.push_back(PointerTy_1);
+FunctionType* FuncTy_24 = FunctionType::get(
+ /*Result=*/PointerTy_1,
+ /*Params=*/FuncTy_24_args,
+ /*isVarArg=*/false);
+
+std::vector<Type*>FuncTy_25_args;
+FuncTy_25_args.push_back(PointerTy_1);
+FuncTy_25_args.push_back(PointerTy_1);
+FunctionType* FuncTy_25 = FunctionType::get(
+ /*Result=*/IntegerType::get(mod->getContext(), 32),
+ /*Params=*/FuncTy_25_args,
+ /*isVarArg=*/false);
+
+std::vector<Type*>FuncTy_26_args;
+FuncTy_26_args.push_back(PointerTy_1);
+FuncTy_26_args.push_back(PointerTy_1);
+FunctionType* FuncTy_26 = FunctionType::get(
+ /*Result=*/Type::getVoidTy(mod->getContext()),
+ /*Params=*/FuncTy_26_args,
+ /*isVarArg=*/false);
+
// Function Declarations
@@ -599,7 +647,7 @@
Function* func_art_set32_instance_from_code = mod->getFunction("art_set32_instance_from_code");
if (!func_art_set32_instance_from_code) {
func_art_set32_instance_from_code = Function::Create(
- /*Type=*/FuncTy_15,
+ /*Type=*/FuncTy_20,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_set32_instance_from_code", mod); // (external, no body)
func_art_set32_instance_from_code->setCallingConv(CallingConv::C);
@@ -610,7 +658,7 @@
Function* func_art_set64_instance_from_code = mod->getFunction("art_set64_instance_from_code");
if (!func_art_set64_instance_from_code) {
func_art_set64_instance_from_code = Function::Create(
- /*Type=*/FuncTy_16,
+ /*Type=*/FuncTy_21,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_set64_instance_from_code", mod); // (external, no body)
func_art_set64_instance_from_code->setCallingConv(CallingConv::C);
@@ -621,7 +669,7 @@
Function* func_art_set_obj_instance_from_code = mod->getFunction("art_set_obj_instance_from_code");
if (!func_art_set_obj_instance_from_code) {
func_art_set_obj_instance_from_code = Function::Create(
- /*Type=*/FuncTy_17,
+ /*Type=*/FuncTy_22,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_set_obj_instance_from_code", mod); // (external, no body)
func_art_set_obj_instance_from_code->setCallingConv(CallingConv::C);
@@ -632,7 +680,7 @@
Function* func_art_get32_instance_from_code = mod->getFunction("art_get32_instance_from_code");
if (!func_art_get32_instance_from_code) {
func_art_get32_instance_from_code = Function::Create(
- /*Type=*/FuncTy_18,
+ /*Type=*/FuncTy_17,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_get32_instance_from_code", mod); // (external, no body)
func_art_get32_instance_from_code->setCallingConv(CallingConv::C);
@@ -643,7 +691,7 @@
Function* func_art_get64_instance_from_code = mod->getFunction("art_get64_instance_from_code");
if (!func_art_get64_instance_from_code) {
func_art_get64_instance_from_code = Function::Create(
- /*Type=*/FuncTy_19,
+ /*Type=*/FuncTy_23,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_get64_instance_from_code", mod); // (external, no body)
func_art_get64_instance_from_code->setCallingConv(CallingConv::C);
@@ -654,7 +702,7 @@
Function* func_art_get_obj_instance_from_code = mod->getFunction("art_get_obj_instance_from_code");
if (!func_art_get_obj_instance_from_code) {
func_art_get_obj_instance_from_code = Function::Create(
- /*Type=*/FuncTy_11,
+ /*Type=*/FuncTy_24,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_get_obj_instance_from_code", mod); // (external, no body)
func_art_get_obj_instance_from_code->setCallingConv(CallingConv::C);
@@ -665,7 +713,7 @@
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_20,
+ /*Type=*/FuncTy_25,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_is_assignable_from_code", mod); // (external, no body)
func_art_is_assignable_from_code->setCallingConv(CallingConv::C);
@@ -676,7 +724,7 @@
Function* func_art_check_cast_from_code = mod->getFunction("art_check_cast_from_code");
if (!func_art_check_cast_from_code) {
func_art_check_cast_from_code = Function::Create(
- /*Type=*/FuncTy_21,
+ /*Type=*/FuncTy_26,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_check_cast_from_code", mod); // (external, no body)
func_art_check_cast_from_code->setCallingConv(CallingConv::C);
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 3af60f4..4694777 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -2305,11 +2305,11 @@
llvm::Function* runtime_func;
if (field_jty == kObject) {
- runtime_func = irb_.GetRuntime(SetObjectInstance);
+ runtime_func = irb_.GetRuntime(GetObjectInstance);
} else if (field_jty == kLong || field_jty == kDouble) {
- runtime_func = irb_.GetRuntime(Set64Instance);
+ runtime_func = irb_.GetRuntime(Get64Instance);
} else {
- runtime_func = irb_.GetRuntime(Set32Instance);
+ runtime_func = irb_.GetRuntime(Get32Instance);
}
llvm::ConstantInt* field_idx_value = irb_.getInt32(field_idx);
@@ -2318,8 +2318,8 @@
EmitUpdateLineNumFromDexPC(dex_pc);
- field_value = irb_.CreateCall2(runtime_func, field_idx_value,
- method_object_addr);
+ field_value = irb_.CreateCall3(runtime_func, field_idx_value,
+ method_object_addr, object_addr);
EmitGuard_ExceptionLandingPad(dex_pc);
@@ -2378,8 +2378,8 @@
EmitUpdateLineNumFromDexPC(dex_pc);
- irb_.CreateCall3(runtime_func, field_idx_value,
- method_object_addr, new_value);
+ irb_.CreateCall4(runtime_func, field_idx_value,
+ method_object_addr, object_addr, new_value);
EmitGuard_ExceptionLandingPad(dex_pc);