src/share/vm/shark/sharkTopLevelBlock.cpp
Print this page
rev 3850 : [mq]: shark.patch
@@ -63,10 +63,11 @@
bool is_field;
switch (bc()) {
case Bytecodes::_ldc:
case Bytecodes::_ldc_w:
+ case Bytecodes::_ldc2_w:
if (!SharkConstant::for_ldc(iter())->is_loaded()) {
set_trap(
Deoptimization::make_trap_request(
Deoptimization::Reason_uninitialized,
Deoptimization::Action_reinterpret), bci());
@@ -107,11 +108,12 @@
case Bytecodes::_invokestatic:
case Bytecodes::_invokespecial:
case Bytecodes::_invokevirtual:
case Bytecodes::_invokeinterface:
- method = iter()->get_method(will_link);
+ ciSignature* sig;
+ method = iter()->get_method(will_link, &sig);
assert(will_link, "typeflow responsibility");
if (!method->holder()->is_linked()) {
set_trap(
Deoptimization::make_trap_request(
@@ -560,16 +562,16 @@
void SharkTopLevelBlock::marshal_exception_fast(int num_options) {
Value *exception_klass = builder()->CreateValueOfStructEntry(
xstack(0)->jobject_value(),
in_ByteSize(oopDesc::klass_offset_in_bytes()),
- SharkType::oop_type(),
+ SharkType::klass_type(),
"exception_klass");
for (int i = 0; i < num_options; i++) {
Value *check_klass =
- builder()->CreateInlineOop(exc_handler(i)->catch_klass());
+ builder()->CreateInlineMetadata(exc_handler(i)->catch_klass(), SharkType::klass_type());
BasicBlock *not_exact = function()->CreateBlock("not_exact");
BasicBlock *not_subtype = function()->CreateBlock("not_subtype");
builder()->CreateCondBr(
@@ -821,11 +823,11 @@
Value *value = builder()->CreateLoad(
builder()->CreateArrayAddress(
array->jarray_value(), basic_type, index->jint_value()));
- const Type *stack_type = SharkType::to_stackType(basic_type);
+ Type *stack_type = SharkType::to_stackType(basic_type);
if (value->getType() != stack_type)
value = builder()->CreateIntCast(value, stack_type, basic_type != T_CHAR);
switch (basic_type) {
case T_BYTE:
@@ -908,11 +910,11 @@
default:
tty->print_cr("Unhandled type %s", type2name(basic_type));
ShouldNotReachHere();
}
- const Type *array_type = SharkType::to_arrayType(basic_type);
+ Type *array_type = SharkType::to_arrayType(basic_type);
if (value->getType() != array_type)
value = builder()->CreateIntCast(value, array_type, basic_type != T_CHAR);
Value *addr = builder()->CreateArrayAddress(
array->jarray_value(), basic_type, index->jint_value(), "addr");
@@ -1100,12 +1102,12 @@
return NULL;
}
Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) {
return builder()->CreateBitCast(
- builder()->CreateInlineOop(method),
- SharkType::Method*_type(),
+ builder()->CreateInlineMetadata(method, SharkType::Method_type()),
+ SharkType::Method_type(),
"callee");
}
Value *SharkTopLevelBlock::get_virtual_callee(SharkValue* receiver,
int vtable_index) {
@@ -1116,11 +1118,11 @@
"klass");
return builder()->CreateLoad(
builder()->CreateArrayAddress(
klass,
- SharkType::Method*_type(),
+ SharkType::Method_type(),
vtableEntry::size() * wordSize,
in_ByteSize(InstanceKlass::vtable_start_offset() * wordSize),
LLVMValue::intptr_constant(vtable_index)),
"callee");
}
@@ -1134,11 +1136,11 @@
BasicBlock *got_entry = function()->CreateBlock("got_entry");
// Locate the receiver's itable
Value *object_klass = builder()->CreateValueOfStructEntry(
receiver->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()),
- SharkType::oop_type(),
+ SharkType::klass_type(),
"object_klass");
Value *vtable_start = builder()->CreateAdd(
builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()),
LLVMValue::intptr_constant(
@@ -1167,29 +1169,29 @@
LLVMValue::intptr_constant(~(BytesPerLong - 1)),
"itable_start");
}
// Locate this interface's entry in the table
- Value *iklass = builder()->CreateInlineOop(method->holder());
+ Value *iklass = builder()->CreateInlineMetadata(method->holder(), SharkType::klass_type());
BasicBlock *loop_entry = builder()->GetInsertBlock();
builder()->CreateBr(loop);
builder()->SetInsertPoint(loop);
PHINode *itable_entry_addr = builder()->CreatePHI(
- SharkType::intptr_type(), "itable_entry_addr");
+ SharkType::intptr_type(), 0, "itable_entry_addr");
itable_entry_addr->addIncoming(itable_start, loop_entry);
Value *itable_entry = builder()->CreateIntToPtr(
itable_entry_addr, SharkType::itableOffsetEntry_type(), "itable_entry");
Value *itable_iklass = builder()->CreateValueOfStructEntry(
itable_entry,
in_ByteSize(itableOffsetEntry::interface_offset_in_bytes()),
- SharkType::oop_type(),
+ SharkType::klass_type(),
"itable_iklass");
builder()->CreateCondBr(
- builder()->CreateICmpEQ(itable_iklass, LLVMValue::null()),
+ builder()->CreateICmpEQ(itable_iklass, LLVMValue::nullKlass()),
got_null, not_null);
// A null entry means that the class doesn't implement the
// interface, and wasn't the same as the class checked when
// the interface was resolved.
@@ -1229,11 +1231,11 @@
offset),
LLVMValue::intptr_constant(
method->itable_index() * itableMethodEntry::size() * wordSize)),
LLVMValue::intptr_constant(
itableMethodEntry::method_offset_in_bytes())),
- PointerType::getUnqual(SharkType::Method*_type())),
+ PointerType::getUnqual(SharkType::Method_type())),
"callee");
}
void SharkTopLevelBlock::do_call() {
// Set frequently used booleans
@@ -1241,11 +1243,13 @@
bool is_virtual = bc() == Bytecodes::_invokevirtual;
bool is_interface = bc() == Bytecodes::_invokeinterface;
// Find the method being called
bool will_link;
- ciMethod *dest_method = iter()->get_method(will_link);
+ ciSignature* sig;
+ ciMethod *dest_method = iter()->get_method(will_link, &sig);
+
assert(will_link, "typeflow responsibility");
assert(dest_method->is_static() == is_static, "must match bc");
// Find the class of the method being called. Note
// that the superclass check in the second assertion
@@ -1257,14 +1261,21 @@
ciInstanceKlass *holder_klass = dest_method->holder();
assert(holder_klass->is_loaded(), "scan_for_traps responsibility");
assert(holder_klass->is_interface() ||
holder_klass->super() == NULL ||
!is_interface, "must match bc");
+
+ bool is_forced_virtual = is_interface && holder_klass == java_lang_Object_klass();
+
ciKlass *holder = iter()->get_declared_method_holder();
ciInstanceKlass *klass =
ciEnv::get_instance_klass_for_declared_method_holder(holder);
+ if (is_forced_virtual) {
+ klass = java_lang_Object_klass();
+ }
+
// Find the receiver in the stack. We do this before
// trying to inline because the inliner can only use
// zero-checked values, not being able to perform the
// check itself.
SharkValue *receiver = NULL;
@@ -1292,11 +1303,11 @@
}
// Find the method we are calling
Value *callee;
if (call_is_virtual) {
- if (is_virtual) {
+ if (is_virtual || is_forced_virtual) {
assert(klass->is_linked(), "scan_for_traps responsibility");
int vtable_index = call_method->resolve_vtable_index(
target()->holder(), klass);
assert(vtable_index >= 0, "should be");
callee = get_virtual_callee(receiver, vtable_index);
@@ -1488,16 +1499,16 @@
merge2, not_null);
BasicBlock *null_block = builder()->GetInsertBlock();
// Get the class we're checking against
builder()->SetInsertPoint(not_null);
- Value *check_klass = builder()->CreateInlineOop(klass);
+ Value *check_klass = builder()->CreateInlineMetadata(klass, SharkType::klass_type());
// Get the class of the object being tested
Value *object_klass = builder()->CreateValueOfStructEntry(
object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
- SharkType::oop_type(),
+ SharkType::klass_type(),
"object_klass");
// Perform the check
builder()->CreateCondBr(
builder()->CreateICmpEQ(check_klass, object_klass),
@@ -1518,22 +1529,22 @@
builder()->CreateBr(merge1);
// First merge
builder()->SetInsertPoint(merge1);
PHINode *nonnull_result = builder()->CreatePHI(
- SharkType::jint_type(), "nonnull_result");
+ SharkType::jint_type(), 0, "nonnull_result");
nonnull_result->addIncoming(
LLVMValue::jint_constant(IC_IS_INSTANCE), is_instance);
nonnull_result->addIncoming(
LLVMValue::jint_constant(IC_NOT_INSTANCE), not_instance);
BasicBlock *nonnull_block = builder()->GetInsertBlock();
builder()->CreateBr(merge2);
// Second merge
builder()->SetInsertPoint(merge2);
PHINode *result = builder()->CreatePHI(
- SharkType::jint_type(), "result");
+ SharkType::jint_type(), 0, "result");
result->addIncoming(LLVMValue::jint_constant(IC_IS_NULL), null_block);
result->addIncoming(nonnull_result, nonnull_block);
// Handle the result
if (bc() == Bytecodes::_checkcast) {
@@ -1696,20 +1707,20 @@
builder()->SetInsertPoint(got_heap);
heap_object = builder()->CreateIntToPtr(
old_top, SharkType::oop_type(), "heap_object");
- Value *check = builder()->CreateCmpxchgPtr(new_top, top_addr, old_top);
+ Value *check = builder()->CreateAtomicCmpXchg(top_addr, old_top, new_top, llvm::SequentiallyConsistent);
builder()->CreateCondBr(
builder()->CreateICmpEQ(old_top, check),
initialize, retry);
// Initialize the object
builder()->SetInsertPoint(initialize);
if (tlab_object) {
PHINode *phi = builder()->CreatePHI(
- SharkType::oop_type(), "fast_object");
+ SharkType::oop_type(), 0, "fast_object");
phi->addIncoming(tlab_object, got_tlab);
phi->addIncoming(heap_object, got_heap);
fast_object = phi;
}
else {
@@ -1728,11 +1739,11 @@
PointerType::getUnqual(SharkType::intptr_type()),
"mark_addr");
Value *klass_addr = builder()->CreateAddressOfStructEntry(
fast_object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
- PointerType::getUnqual(SharkType::oop_type()),
+ PointerType::getUnqual(SharkType::klass_type()),
"klass_addr");
// Set the mark
intptr_t mark;
if (UseBiasedLocking) {
@@ -1742,11 +1753,11 @@
mark = (intptr_t) markOopDesc::prototype();
}
builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr);
// Set the class
- Value *rtklass = builder()->CreateInlineOop(klass);
+ Value *rtklass = builder()->CreateInlineMetadata(klass, SharkType::klass_type());
builder()->CreateStore(rtklass, klass_addr);
got_fast = builder()->GetInsertBlock();
builder()->CreateBr(push_object);
builder()->SetInsertPoint(slow_alloc_and_init);
@@ -1765,11 +1776,11 @@
if (push_object) {
builder()->CreateBr(push_object);
builder()->SetInsertPoint(push_object);
}
if (fast_object) {
- PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "object");
+ PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "object");
phi->addIncoming(fast_object, got_fast);
phi->addIncoming(slow_object, got_slow);
object = phi;
current_state()->merge(fast_state, got_fast, got_slow);
}
@@ -1847,12 +1858,13 @@
push(SharkValue::create_generic(array_klass, get_vm_result(), true));
}
void SharkTopLevelBlock::acquire_method_lock() {
Value *lockee;
- if (target()->is_static())
+ if (target()->is_static()) {
lockee = builder()->CreateInlineOop(target()->holder()->java_mirror());
+ }
else
lockee = local(0)->jobject_value();
iter()->force_bci(start()); // for the decache in acquire_lock
acquire_lock(lockee, EX_CHECK_NO_CATCH);
@@ -1896,11 +1908,11 @@
mark, LLVMValue::intptr_constant(markOopDesc::unlocked_value), "disp");
builder()->CreateStore(disp, monitor_header_addr);
Value *lock = builder()->CreatePtrToInt(
monitor_header_addr, SharkType::intptr_type());
- Value *check = builder()->CreateCmpxchgPtr(lock, mark_addr, disp);
+ Value *check = builder()->CreateAtomicCmpXchg(mark_addr, disp, lock, llvm::Acquire);
builder()->CreateCondBr(
builder()->CreateICmpEQ(disp, check),
acquired_fast, try_recursive);
// Locking failed, but maybe this thread already owns it
@@ -1981,11 +1993,11 @@
Value *mark_addr = builder()->CreateAddressOfStructEntry(
lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
PointerType::getUnqual(SharkType::intptr_type()),
"mark_addr");
- Value *check = builder()->CreateCmpxchgPtr(disp, mark_addr, lock);
+ Value *check = builder()->CreateAtomicCmpXchg(mark_addr, lock, disp, llvm::Release);
builder()->CreateCondBr(
builder()->CreateICmpEQ(lock, check),
released_fast, slow_path);
// Create an edge for the state merge