src/cpu/x86/vm/templateTable_x86_64.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Oct 22 18:35:31 2009
--- new/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Oct 22 18:35:31 2009
*** 201,222 ****
--- 201,219 ----
__ movzbl(scratch, at_bcp(0));
__ cmpl(scratch, Bytecodes::_breakpoint);
__ jcc(Assembler::notEqual, fast_patch);
__ get_method(scratch);
// Let breakpoint table handling rewrite to quicker bytecode
! __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, r13, bc);
CAST_FROM_FN_PTR(address,
InterpreterRuntime::set_original_bytecode_at),
scratch, r13, bc);
#ifndef ASSERT
__ jmpb(patch_done);
__ bind(fast_patch);
}
#else
__ jmp(patch_done);
+ #endif
__ bind(fast_patch);
}
+ #ifdef ASSERT
Label okay;
__ load_unsigned_byte(scratch, at_bcp(0));
__ cmpl(scratch, (int) Bytecodes::java_code(bytecode));
__ jcc(Assembler::equal, okay);
__ cmpl(scratch, bc);
*** 2052,2081 ****
--- 2049,2080 ----
if (os::is_MP()) { // Not needed on single CPU
__ membar(order_constraint);
}
}
! void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) {
Register Rcache,
Register index) {
assert(byte_no == 1 || byte_no == 2, "byte_no out of range");
+ bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic);
const Register temp = rbx;
assert_different_registers(Rcache, index, temp);
const int shift_count = (1 + byte_no) * BitsPerByte;
Label resolved;
! __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
__ movl(temp, Address(Rcache,
index, Address::times_8,
constantPoolCacheOopDesc::base_offset() +
! ConstantPoolCacheEntry::indices_offset()));
+ if (is_invokedynamic) {
+ // we are resolved if the f1 field contains a non-null CallSite object
+ __ cmpptr(Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()), (int32_t) NULL_WORD);
! __ jcc(Assembler::notEqual, resolved);
+ } else {
+ __ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
__ shrl(temp, shift_count);
// have we resolved this bytecode?
__ andl(temp, 0xFF);
__ cmpl(temp, (int) bytecode());
__ jcc(Assembler::equal, resolved);
+ }
// resolve first time through
address entry;
switch (bytecode()) {
case Bytecodes::_getstatic:
*** 2088,2106 ****
--- 2087,2108 ----
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic:
case Bytecodes::_invokeinterface:
entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
break;
+ case Bytecodes::_invokedynamic:
+ entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
+ break;
default:
ShouldNotReachHere();
break;
}
__ movl(temp, (int) bytecode());
__ call_VM(noreg, entry, temp);
// Update registers with resolved info
! __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
__ bind(resolved);
}
// The Rcache and index registers must be set before call
void TemplateTable::load_field_cp_cache_entry(Register obj,
*** 2830,2848 ****
--- 2832,2849 ----
void TemplateTable::count_calls(Register method, Register temp) {
// implemented elsewhere
ShouldNotReachHere();
}
! void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
Register index,
int byte_no,
Bytecodes::Code code) {
// determine flags
+ Bytecodes::Code code = bytecode();
const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
+ const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
const bool is_invokespecial = code == Bytecodes::_invokespecial;
! const bool load_receiver = code != Bytecodes::_invokestatic;
! const bool load_receiver = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic);
const bool receiver_null_check = is_invokespecial;
const bool save_flags = is_invokeinterface || is_invokevirtual;
// setup registers & access constant pool cache
const Register recv = rcx;
const Register flags = rdx;
*** 2856,2869 ****
--- 2857,2874 ----
// load receiver if needed (note: no return address pushed yet)
if (load_receiver) {
__ movl(recv, flags);
__ andl(recv, 0xFF);
if (TaggedStackInterpreter) __ shll(recv, 1); // index*2
__ movptr(recv, Address(rsp, recv, Address::times_8,
-Interpreter::expr_offset_in_bytes(1)));
+ Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1));
+ if (is_invokedynamic) {
+ __ lea(recv, recv_addr);
+ } else {
+ __ movptr(recv, recv_addr);
__ verify_oop(recv);
}
+ }
// do null check if needed
if (receiver_null_check) {
__ null_check(recv);
}
*** 2876,2889 ****
--- 2881,2898 ----
__ shrl(flags, ConstantPoolCacheEntry::tosBits);
// Make sure we don't need to mask flags for tosBits after the above shift
ConstantPoolCacheEntry::verify_tosBits();
// load return address
{
! ExternalAddress return_5((address)Interpreter::return_5_addrs_by_index_table());
ExternalAddress return_3((address)Interpreter::return_3_addrs_by_index_table());
! __ lea(rscratch1, (is_invokeinterface ? return_5 : return_3));
__ movptr(flags, Address(rscratch1, flags, Address::times_8));
! address table_addr;
+ if (is_invokeinterface || is_invokedynamic)
! table_addr = (address)Interpreter::return_5_addrs_by_index_table();
+ else
+ table_addr = (address)Interpreter::return_3_addrs_by_index_table();
+ ExternalAddress table(table_addr);
+ __ lea(rscratch1, table);
+ __ movptr(flags, Address(rscratch1, flags, Address::times_ptr));
}
// push return address
__ push(flags);
*** 2945,2955 ****
--- 2954,2964 ----
}
void TemplateTable::invokevirtual(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rbx, noreg, byte_no, bytecode());
// rbx: index
// rcx: receiver
// rdx: flags
*** 2957,2977 ****
--- 2966,2986 ----
}
void TemplateTable::invokespecial(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rbx, noreg, byte_no, bytecode());
// do the call
__ verify_oop(rbx);
__ profile_call(rax);
__ jump_from_interpreted(rbx, rax);
}
void TemplateTable::invokestatic(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rbx, noreg, byte_no, bytecode());
// do the call
__ verify_oop(rbx);
__ profile_call(rax);
__ jump_from_interpreted(rbx, rax);
}
*** 2981,2991 ****
--- 2990,3000 ----
__ stop("fast_invokevfinal not used on amd64");
}
void TemplateTable::invokeinterface(int byte_no) {
transition(vtos, vtos);
- prepare_invoke(rax, rbx, byte_no, bytecode());
// rax: Interface
// rbx: index
// rcx: receiver
// rdx: flags
*** 3070,3080 ****
--- 3079,3106 ----
// the call_VM checks for exception, so we should never return here.
__ should_not_reach_here();
return;
}
__ stop("invokedynamic NYI");//6815692//
+ prepare_invoke(rax, rbx, byte_no);
+
+ // rax: CallSite object (f1)
+ // rbx: unused (f2)
+ // rcx: receiver address
+ // rdx: flags (unused)
+
+ if (ProfileInterpreter) {
+ Label L;
+ // %%% should make a type profile for any invokedynamic that takes a ref argument
+ // profile this call
+ __ profile_call(r13);
+ }
+
+ __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
+ __ null_check(rcx);
+ __ prepare_to_jump_from_interpreted();
+ __ jump_to_method_handle_entry(rcx, rdx);
}
//-----------------------------------------------------------------------------
// Allocation
src/cpu/x86/vm/templateTable_x86_64.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File