src/share/vm/shark/sharkTopLevelBlock.cpp
Print this page
rev 3810 : [mq]: shark.patch
*** 63,72 ****
--- 63,73 ----
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,117 ****
case Bytecodes::_invokestatic:
case Bytecodes::_invokespecial:
case Bytecodes::_invokevirtual:
case Bytecodes::_invokeinterface:
! method = iter()->get_method(will_link);
assert(will_link, "typeflow responsibility");
if (!method->holder()->is_linked()) {
set_trap(
Deoptimization::make_trap_request(
--- 108,119 ----
case Bytecodes::_invokestatic:
case Bytecodes::_invokespecial:
case Bytecodes::_invokevirtual:
case Bytecodes::_invokeinterface:
! 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,575 ****
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(),
"exception_klass");
for (int i = 0; i < num_options; i++) {
Value *check_klass =
! builder()->CreateInlineOop(exc_handler(i)->catch_klass());
BasicBlock *not_exact = function()->CreateBlock("not_exact");
BasicBlock *not_subtype = function()->CreateBlock("not_subtype");
builder()->CreateCondBr(
--- 562,577 ----
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::klass_type(),
"exception_klass");
for (int i = 0; i < num_options; i++) {
Value *check_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,831 ****
Value *value = builder()->CreateLoad(
builder()->CreateArrayAddress(
array->jarray_value(), basic_type, index->jint_value()));
! const 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:
--- 823,833 ----
Value *value = builder()->CreateLoad(
builder()->CreateArrayAddress(
array->jarray_value(), basic_type, index->jint_value()));
! 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,918 ****
default:
tty->print_cr("Unhandled type %s", type2name(basic_type));
ShouldNotReachHere();
}
! const 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");
--- 910,920 ----
default:
tty->print_cr("Unhandled type %s", type2name(basic_type));
ShouldNotReachHere();
}
! 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,1111 ****
return NULL;
}
Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) {
return builder()->CreateBitCast(
! builder()->CreateInlineOop(method),
! SharkType::Method*_type(),
"callee");
}
Value *SharkTopLevelBlock::get_virtual_callee(SharkValue* receiver,
int vtable_index) {
--- 1102,1113 ----
return NULL;
}
Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) {
return builder()->CreateBitCast(
! builder()->CreateInlineMetadata(method, SharkType::Method_type()),
! SharkType::Method_type(),
"callee");
}
Value *SharkTopLevelBlock::get_virtual_callee(SharkValue* receiver,
int vtable_index) {
*** 1116,1126 ****
"klass");
return builder()->CreateLoad(
builder()->CreateArrayAddress(
klass,
! SharkType::Method*_type(),
vtableEntry::size() * wordSize,
in_ByteSize(InstanceKlass::vtable_start_offset() * wordSize),
LLVMValue::intptr_constant(vtable_index)),
"callee");
}
--- 1118,1128 ----
"klass");
return builder()->CreateLoad(
builder()->CreateArrayAddress(
klass,
! SharkType::Method_type(),
vtableEntry::size() * wordSize,
in_ByteSize(InstanceKlass::vtable_start_offset() * wordSize),
LLVMValue::intptr_constant(vtable_index)),
"callee");
}
*** 1134,1144 ****
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(),
"object_klass");
Value *vtable_start = builder()->CreateAdd(
builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()),
LLVMValue::intptr_constant(
--- 1136,1146 ----
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::klass_type(),
"object_klass");
Value *vtable_start = builder()->CreateAdd(
builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()),
LLVMValue::intptr_constant(
*** 1167,1195 ****
LLVMValue::intptr_constant(~(BytesPerLong - 1)),
"itable_start");
}
// Locate this interface's entry in the table
! Value *iklass = builder()->CreateInlineOop(method->holder());
BasicBlock *loop_entry = builder()->GetInsertBlock();
builder()->CreateBr(loop);
builder()->SetInsertPoint(loop);
PHINode *itable_entry_addr = builder()->CreatePHI(
! SharkType::intptr_type(), "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(),
"itable_iklass");
builder()->CreateCondBr(
! builder()->CreateICmpEQ(itable_iklass, LLVMValue::null()),
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.
--- 1169,1197 ----
LLVMValue::intptr_constant(~(BytesPerLong - 1)),
"itable_start");
}
// Locate this interface's entry in the table
! 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(), 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::klass_type(),
"itable_iklass");
builder()->CreateCondBr(
! 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,1239 ****
offset),
LLVMValue::intptr_constant(
method->itable_index() * itableMethodEntry::size() * wordSize)),
LLVMValue::intptr_constant(
itableMethodEntry::method_offset_in_bytes())),
! PointerType::getUnqual(SharkType::Method*_type())),
"callee");
}
void SharkTopLevelBlock::do_call() {
// Set frequently used booleans
--- 1231,1241 ----
offset),
LLVMValue::intptr_constant(
method->itable_index() * itableMethodEntry::size() * wordSize)),
LLVMValue::intptr_constant(
itableMethodEntry::method_offset_in_bytes())),
! PointerType::getUnqual(SharkType::Method_type())),
"callee");
}
void SharkTopLevelBlock::do_call() {
// Set frequently used booleans
*** 1241,1251 ****
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);
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
--- 1243,1255 ----
bool is_virtual = bc() == Bytecodes::_invokevirtual;
bool is_interface = bc() == Bytecodes::_invokeinterface;
// Find the method being called
bool 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,1270 ****
--- 1261,1281 ----
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,1302 ****
}
// Find the method we are calling
Value *callee;
if (call_is_virtual) {
! if (is_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);
--- 1303,1313 ----
}
// Find the method we are calling
Value *callee;
if (call_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,1503 ****
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);
// Get the class of the object being tested
Value *object_klass = builder()->CreateValueOfStructEntry(
object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
! SharkType::oop_type(),
"object_klass");
// Perform the check
builder()->CreateCondBr(
builder()->CreateICmpEQ(check_klass, object_klass),
--- 1499,1514 ----
merge2, not_null);
BasicBlock *null_block = builder()->GetInsertBlock();
// Get the class we're checking against
builder()->SetInsertPoint(not_null);
! 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::klass_type(),
"object_klass");
// Perform the check
builder()->CreateCondBr(
builder()->CreateICmpEQ(check_klass, object_klass),
*** 1518,1539 ****
builder()->CreateBr(merge1);
// First merge
builder()->SetInsertPoint(merge1);
PHINode *nonnull_result = builder()->CreatePHI(
! SharkType::jint_type(), "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");
result->addIncoming(LLVMValue::jint_constant(IC_IS_NULL), null_block);
result->addIncoming(nonnull_result, nonnull_block);
// Handle the result
if (bc() == Bytecodes::_checkcast) {
--- 1529,1550 ----
builder()->CreateBr(merge1);
// First merge
builder()->SetInsertPoint(merge1);
PHINode *nonnull_result = builder()->CreatePHI(
! 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(), 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,1715 ****
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);
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");
phi->addIncoming(tlab_object, got_tlab);
phi->addIncoming(heap_object, got_heap);
fast_object = phi;
}
else {
--- 1707,1726 ----
builder()->SetInsertPoint(got_heap);
heap_object = builder()->CreateIntToPtr(
old_top, SharkType::oop_type(), "heap_object");
! 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(), 0, "fast_object");
phi->addIncoming(tlab_object, got_tlab);
phi->addIncoming(heap_object, got_heap);
fast_object = phi;
}
else {
*** 1728,1738 ****
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()),
"klass_addr");
// Set the mark
intptr_t mark;
if (UseBiasedLocking) {
--- 1739,1749 ----
PointerType::getUnqual(SharkType::intptr_type()),
"mark_addr");
Value *klass_addr = builder()->CreateAddressOfStructEntry(
fast_object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
! PointerType::getUnqual(SharkType::klass_type()),
"klass_addr");
// Set the mark
intptr_t mark;
if (UseBiasedLocking) {
*** 1742,1752 ****
mark = (intptr_t) markOopDesc::prototype();
}
builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr);
// Set the class
! Value *rtklass = builder()->CreateInlineOop(klass);
builder()->CreateStore(rtklass, klass_addr);
got_fast = builder()->GetInsertBlock();
builder()->CreateBr(push_object);
builder()->SetInsertPoint(slow_alloc_and_init);
--- 1753,1763 ----
mark = (intptr_t) markOopDesc::prototype();
}
builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr);
// Set the class
! 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,1775 ****
if (push_object) {
builder()->CreateBr(push_object);
builder()->SetInsertPoint(push_object);
}
if (fast_object) {
! PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "object");
phi->addIncoming(fast_object, got_fast);
phi->addIncoming(slow_object, got_slow);
object = phi;
current_state()->merge(fast_state, got_fast, got_slow);
}
--- 1776,1786 ----
if (push_object) {
builder()->CreateBr(push_object);
builder()->SetInsertPoint(push_object);
}
if (fast_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,1858 ****
push(SharkValue::create_generic(array_klass, get_vm_result(), true));
}
void SharkTopLevelBlock::acquire_method_lock() {
Value *lockee;
! 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);
--- 1858,1870 ----
push(SharkValue::create_generic(array_klass, get_vm_result(), true));
}
void SharkTopLevelBlock::acquire_method_lock() {
Value *lockee;
! 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,1906 ****
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);
builder()->CreateCondBr(
builder()->CreateICmpEQ(disp, check),
acquired_fast, try_recursive);
// Locking failed, but maybe this thread already owns it
--- 1908,1918 ----
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()->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,1991 ****
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);
builder()->CreateCondBr(
builder()->CreateICmpEQ(lock, check),
released_fast, slow_path);
// Create an edge for the state merge
--- 1993,2003 ----
Value *mark_addr = builder()->CreateAddressOfStructEntry(
lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
PointerType::getUnqual(SharkType::intptr_type()),
"mark_addr");
! 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