src/share/vm/shark/sharkBuilder.cpp
Print this page
rev 3850 : [mq]: shark.patch
@@ -45,18 +45,18 @@
}
// Helpers for accessing structures
Value* SharkBuilder::CreateAddressOfStructEntry(Value* base,
ByteSize offset,
- const Type* type,
+ Type* type,
const char* name) {
return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name);
}
LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base,
ByteSize offset,
- const Type* type,
+ Type* type,
const char* name) {
return CreateLoad(
CreateAddressOfStructEntry(
base, offset, PointerType::getUnqual(type)),
name);
@@ -69,11 +69,11 @@
arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()),
SharkType::jint_type(), "length");
}
Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
- const Type* element_type,
+ Type* element_type,
int element_bytes,
ByteSize base_offset,
Value* index,
const char* name) {
Value* offset = CreateIntCast(index, SharkType::intptr_type(), false);
@@ -112,11 +112,11 @@
index, name);
}
// Helpers for creating intrinsics and external functions.
-const Type* SharkBuilder::make_type(char type, bool void_ok) {
+Type* SharkBuilder::make_type(char type, bool void_ok) {
switch (type) {
// Primitive types
case 'c':
return SharkType::jbyte_type();
case 'i':
@@ -144,10 +144,12 @@
return SharkType::thread_type();
case 'M':
return PointerType::getUnqual(SharkType::monitor_type());
case 'O':
return SharkType::oop_type();
+ case 'K':
+ return SharkType::klass_type();
// Miscellaneous
case 'v':
assert(void_ok, "should be");
return SharkType::void_type();
@@ -157,18 +159,18 @@
default:
ShouldNotReachHere();
}
}
-const FunctionType* SharkBuilder::make_ftype(const char* params,
+FunctionType* SharkBuilder::make_ftype(const char* params,
const char* ret) {
- std::vector<const Type*> param_types;
+ std::vector<Type*> param_types;
for (const char* c = params; *c; c++)
param_types.push_back(make_type(*c, false));
assert(strlen(ret) == 1, "should be");
- const Type *return_type = make_type(*ret, true);
+ Type *return_type = make_type(*ret, true);
return FunctionType::get(return_type, param_types, false);
}
// Create an object representing an intrinsic or external function by
@@ -272,11 +274,11 @@
Value* SharkBuilder::d2l() {
return make_function((address) SharedRuntime::d2l, "d", "l");
}
Value* SharkBuilder::is_subtype_of() {
- return make_function((address) SharkRuntime::is_subtype_of, "OO", "c");
+ return make_function((address) SharkRuntime::is_subtype_of, "KK", "c");
}
Value* SharkBuilder::current_time_millis() {
return make_function((address) os::javaTimeMillis, "", "l");
}
@@ -350,83 +352,30 @@
return make_function(
(address) JavaThread::check_special_condition_for_native_trans,
"T", "v");
}
-// Low-level non-VM calls
-
-// The ARM-specific code here is to work around unimplemented
-// atomic exchange and memory barrier intrinsics in LLVM.
-//
-// Delegating to external functions for these would normally
-// incur a speed penalty, but Linux on ARM is a special case
-// in that atomic operations on that platform are handled by
-// external functions anyway. It would be *preferable* for
-// the calls to be hidden away in LLVM, but it's not hurting
-// performance so having the calls here is acceptable.
-//
-// If you are building Shark on a platform without atomic
-// exchange and/or memory barrier intrinsics then it is only
-// acceptable to mimic this approach if your platform cannot
-// perform these operations without delegating to a function.
-
-#ifdef ARM
-static jint zero_cmpxchg_int(volatile jint *ptr, jint oldval, jint newval) {
- return Atomic::cmpxchg(newval, ptr, oldval);
-}
-#endif // ARM
-
-Value* SharkBuilder::cmpxchg_int() {
- return make_function(
-#ifdef ARM
- (address) zero_cmpxchg_int,
-#else
- "llvm.atomic.cmp.swap.i32.p0i32",
-#endif // ARM
- "Iii", "i");
-}
-
-#ifdef ARM
-static intptr_t zero_cmpxchg_ptr(volatile intptr_t* ptr,
- intptr_t oldval,
- intptr_t newval) {
- return Atomic::cmpxchg_ptr(newval, ptr, oldval);
-}
-#endif // ARM
-
-Value* SharkBuilder::cmpxchg_ptr() {
- return make_function(
-#ifdef ARM
- (address) zero_cmpxchg_ptr,
-#else
- "llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32") ".p0i" LP64_ONLY("64") NOT_LP64("32"),
-#endif // ARM
- "Xxx", "x");
-}
-
Value* SharkBuilder::frame_address() {
return make_function("llvm.frameaddress", "i", "C");
}
+#if SHARK_LLVM_VERSION <= 31
Value* SharkBuilder::memory_barrier() {
return make_function(
#ifdef ARM
(address) 0xffff0fa0, // __kernel_dmb
#else
"llvm.memory.barrier",
#endif // ARM
"11111", "v");
}
+#endif
Value* SharkBuilder::memset() {
-#if SHARK_LLVM_VERSION >= 28
// LLVM 2.8 added a fifth isVolatile field for memset
// introduced with LLVM r100304
- return make_function("llvm.memset.i32", "Cciii", "v");
-#else
- return make_function("llvm.memset.i32", "Ccii", "v");
-#endif
+ return make_function("llvm.memset.p0i8.i32", "Cciii", "v");
}
Value* SharkBuilder::unimplemented() {
return make_function((address) report_unimplemented, "Ci", "v");
}
@@ -439,47 +388,33 @@
return make_function((address) SharkRuntime::dump, "Cx", "v");
}
// Public interface to low-level non-VM calls
-CallInst* SharkBuilder::CreateCmpxchgInt(Value* exchange_value,
- Value* dst,
- Value* compare_value) {
- return CreateCall3(cmpxchg_int(), dst, compare_value, exchange_value);
-}
-
-CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value,
- Value* dst,
- Value* compare_value) {
- return CreateCall3(cmpxchg_ptr(), dst, compare_value, exchange_value);
-}
-
CallInst* SharkBuilder::CreateGetFrameAddress() {
return CreateCall(frame_address(), LLVMValue::jint_constant(0));
}
-CallInst *SharkBuilder::CreateMemoryBarrier(int flags) {
+#if SHARK_LLVM_VERSION <= 31
+CallInst* SharkBuilder::CreateMemoryBarrier(int flags) {
Value *args[] = {
LLVMValue::bit_constant((flags & BARRIER_LOADLOAD) ? 1 : 0),
LLVMValue::bit_constant((flags & BARRIER_LOADSTORE) ? 1 : 0),
LLVMValue::bit_constant((flags & BARRIER_STORELOAD) ? 1 : 0),
LLVMValue::bit_constant((flags & BARRIER_STORESTORE) ? 1 : 0),
LLVMValue::bit_constant(1)};
- return CreateCall(memory_barrier(), args, args + 5);
+ return CreateCall(memory_barrier(), llvm::makeArrayRef(args, args + 5));
}
+#endif
CallInst* SharkBuilder::CreateMemset(Value* dst,
Value* value,
Value* len,
Value* align) {
-#if SHARK_LLVM_VERSION >= 28
return CreateCall5(memset(), dst, value, len, align,
LLVMValue::jint_constant(0));
-#else
- return CreateCall4(memset(), dst, value, len, align);
-#endif
}
CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) {
return CreateCall2(
unimplemented(),
@@ -508,15 +443,11 @@
name = "unnamed_value";
if (isa<PointerType>(value->getType()))
value = CreatePtrToInt(value, SharkType::intptr_type());
else if (value->getType()->
-#if SHARK_LLVM_VERSION >= 27
isIntegerTy()
-#else
- isInteger()
-#endif
)
value = CreateIntCast(value, SharkType::intptr_type(), false);
else
Unimplemented();
@@ -561,13 +492,23 @@
code_buffer_address(code_buffer()->inline_oop(object)),
PointerType::getUnqual(SharkType::oop_type())),
name);
}
+Value* SharkBuilder::CreateInlineMetadata(Metadata* metadata, llvm::PointerType* type, const char* name) {
+ assert(metadata != NULL, "inlined metadata must not be NULL");
+ assert(metadata->is_metadata(), "sanity check");
+ return CreateLoad(
+ CreateIntToPtr(
+ code_buffer_address(code_buffer()->inline_Metadata(metadata)),
+ PointerType::getUnqual(type)),
+ name);
+}
+
Value* SharkBuilder::CreateInlineData(void* data,
size_t size,
- const Type* type,
+ Type* type,
const char* name) {
return CreateIntToPtr(
code_buffer_address(code_buffer()->inline_data(data, size)),
type,
name);
@@ -598,5 +539,13 @@
BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const {
return BasicBlock::Create(
SharkContext::current(), name, GetInsertBlock()->getParent(), ip);
}
+
+LoadInst* SharkBuilder::CreateAtomicLoad(Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) {
+ return Insert(new LoadInst(ptr, name, isVolatile, align, ordering, synchScope), name);
+}
+
+StoreInst* SharkBuilder::CreateAtomicStore(Value* val, Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) {
+ return Insert(new StoreInst(val, ptr, isVolatile, align, ordering, synchScope), name);
+}