Inline monitor-enter in portable.
Bug: 8195271
Inline monitor-enter fast path in the portable. It only deals with the simplest
case where no one is holding the monitor. It preserves the hash state of the
monitor and atomically updates the owner using "cmpxchg" atomic instruction.
This is now the default behavior in portable. However, there is still custom
code for ARM Thumb2 target (using inline asm) which is synchronized with the
Quick compiler (see compiler_llvm/runtime_support_builder_thumb2.cc).
It is not tested since portable does not work yet for x86 or mips. I verified
the output bitcode using "dex2oat --bitcode" command line option and I compiled
the bitcode with llc using the same options the portable compiler uses to
configure the target and the pass manager.
Change-Id: I96dcc04cc5dfe0aee1a4eb489e4a6f36740cea38
diff --git a/src/compiler_llvm/ir_builder.h b/src/compiler_llvm/ir_builder.h
index 4a58515..60a0f2a 100644
--- a/src/compiler_llvm/ir_builder.h
+++ b/src/compiler_llvm/ir_builder.h
@@ -65,6 +65,15 @@
return inst;
}
+ llvm::AtomicCmpXchgInst*
+ CreateAtomicCmpXchgInst(llvm::Value* ptr, llvm::Value* cmp, llvm::Value* val,
+ llvm::MDNode* tbaa_info) {
+ llvm::AtomicCmpXchgInst* inst =
+ LLVMIRBuilder::CreateAtomicCmpXchg(ptr, cmp, val, llvm::Acquire);
+ inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
+ return inst;
+ }
+
//--------------------------------------------------------------------------
// TBAA
@@ -120,6 +129,17 @@
StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
}
+ llvm::AtomicCmpXchgInst*
+ CompareExchangeObjectOffset(llvm::Value* object_addr,
+ int64_t offset,
+ llvm::Value* cmp_value,
+ llvm::Value* new_value,
+ TBAASpecialType special_ty) {
+ DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
+ return CompareExchangeObjectOffset(object_addr, offset, cmp_value, new_value,
+ mdb_.GetTBAASpecialType(special_ty));
+ }
+
void SetTBAA(llvm::Instruction* inst, TBAASpecialType special_ty) {
inst->setMetadata(llvm::LLVMContext::MD_tbaa, mdb_.GetTBAASpecialType(special_ty));
}
@@ -210,6 +230,21 @@
CreateStore(new_value, value_addr, tbaa_info);
}
+ llvm::AtomicCmpXchgInst* CompareExchangeObjectOffset(llvm::Value* object_addr,
+ int64_t offset,
+ llvm::Value* cmp_value,
+ llvm::Value* new_value,
+ llvm::MDNode* tbaa_info) {
+ // Convert offset to llvm::value
+ llvm::Value* llvm_offset = getPtrEquivInt(offset);
+ // Calculate the value's address
+ llvm::Value* value_addr = CreatePtrDisp(object_addr,
+ llvm_offset,
+ new_value->getType()->getPointerTo());
+ // Atomic compare and exchange
+ return CreateAtomicCmpXchgInst(value_addr, cmp_value, new_value, tbaa_info);
+ }
+
//--------------------------------------------------------------------------
// Runtime Helper Function