Implement MarkGCCard.
Change-Id: Ic004750a303897d33a5459a41ac60ac552926e07
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 153d99a..fa8a827 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -2252,6 +2252,12 @@
}
}
+void MethodCompiler::EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr) {
+ // Using runtime support, let the target can override by InlineAssembly.
+ llvm::Function* runtime_func = irb_.GetRuntime(MarkGCCard);
+
+ irb_.CreateCall2(runtime_func, value, target_addr);
+}
void
MethodCompiler::EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc,
@@ -2354,12 +2360,14 @@
llvm::Value* new_value = EmitLoadDalvikReg(dec_insn.vA, elem_jty, kArray);
- if (elem_jty == kObject) { // If put an object, check the type.
+ if (elem_jty == kObject) { // If put an object, check the type, and mark GC card table.
llvm::Function* runtime_func = irb_.GetRuntime(CheckPutArrayElement);
irb_.CreateCall2(runtime_func, new_value, array_addr);
EmitGuard_ExceptionLandingPad(dex_pc);
+
+ EmitMarkGCCard(new_value, array_addr);
}
irb_.CreateStore(new_value, array_elem_addr);
@@ -2488,6 +2496,10 @@
// TODO: Check is_volatile. We need to generate atomic store instruction
// when is_volatile is true.
irb_.CreateStore(new_value, field_addr);
+
+ if (field_jty == kObject) { // If put an object, mark the GC card table.
+ EmitMarkGCCard(new_value, object_addr);
+ }
}
irb_.CreateBr(GetNextBasicBlock(dex_pc));
@@ -2704,6 +2716,10 @@
// TODO: Check is_volatile. We need to generate atomic store instruction
// when is_volatile is true.
irb_.CreateStore(new_value, static_field_addr);
+
+ if (field_jty == kObject) { // If put an object, mark the GC card table.
+ EmitMarkGCCard(new_value, static_storage_addr);
+ }
}
irb_.CreateBr(GetNextBasicBlock(dex_pc));