--- a/tailc-eager.patch Tue Jun 02 23:41:37 2009 -0700
+++ b/tailc-eager.patch Fri Jun 12 15:04:35 2009 -0700
@@ -1,7 +1,7 @@ diff -r ce2272390558 src/cpu/sparc/vm/sp
-diff -r ce2272390558 src/cpu/sparc/vm/sparc.ad
---- a/src/cpu/sparc/vm/sparc.ad Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/sparc/vm/sparc.ad Mon Mar 16 11:42:47 2009 +0100
-@@ -1559,7 +1559,7 @@ void emit_java_to_interp(CodeBuffer &cbu
+diff -r aa0c48844632 src/cpu/sparc/vm/sparc.ad
+--- a/src/cpu/sparc/vm/sparc.ad Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/sparc/vm/sparc.ad Thu Jun 04 10:20:29 2009 +0200
+@@ -1552,7 +1552,7 @@ void emit_java_to_interp(CodeBuffer &cbu
// jmp -1
address mark = cbuf.inst_mark(); // get mark within main instrs section
@@ -10,10 +10,10 @@ diff -r ce2272390558 src/cpu/sparc/vm/sp
MacroAssembler _masm(&cbuf);
address base =
-diff -r ce2272390558 src/cpu/x86/vm/assembler_x86.cpp
---- a/src/cpu/x86/vm/assembler_x86.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/assembler_x86.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -1342,6 +1342,15 @@ void Assembler::jmp(Address adr) {
+diff -r aa0c48844632 src/cpu/x86/vm/assembler_x86.cpp
+--- a/src/cpu/x86/vm/assembler_x86.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/assembler_x86.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -1348,6 +1348,15 @@ void Assembler::jmp(Address adr) {
emit_byte(0xFF);
emit_operand(rsp, adr);
}
@@ -29,7 +29,7 @@ diff -r ce2272390558 src/cpu/x86/vm/asse
void Assembler::jmp(Label& L, relocInfo::relocType rtype) {
if (L.is_bound()) {
-@@ -3276,6 +3285,22 @@ void Assembler::shrdl(Register dst, Regi
+@@ -3335,6 +3344,15 @@ void Assembler::shrdl(Register dst, Regi
emit_byte(0xC0 | src->encoding() << 3 | dst->encoding());
}
@@ -41,18 +41,11 @@ diff -r ce2272390558 src/cpu/x86/vm/asse
+ jcc(Assembler::greater, is_not_interpreter_continutation);
+}
+
-+void MacroAssembler::move_args_to_outgoing_area(Register base_pointer, Register stack_pointer, Register tmp, int no_args, int pd_slots, int adjust_sp_slots) {
-+ for (int i=pd_slots; i < no_args; i++) {
-+ // Count in return address stack slot. Hence + 1.
-+ movl(tmp, Address(base_pointer, VMRegImpl::stack_slot_size * (i + 2)));
-+ movl(Address(stack_pointer, VMRegImpl::stack_slot_size * (adjust_sp_slots+i+1)), tmp);
-+ }
-+}
+
#else // LP64
// 64bit only pieces of the assembler
-@@ -3736,6 +3761,15 @@ void Assembler::cvttss2siq(Register dst,
+@@ -3795,6 +3813,15 @@ void Assembler::cvttss2siq(Register dst,
emit_byte(0x0F);
emit_byte(0x2C);
emit_byte(0xC0 | encode);
@@ -68,10 +61,10 @@ diff -r ce2272390558 src/cpu/x86/vm/asse
}
void Assembler::decl(Register dst) {
-diff -r ce2272390558 src/cpu/x86/vm/assembler_x86.hpp
---- a/src/cpu/x86/vm/assembler_x86.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/assembler_x86.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -560,7 +560,12 @@ private:
+diff -r aa0c48844632 src/cpu/x86/vm/assembler_x86.hpp
+--- a/src/cpu/x86/vm/assembler_x86.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/assembler_x86.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -606,7 +606,12 @@ private:
void call_literal(address entry, RelocationHolder const& rspec);
void jmp_literal(address entry, RelocationHolder const& rspec);
@@ -85,7 +78,7 @@ diff -r ce2272390558 src/cpu/x86/vm/asse
// Avoid using directly section
// Instructions in this section are actually usable by anyone without danger
// of failure but have performance issues that are addressed my enhanced
-@@ -1065,7 +1070,8 @@ private:
+@@ -1119,7 +1124,8 @@ private:
void movl(Register dst, Register src);
void movl(Register dst, Address src);
void movl(Address dst, Register src);
@@ -95,18 +88,16 @@ diff -r ce2272390558 src/cpu/x86/vm/asse
// These dummies prevent using movl from converting a zero (like NULL) into Register
// by giving the compiler two choices it can't resolve
-@@ -2032,6 +2038,10 @@ public:
-
+@@ -2183,6 +2189,8 @@ public:
// Can push value or effective address
void pushptr(AddressLiteral src);
-+ // Tail call support.
+
+ void parent_is_not_interpreter_jcc(Register base_pointer, Register temp, Label& is_not_interpreter_continutation);
-+ // Move parameters from area above base_pointer to area above stack pointer.
-+ void move_args_to_outgoing_area(Register base_pointer, Register stack_pointer, Register tmp, int no_args, int pd_slots, int adjust_sp_slots=0);
-
++
void pushptr(Address src) { LP64_ONLY(pushq(src)) NOT_LP64(pushl(src)); }
void popptr(Address src) { LP64_ONLY(popq(src)) NOT_LP64(popl(src)); }
-@@ -2041,7 +2051,6 @@ public:
+
+@@ -2191,7 +2199,6 @@ public:
// sign extend as need a l to ptr sized element
void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); }
void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); }
@@ -114,9 +105,9 @@ diff -r ce2272390558 src/cpu/x86/vm/asse
#undef VIRTUAL
-diff -r ce2272390558 src/cpu/x86/vm/assembler_x86.inline.hpp
---- a/src/cpu/x86/vm/assembler_x86.inline.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/assembler_x86.inline.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/assembler_x86.inline.hpp
+--- a/src/cpu/x86/vm/assembler_x86.inline.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/assembler_x86.inline.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -24,14 +24,19 @@
inline void MacroAssembler::pd_patch_instruction(address branch, address target) {
@@ -139,9 +130,9 @@ diff -r ce2272390558 src/cpu/x86/vm/asse
// short offset operators (jmp and jcc)
char* disp = (char*) &branch[1];
int imm8 = target - (address) &disp[1];
-diff -r ce2272390558 src/cpu/x86/vm/c1_CodeStubs_x86.cpp
---- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/c1_CodeStubs_x86.cpp
+--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -441,7 +441,7 @@ void ArrayCopyStub::emit_code(LIR_Assemb
}
}
@@ -151,9 +142,9 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_C
ce->emit_static_call_stub();
AddressLiteral resolve(SharedRuntime::get_resolve_static_call_stub(),
-diff -r ce2272390558 src/cpu/x86/vm/c1_FrameMap_x86.cpp
---- a/src/cpu/x86/vm/c1_FrameMap_x86.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/c1_FrameMap_x86.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/c1_FrameMap_x86.cpp
+--- a/src/cpu/x86/vm/c1_FrameMap_x86.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/c1_FrameMap_x86.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -27,7 +27,7 @@
const int FrameMap::pd_c_runtime_reserved_arg_size = 0;
@@ -178,14 +169,19 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_F
} else if (r_1->is_Register()) {
Register reg = r_1->as_Register();
if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) {
-diff -r ce2272390558 src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
---- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -510,6 +510,332 @@ void LIR_Assembler::emit_deopt_handler()
+diff -r aa0c48844632 src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
+--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -510,6 +510,296 @@ void LIR_Assembler::emit_deopt_handler()
}
+void LIR_Assembler::emit_static_not_sibling_tail_call_stub() {
++ // if the last instruction is a call (typically to do a throw which
++ // is coming at the end after block reordering) the return address
++ // must still point into the code area in order to avoid assertion
++ // failures when searching for the corresponding bci => add a nop
++ // (was bug 5/14/1999 - gri)
+ __ nop();
+ CallingConvention * incoming_args = frame_map()->incoming_arguments();
+ Label call_to_interpreter;
@@ -261,71 +257,13 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
+ __ end_a_stub();
+}
+
-+void LIR_Assembler::emit_tail_call_pd_mismatch_stub() {
-+ __ nop();
-+ CallingConvention * incoming_args = frame_map()->incoming_arguments();
-+ assert(incoming_args!=NULL, "ops");
-+ int arg_slots = incoming_args->reserved_stack_slots();
-+ // TODO: proper size.
-+ int stub_size = 8*arg_slots + static_tail_call_stub_size;
-+ address handler_base = __ start_a_stub(stub_size);
-+ if (handler_base == NULL) {
-+ // Not enough space left for the handler.
-+ bailout("tail call pd mismatch stub overflow");
-+ return;
-+ }
-+#ifdef ASSERT
-+ int offset = code_offset();
-+#endif // ASSERT
-+
-+ compilation()->offsets()->set_value(CodeOffsets::Tail_Call_Move_Arguments, code_offset());
-+ if (TraceTailCalls) __ warn("verified tail call pd mismatch stub");
-+ // Compute target of jump. Unverified entry point of current method.
-+ address uep_entry = compilation()->code()->insts()->start() +
-+ compilation()->offsets()->value(CodeOffsets::Entry);
-+ RelocationHolder rh = section_call_Relocation::spec(uep_entry, CodeBuffer::SECT_INSTS);
-+ // Move arguments.
-+ __ move_args_to_outgoing_area(rbp, rsp, rbx, arg_slots, SharedRuntime::tail_call_protection_domain_slots());
-+ // Jump to UEP.
-+ __ jump(AddressLiteral((address)uep_entry, rh));
-+
-+ assert(code_offset() - offset <= stub_size, "overflow");
-+ __ end_a_stub();
-+}
-+
-+void LIR_Assembler::emit_verified_tail_call_pd_mismatch_stub() {
-+ __ nop();
-+ CallingConvention * incoming_args = frame_map()->incoming_arguments();
-+ assert(incoming_args!=NULL, "ops");
-+ int arg_slots = incoming_args->reserved_stack_slots();
-+ // TODO: proper size.
-+ int stub_size = 8*arg_slots + static_tail_call_stub_size;
-+ address handler_base = __ start_a_stub(stub_size);
-+ if (handler_base == NULL) {
-+ // Not enough space left for the handler.
-+ bailout("verified tail call pd mismatch stub overflow");
-+ return;
-+ }
-+#ifdef ASSERT
-+ int offset = code_offset();
-+#endif // ASSERT
-+
-+ compilation()->offsets()->set_value(CodeOffsets::Verified_Tail_Call_Move_Arguments, code_offset());
-+ if (TraceTailCalls) __ warn("verified tail call pd mismatch stub");
-+ // Compute target of jump. Verified entry point of current method.
-+ address vep_entry = compilation()->code()->insts()->start() +
-+ compilation()->offsets()->value(CodeOffsets::Verified_Entry);
-+ RelocationHolder rh = section_call_Relocation::spec(vep_entry, CodeBuffer::SECT_INSTS);
-+ // Move arguments.
-+ __ move_args_to_outgoing_area(rbp, rsp, rbx, arg_slots, SharedRuntime::tail_call_protection_domain_slots());
-+ // Jump to vep.
-+ __ jump(AddressLiteral((address)vep_entry, rh));
-+
-+ assert(code_offset() - offset <= stub_size, "overflow");
-+ __ end_a_stub();
-+}
-+
+void LIR_Assembler::emit_static_tail_call_stub() {
++ // if the last instruction is a call (typically to do a throw which
++ // is coming at the end after block reordering) the return address
++ // must still point into the code area in order to avoid assertion
++ // failures when searching for the corresponding bci => add a nop
++ // (was bug 5/14/1999 - gri)
++
+ __ nop();
+ CallingConvention * incoming_args = frame_map()->incoming_arguments();
+ assert(incoming_args!=NULL, "ops");
@@ -347,12 +285,15 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
+ if (TraceTailCalls) __ warn("Compiled entry point: Verified_Tail_Call_Entry");
+ __ generate_stack_overflow_check(initial_frame_size_in_bytes());
+
++ // Move arguments.
++ emit_tail_call_argument_move(arg_slots);
+ // Remove tail calling caller's stack frame.
+ Address new_stack_pointer(rbp, -1*initial_frame_size_in_bytes());
+ __ leal(rsp, new_stack_pointer);
+ // Compute target of jump. Verified entry point of current method.
+ address vep_entry = compilation()->code()->insts()->start() +
+ compilation()->offsets()->value(CodeOffsets::Frame_Complete);
++ //compilation()->offsets()->value(CodeOffsets::Verified_Entry);
+ RelocationHolder rh = section_call_Relocation::spec(vep_entry, CodeBuffer::SECT_INSTS);
+ // Jump to vep.
+ __ jump(AddressLiteral((address)vep_entry, rh));
@@ -394,6 +335,11 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
+}
+
+void LIR_Assembler::emit_not_sibling_monomorphic_tail_call_stub() {
++ // if the last instruction is a call (typically to do a throw which
++ // is coming at the end after block reordering) the return address
++ // must still point into the code area in order to avoid assertion
++ // failures when searching for the corresponding bci => add a nop
++ // (was bug 5/14/1999 - gri)
+ __ nop();
+ CallingConvention * incoming_args = frame_map()->incoming_arguments();
+ Label call_to_interpreter;
@@ -471,6 +417,12 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
+}
+
+void LIR_Assembler::emit_monomorphic_tail_call_stub() {
++ // if the last instruction is a call (typically to do a throw which
++ // is coming at the end after block reordering) the return address
++ // must still point into the code area in order to avoid assertion
++ // failures when searching for the corresponding bci => add a nop
++ // (was bug 5/14/1999 - gri)
++
+ __ nop();
+ CallingConvention * incoming_args = frame_map()->incoming_arguments();
+ assert(incoming_args!=NULL, "ops");
@@ -495,6 +447,8 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
+ // the frame would be popped again by handle_ic_miss code path.
+ check_icache();
+ __ generate_stack_overflow_check(initial_frame_size_in_bytes());
++ // Move arguments.
++ emit_tail_call_argument_move(arg_slots);
+
+ // Remove tail calling caller's stack frame.
+ Address new_stack_pointer(rbp, -1*initial_frame_size_in_bytes());
@@ -502,6 +456,7 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
+
+ // Compute target of jump. Verified entry point of current method.
+ address vep_entry = compilation()->code()->insts()->start() +
++ //compilation()->offsets()->value(CodeOffsets::Verified_Entry);
+ compilation()->offsets()->value(CodeOffsets::Frame_Complete);
+ RelocationHolder rh = section_call_Relocation::spec(vep_entry, CodeBuffer::SECT_INSTS);
+ // Jump to vep.
@@ -514,7 +469,7 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
// This is the fast version of java.lang.String.compare; it has not
// OSR-entry and therefore, we generate a slow version for OSR's
-@@ -2751,7 +3077,7 @@ void LIR_Assembler::comp_fl2i(LIR_Code c
+@@ -2726,7 +3016,7 @@ void LIR_Assembler::comp_fl2i(LIR_Code c
}
@@ -523,7 +478,7 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
if (os::is_MP()) {
// make sure that the displacement word of the call ends up word aligned
int offset = __ offset();
-@@ -2759,9 +3085,14 @@ void LIR_Assembler::align_call(LIR_Code
+@@ -2734,9 +3024,14 @@ void LIR_Assembler::align_call(LIR_Code
case lir_static_call:
case lir_optvirtual_call:
offset += NativeCall::displacement_offset;
@@ -540,7 +495,7 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
break;
case lir_virtual_call: // currently, sparc-specific for niagara
default: ShouldNotReachHere();
-@@ -2772,22 +3103,93 @@ void LIR_Assembler::align_call(LIR_Code
+@@ -2747,22 +3042,93 @@ void LIR_Assembler::align_call(LIR_Code
}
}
@@ -641,9 +596,9 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
add_call_info(code_offset(), info);
}
-diff -r ce2272390558 src/cpu/x86/vm/c1_LIRAssembler_x86.hpp
---- a/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/c1_LIRAssembler_x86.hpp
+--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -36,6 +36,9 @@
address float_constant(float f);
address double_constant(double d);
@@ -664,9 +619,9 @@ diff -r ce2272390558 src/cpu/x86/vm/c1_L
+ monomorphic_not_sibling_tail_call_stub_size = NOT_LP64(300) LP64_ONLY(xxx),
deopt_handler_size = NOT_LP64(10) LP64_ONLY(17)
};
-diff -r ce2272390558 src/cpu/x86/vm/frame_x86.hpp
---- a/src/cpu/x86/vm/frame_x86.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/frame_x86.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/frame_x86.hpp
+--- a/src/cpu/x86/vm/frame_x86.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/frame_x86.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -109,7 +109,9 @@
interpreter_frame_cache_offset = interpreter_frame_mdx_offset - 1,
interpreter_frame_locals_offset = interpreter_frame_cache_offset - 1,
@@ -678,9 +633,9 @@ diff -r ce2272390558 src/cpu/x86/vm/fram
interpreter_frame_monitor_block_top_offset = interpreter_frame_initial_sp_offset,
interpreter_frame_monitor_block_bottom_offset = interpreter_frame_initial_sp_offset,
-diff -r ce2272390558 src/cpu/x86/vm/frame_x86.inline.hpp
---- a/src/cpu/x86/vm/frame_x86.inline.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/frame_x86.inline.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/frame_x86.inline.hpp
+--- a/src/cpu/x86/vm/frame_x86.inline.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/frame_x86.inline.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -191,6 +191,9 @@ inline intptr_t* frame::interpreter_fram
#else /* asm interpreter */
inline intptr_t* frame::sender_sp() const { return addr_at( sender_sp_offset); }
@@ -691,44 +646,55 @@ diff -r ce2272390558 src/cpu/x86/vm/fram
inline intptr_t** frame::interpreter_frame_locals_addr() const {
return (intptr_t**)addr_at(interpreter_frame_locals_offset);
}
-diff -r ce2272390558 src/cpu/x86/vm/interp_masm_x86_32.cpp
---- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -588,11 +588,15 @@ void InterpreterMacroAssembler::super_ca
-
- // Jump to from_interpreted entry of a call unless single stepping is possible
- // in this thread in which case we must call the i2i entry
--void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) {
-+void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp, bool is_tail_call) {
-+ // tail call codes sets its own sender sp
+diff -r aa0c48844632 src/cpu/x86/vm/interp_masm_x86_32.cpp
+--- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -568,18 +568,22 @@ void InterpreterMacroAssembler::super_ca
+ }
+
+
+-void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
++void InterpreterMacroAssembler::prepare_to_jump_from_interpreted(bool is_tail_call) {
// set sender sp
- lea(rsi, Address(rsp, wordSize));
- // record last_sp
- movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rsi);
-+ //leal(rsi, Address(rsp, wordSize));
++ // Tail call codes sets its own sender sp. So only set sp if current call is
++ // not a tail call.
+ if (is_tail_call==false) {
+ leal(rsi, Address(rsp, wordSize));
+ // record last_sp
+ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rsi);
+ }
+ }
+
+
+ // Jump to from_interpreted entry of a call unless single stepping is possible
+ // in this thread in which case we must call the i2i entry
+-void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) {
+- prepare_to_jump_from_interpreted();
++void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp, bool is_tail_call) {
++ prepare_to_jump_from_interpreted(is_tail_call);
if (JvmtiExport::can_post_interpreter_events()) {
Label run_compiled_code;
-diff -r ce2272390558 src/cpu/x86/vm/interp_masm_x86_32.hpp
---- a/src/cpu/x86/vm/interp_masm_x86_32.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -161,7 +161,7 @@ class InterpreterMacroAssembler: public
+diff -r aa0c48844632 src/cpu/x86/vm/interp_masm_x86_32.hpp
+--- a/src/cpu/x86/vm/interp_masm_x86_32.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -162,8 +162,8 @@ class InterpreterMacroAssembler: public
// jump to an invoked target
+- void prepare_to_jump_from_interpreted();
- void jump_from_interpreted(Register method, Register temp);
++ void prepare_to_jump_from_interpreted(bool is_tail_call=false);
+ void jump_from_interpreted(Register method, Register temp, bool is_tail_call=false);
// Returning from interpreted functions
//
-diff -r ce2272390558 src/cpu/x86/vm/nativeInst_x86.cpp
---- a/src/cpu/x86/vm/nativeInst_x86.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/nativeInst_x86.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/nativeInst_x86.cpp
+--- a/src/cpu/x86/vm/nativeInst_x86.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/nativeInst_x86.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -114,7 +114,18 @@ void NativeCall::replace_mt_safe(address
}
@@ -809,9 +775,9 @@ diff -r ce2272390558 src/cpu/x86/vm/nati
address NativeGeneralJump::jump_destination() const {
int op_code = ubyte_at(0);
bool is_rel32off = (op_code == 0xE9 || op_code == 0x0F);
-diff -r ce2272390558 src/cpu/x86/vm/nativeInst_x86.hpp
---- a/src/cpu/x86/vm/nativeInst_x86.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/nativeInst_x86.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/nativeInst_x86.hpp
+--- a/src/cpu/x86/vm/nativeInst_x86.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/nativeInst_x86.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -154,6 +154,8 @@ class NativeCall: public NativeInstructi
static void insert(address code_pos, address entry);
@@ -906,9 +872,9 @@ diff -r ce2272390558 src/cpu/x86/vm/nati
inline NativeJump* nativeJump_at(address address) {
NativeJump* jump = (NativeJump*)(address - NativeJump::instruction_offset);
#ifdef ASSERT
-diff -r ce2272390558 src/cpu/x86/vm/sharedRuntime_x86_32.cpp
---- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/sharedRuntime_x86_32.cpp
+--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -38,6 +38,12 @@ RuntimeStub* SharedRuntime::_resol
RuntimeStub* SharedRuntime::_resolve_opt_virtual_call_blob;
RuntimeStub* SharedRuntime::_resolve_virtual_call_blob;
@@ -991,7 +957,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
__ subptr(rsp, extraspace);
-@@ -913,6 +931,230 @@ AdapterHandlerEntry* SharedRuntime::gene
+@@ -913,6 +931,181 @@ AdapterHandlerEntry* SharedRuntime::gene
gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
// -------------------------------------------------------------------------
@@ -1020,7 +986,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
+ Register holder = rax;
+ Register receiver = rcx;
+ Register temp = rbx;
-+ if (TraceTailCalls) __ warn ("c2i unverified not sib tail call entry");
++
+ __ verify_oop(holder);
+ __ movl(temp, Address(receiver, oopDesc::klass_offset_in_bytes()));
+ __ verify_oop(temp);
@@ -1040,17 +1006,20 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
+
+ address c2i_verified_not_sibling_tail_call_entry = __ pc();
+ {
++ //__ warn("c2i_not_sibling_tail_call_entry");
+ patch_callers_callsite(masm);
-+ if (TraceTailCalls) __ warn("c2i verified not_sibling_tail_call_entry");
+ __ verify_oop(rbx); // Rbx should contain methodoop of callee
+ Register tmp = rax; // Rax (IC_klass) is not used for static calls.
+ __ bind(verified_tail_call_not_sibling);
++ if (TraceTailCalls) __ warn("c2i static not sib tail call entry");
+ __ parent_is_not_interpreter_jcc(base_pointer, tmp, continue_in_interpreter);
++ //__ warn("c2i_not_sibling_tail_call_entry: parent is interpreted");
+ // Parent is interpreted: can use code path of static tail call.
+ // It moves the arguments relative to the last_sp of the parent frame.
+ __ jmp(verified_tail_call);
+ __ bind(continue_in_interpreter);
+ if (TraceTailCalls) __ warn("c2i continue in interpreter");
++ //__ warn("c2i_not_sibling_tail_call_entry: parent is compiled: continue in interpreted");
+ // Leave an int frame - lazily create an interpreter frame (the callee frame)
+ // Since we want to guarantee an interpreter frame on the stack we turn off
+ // on stack replacement (OSR) for one run (frame) of the called function.
@@ -1065,9 +1034,6 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
+ __ jmp(skip_fixup); // to interpreter.
+ }
+
-+
-+ Label tail_call_arguments_already_moved;
-+ Label tail_call_args_moved_pop_frame;
+ address c2i_unverified_tail_call_entry = __ pc();
+ {
+
@@ -1076,7 +1042,6 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
+ Register receiver = rcx;
+ Register temp = rbx;
+
-+ if (TraceTailCalls) __ warn("c2i unverified entry tail call");
+ __ verify_oop(holder);
+ __ movl(temp, Address(receiver, oopDesc::klass_offset_in_bytes()));
+ __ verify_oop(temp);
@@ -1088,122 +1053,74 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
+ // interpreted if that is the case treat it as a miss so we can get
+ // the call site corrected.
+ __ cmpl(Address(rbx, in_bytes(methodOopDesc::code_offset())), NULL_WORD);
-+ __ jcc(Assembler::equal, tail_call_arguments_already_moved);
++ __ jcc(Assembler::equal, verified_tail_call);
++
+ __ bind(missed);
+ __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
+ }
+
+ // Static tail call entry: We know that the protection domain and klass is
+ // correct.
++
+ address verified_tail_call_c2i_entry = __ pc();
-+ {
-+ if (TraceTailCalls) __ warn("c2i verified entry tail call");
-+ __ bind(tail_call_arguments_already_moved);
-+ Register tmp = rax;
-+ patch_callers_callsite(masm);
-+ __ parent_is_not_interpreter_jcc(base_pointer, tmp, tail_call_args_moved_pop_frame);
-+ // Parent is interpreted
-+ // Safe some registers.
-+ __ push(rax);
-+ __ push(rbx);
-+ // store rbp
-+ __ movl(tmp, Address(base_pointer, frame::link_offset*wordSize));
-+ __ push(tmp);
-+ // Store ret address.
-+ __ movl(tmp, Address(base_pointer, frame::return_addr_offset * wordSize));
-+ __ push(tmp);
-+ // Get last_sp from parent frame.
-+ Register last_sp = tmp; tmp = rbx;
-+ __ movl(tmp, Address(base_pointer, frame::link_offset * wordSize)); // old rbp
-+ __ movl(last_sp, Address(tmp, frame::interpreter_frame_last_sp_offset * wordSize));
-+#ifdef COMPILER2
-+ // Server compiler needs to use rdi as base_pointer. Because rsi holds
-+ // last_sp for interpreter.
-+ __ movl(rdi, base_pointer);
-+ base_pointer = rdi;
-+#endif
-+ __ movl(rsi, last_sp); // old_sp for interpreter
-+ // Shuffle arguments
-+ for (int src_slot = comp_args_on_stack, dest_slot=-1; src_slot > 0; src_slot--, dest_slot--) {
-+ // retaddr => +1
-+ Address src(base_pointer, VMRegImpl::stack_slot_size * (1+src_slot));
-+ Address dest(last_sp, VMRegImpl::stack_slot_size * (dest_slot));
-+ __ movl(tmp, src);
-+ __ movl(dest, tmp);
-+ }
-+ // Set return address.
-+ __ subl(last_sp, (1+comp_args_on_stack)*wordSize);
-+ __ pop(tmp);
-+ __ movl(Address(last_sp, 0), tmp);
-+ // Set rbp
-+ __ pop(rbp);
-+ // Restore used registers.
-+ __ pop(rbx);
-+ // Set new rsp.
-+ __ movl(rsp, last_sp);
-+ __ jmp(skip_fixup_tail_call);
-+#ifdef COMPILER2
-+ base_pointer = rsi; // reset
-+#endif
-+ }
-+
-+ // Not sibling tail calls arrive here.
-+ {
-+ __ bind (verified_tail_call);
-+ if (TraceTailCalls) __ warn("c2i static tail call entry");
-+ // Check whether parent frame is interpreter.
-+ Register tmp = rax; // Klass not used if static call.
-+
-+ __ parent_is_not_interpreter_jcc(base_pointer, tmp, parent_is_not_interpreted);
-+ // Parent is interpreted
-+ // Safe some registers.
-+ __ push(rax);
-+ __ push(rbx);
-+ // store rbp
-+ __ movl(tmp, Address(base_pointer, frame::link_offset*wordSize));
-+ __ push(tmp);
-+ // Store ret address.
-+ __ movl(tmp, Address(base_pointer, frame::return_addr_offset * wordSize));
-+ __ push(tmp);
-+ // Get last_sp from parent frame.
-+ Register last_sp = tmp; tmp = rbx;
-+ __ movl(tmp, Address(base_pointer, frame::link_offset * wordSize)); // old rbp
-+ __ movl(last_sp, Address(tmp, frame::interpreter_frame_last_sp_offset * wordSize));
-+ __ movl(rsi, last_sp); // old_sp for interpreter
-+ // Shuffle arguments
-+ for (int src_slot = comp_args_on_stack, dest_slot=-1; src_slot > 0; src_slot--, dest_slot--) {
-+ // rax,rbx,old_rbp,old_retaddr => +4
-+ Address src(rsp, VMRegImpl::stack_slot_size * (4+src_slot));
-+ Address dest(last_sp, VMRegImpl::stack_slot_size * (dest_slot));
-+ __ movl(tmp, src);
-+ __ movl(dest, tmp);
-+ }
-+ // Set return address.
-+ __ subl(last_sp, (1+comp_args_on_stack)*wordSize);
-+ __ pop(tmp);
-+ __ movl(Address(last_sp, 0), tmp);
-+ // Set rbp
-+ __ pop(rbp);
-+ // Restore used registers.
-+ __ pop(rbx);
-+ // Set new rsp.
-+ __ movl(rsp, last_sp);
-+ __ jmp(skip_fixup_tail_call);
-+
-+ // Parent is compiled.
-+ __ bind(parent_is_not_interpreted);
-+ tmp = rax;
-+ for (int slot = 1; slot <= comp_args_on_stack; slot++) {
-+ Address src (rsp, VMRegImpl::stack_slot_size * (SharedRuntime::out_preserve_stack_slots()+slot));
-+ // Need to add safed rbp slot so slot+1 VVV
-+ Address dest(base_pointer, VMRegImpl::stack_slot_size * (SharedRuntime::out_preserve_stack_slots()+slot+1));
-+ __ movl(tmp, src);
-+ __ movl(dest, tmp);
-+ }
-+ }
-+
-+ // Sibling tail calls arrive here.
-+ __ bind(tail_call_args_moved_pop_frame);
++ patch_callers_callsite(masm);
++ __ bind (verified_tail_call);
++ if (TraceTailCalls) __ warn("c2i static tail call entry");
++ // Check whether parent frame is interpreter.
++ Register tmp = rax; // Klass not used if static call.
++
++
++ __ parent_is_not_interpreter_jcc(base_pointer, tmp, parent_is_not_interpreted);
++ //__ warn("c2i_static_tail_call_entry: parent is interpreted");
++ // Parent is interpreted
++ // Safe some registers.
++ __ push(rax);
++ __ push(rbx);
++ // store rbp
++ __ movl(tmp, Address(base_pointer, frame::link_offset*wordSize));
++ __ push(tmp);
++ // Store ret address.
++ __ movl(tmp, Address(base_pointer, frame::return_addr_offset * wordSize));
++ __ push(tmp);
++ // Get last_sp from parent frame.
++ Register last_sp = tmp; tmp = rbx;
++ __ movl(tmp, Address(base_pointer, frame::link_offset * wordSize)); // old rbp
++ __ movl(last_sp, Address(tmp, frame::interpreter_frame_last_sp_offset * wordSize));
++ __ movl(rsi, last_sp); // old_sp for interpreter
++ // Shuffle arguments
++ for (int src_slot = comp_args_on_stack, dest_slot=-1; src_slot > 0; src_slot--, dest_slot--) {
++ // rax,rbx,old_rbp,old_retaddr => +4
++ Address src(rsp, VMRegImpl::stack_slot_size * (4+src_slot));
++ Address dest(last_sp, VMRegImpl::stack_slot_size * (dest_slot));
++ __ movl(tmp, src);
++ __ movl(dest, tmp);
++ }
++ // Set return address.
++ __ subl(last_sp, (1+comp_args_on_stack)*wordSize);
++ __ pop(tmp);
++ __ movl(Address(last_sp, 0), tmp);
++ // Set rbp
++ __ pop(rbp);
++ // Restore used registers.
++ __ pop(rbx);
++ // Set new rsp.
++ __ movl(rsp, last_sp);
++ // Set new rbp
++ // BUG: might be overwritten !!!???!!! see not sibling entry point. push rbp
++ // at the beginning.
++ //__ movl(rbp, Address(rbp, frame::link_offset * wordSize)); // old rbp
++ __ jmp(skip_fixup_tail_call);
++
++ // Parent is compiled.
++ __ bind(parent_is_not_interpreted);
++ tmp = rax;
++ for (int slot = 1; slot <= comp_args_on_stack; slot++) {
++ Address src (rsp, VMRegImpl::stack_slot_size * (SharedRuntime::out_preserve_stack_slots()+slot));
++ // Need to add safed rbp slot so slot+1 VVV
++ Address dest(base_pointer, VMRegImpl::stack_slot_size * (SharedRuntime::out_preserve_stack_slots()+slot+1));
++ __ movl(tmp, src);
++ __ movl(dest, tmp);
++ }
+ // pop frame
+#ifdef COMPILER2
+ __ mov(rsp, rsi); // Rsi contains base_pointer for opto.
@@ -1222,60 +1139,31 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
// Generate a C2I adapter. On entry we know rbx, holds the methodOop during calls
// to the interpreter. The args start out packed in the compiled layout. They
// need to be unpacked into the interpreter layout. This will almost always
-@@ -920,10 +1162,10 @@ AdapterHandlerEntry* SharedRuntime::gene
- // the args. We finally end in a jump to the generic interpreter entry point.
- // On exit from the interpreter, the interpreter will restore our SP (lest the
+@@ -922,7 +1115,8 @@ AdapterHandlerEntry* SharedRuntime::gene
// compiled code, which relys solely on SP and not EBP, get sick).
--
-+ Label c2i_unverified_entry_label;
+
address c2i_unverified_entry = __ pc();
- Label skip_fixup;
--
-+ __ bind(c2i_unverified_entry_label);
+ if (TraceTailCalls) __ warn("c2i_unverified_entry (not tail call)");
++ //Label skip_fixup;
+
Register holder = rax;
Register receiver = rcx;
- Register temp = rbx;
-@@ -949,12 +1191,50 @@ AdapterHandlerEntry* SharedRuntime::gene
+@@ -948,13 +1142,22 @@ AdapterHandlerEntry* SharedRuntime::gene
+ __ bind(missed);
__ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
}
-
-+ // Protection domain mismatch move args back to caller frame.
-+ Label c2i_entry_label;
-+ address c2i_pd_mismatch_entry = __ pc();
-+ {
-+ Register base_pointer = rbp;
-+#ifdef COMPILER2
-+ base_pointer = rsi;
-+#endif
-+ __ warn("c2i tail call pd mismatch verified entry");
-+ __ push(rbx); // Safe rbx. Contains methodoop.
-+ __ move_args_to_outgoing_area(base_pointer, rsp, rbx, comp_args_on_stack, SharedRuntime::tail_call_protection_domain_slots(), 1);
-+ __ pop(rbx); // Restore rbx.
-+ __ jmp(c2i_entry_label);
-+ }
-+ address c2i_unverified_pd_mismatch_entry = __ pc();
-+ {
-+ Register base_pointer = rbp;
-+#ifdef COMPILER2
-+ base_pointer = rsi;
-+#endif
-+ __ warn("c2i tail call pd mismatch unverified entry");
-+ __ push(rbx); // Safe rbx. Contains methodoop?
-+ __ move_args_to_outgoing_area(base_pointer, rsp, rbx, comp_args_on_stack, SharedRuntime::tail_call_protection_domain_slots(), 1);
-+ __ pop(rbx); // Restore rbx.
-+ __ jmp(c2i_unverified_entry_label);
-+ }
-+
+-
+ // For tail calls (lazy adapter/ interpreter frame) we skip the fix up check.
+ address c2i_entry_skip_fixup = __ pc();
+ if (TraceTailCalls) __ warn("c2i entry skip fixup");
+ __ jmp(continue_in_interpreter);
++ //__ jmp(skip_fixup);
+
address c2i_entry = __ pc();
-
- gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
-+ __ bind(c2i_entry_label);
++ //if (TraceTailCalls) __ warn("c2i_entry (not tail call)");
+ gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup, false);
__ flush();
@@ -1284,13 +1172,11 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
+ verified_tail_call_c2i_entry, c2i_unverified_tail_call_entry,
+ c2i_entry_skip_fixup,
+ c2i_verified_not_sibling_tail_call_entry,
-+ c2i_unverified_not_sibling_tail_call_entry,
-+ c2i_pd_mismatch_entry,
-+ c2i_unverified_pd_mismatch_entry);
++ c2i_unverified_not_sibling_tail_call_entry);
}
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
-@@ -1453,7 +1733,9 @@ nmethod *SharedRuntime::generate_native_
+@@ -1453,7 +1656,9 @@ nmethod *SharedRuntime::generate_native_
// sure we can capture all the incoming oop args from the
// caller.
//
@@ -1301,7 +1187,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
// Mark location of rbp,
// map->set_callee_saved(VMRegImpl::stack2reg( stack_slots - 2), stack_slots * 2, 0, rbp->as_VMReg());
-@@ -2328,7 +2610,7 @@ void SharedRuntime::generate_deopt_blob(
+@@ -2335,7 +2540,7 @@ void SharedRuntime::generate_deopt_blob(
// allocate space for the code
ResourceMark rm;
// setup code generation tools
@@ -1310,7 +1196,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
MacroAssembler* masm = new MacroAssembler(&buffer);
int frame_size_in_words;
OopMap* map = NULL;
-@@ -2390,6 +2672,29 @@ void SharedRuntime::generate_deopt_blob(
+@@ -2397,6 +2602,29 @@ void SharedRuntime::generate_deopt_blob(
__ push(Deoptimization::Unpack_reexecute);
__ jmp(cont);
@@ -1340,7 +1226,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
int exception_offset = __ pc() - start;
// Prolog for exception case
-@@ -2469,6 +2774,8 @@ void SharedRuntime::generate_deopt_blob(
+@@ -2476,6 +2704,8 @@ void SharedRuntime::generate_deopt_blob(
oop_maps->add_gc_map( __ pc()-start, map);
@@ -1349,7 +1235,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
// Discard arg to fetch_unroll_info
__ pop(rcx);
-@@ -2529,7 +2836,7 @@ void SharedRuntime::generate_deopt_blob(
+@@ -2536,7 +2766,7 @@ void SharedRuntime::generate_deopt_blob(
// Stack bang to make sure there's enough room for these interpreter frames.
if (UseStackBanging) {
@@ -1358,7 +1244,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
__ bang_stack_size(rbx, rcx);
}
-@@ -2549,9 +2856,9 @@ void SharedRuntime::generate_deopt_blob(
+@@ -2556,9 +2786,9 @@ void SharedRuntime::generate_deopt_blob(
// Pick up the initial fp we should save
__ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes()));
@@ -1371,7 +1257,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
// value and not the "real" sp value.
Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes());
-@@ -2667,7 +2974,7 @@ void SharedRuntime::generate_deopt_blob(
+@@ -2674,7 +2904,7 @@ void SharedRuntime::generate_deopt_blob(
// make sure all code is generated
masm->flush();
@@ -1380,7 +1266,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
_deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
}
-@@ -2952,7 +3259,7 @@ static SafepointBlob* generate_handler_b
+@@ -2959,7 +3189,7 @@ static SafepointBlob* generate_handler_b
// but since this is generic code we don't know what they are and the caller
// must do any gc of the args.
//
@@ -1389,7 +1275,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
// allocate space for the code
-@@ -3007,10 +3314,24 @@ static RuntimeStub* generate_resolve_blo
+@@ -3014,10 +3244,24 @@ static RuntimeStub* generate_resolve_blo
__ movptr(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax);
@@ -1416,7 +1302,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
__ jmp(rax);
// Pending exception after the safepoint
-@@ -3052,6 +3373,23 @@ void SharedRuntime::generate_stubs() {
+@@ -3059,6 +3303,23 @@ void SharedRuntime::generate_stubs() {
_resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C),
"resolve_static_call");
@@ -1440,7 +1326,7 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
_polling_page_safepoint_handler_blob =
generate_handler_blob(CAST_FROM_FN_PTR(address,
SafepointSynchronize::handle_polling_page_exception), false);
-@@ -3061,6 +3399,10 @@ void SharedRuntime::generate_stubs() {
+@@ -3068,6 +3329,10 @@ void SharedRuntime::generate_stubs() {
SafepointSynchronize::handle_polling_page_exception), true);
generate_deopt_blob();
@@ -1451,10 +1337,10 @@ diff -r ce2272390558 src/cpu/x86/vm/shar
#ifdef COMPILER2
generate_uncommon_trap_blob();
#endif // COMPILER2
-diff -r ce2272390558 src/cpu/x86/vm/stubGenerator_x86_32.cpp
---- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -2101,12 +2101,28 @@ class StubGenerator: public StubCodeGene
+diff -r aa0c48844632 src/cpu/x86/vm/stubGenerator_x86_32.cpp
+--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -2071,12 +2071,28 @@ class StubGenerator: public StubCodeGene
// exceptions (e.g., NullPointerException or AbstractMethodError on entry) are
// either at call sites or otherwise assume that stack unwinding will be initiated,
// so caller saved registers were assumed volatile in the compiler.
@@ -1486,7 +1372,7 @@ diff -r ce2272390558 src/cpu/x86/vm/stub
CodeBuffer code(name, insts_size, locs_size);
OopMapSet* oop_maps = new OopMapSet();
MacroAssembler* masm = new MacroAssembler(&code);
-@@ -2125,7 +2141,22 @@ class StubGenerator: public StubCodeGene
+@@ -2095,7 +2111,22 @@ class StubGenerator: public StubCodeGene
}
__ enter(); // required for proper stackwalking of RuntimeStub frame
@@ -1510,7 +1396,7 @@ diff -r ce2272390558 src/cpu/x86/vm/stub
// pc and rbp, already pushed
__ subptr(rsp, (framesize-2) * wordSize); // prolog
-@@ -2152,9 +2183,33 @@ class StubGenerator: public StubCodeGene
+@@ -2122,9 +2153,33 @@ class StubGenerator: public StubCodeGene
__ get_thread(java_thread);
__ reset_last_Java_frame(java_thread, true, false);
@@ -1546,7 +1432,7 @@ diff -r ce2272390558 src/cpu/x86/vm/stub
// check for pending exceptions
#ifdef ASSERT
Label L;
-@@ -2165,8 +2220,8 @@ class StubGenerator: public StubCodeGene
+@@ -2135,8 +2190,8 @@ class StubGenerator: public StubCodeGene
#endif /* ASSERT */
__ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
@@ -1557,7 +1443,7 @@ diff -r ce2272390558 src/cpu/x86/vm/stub
return stub->entry_point();
}
-@@ -2240,6 +2295,9 @@ class StubGenerator: public StubCodeGene
+@@ -2210,6 +2265,9 @@ class StubGenerator: public StubCodeGene
StubRoutines::_throw_NullPointerException_entry = generate_throw_exception("NullPointerException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException), true);
StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false);
StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
@@ -1567,9 +1453,9 @@ diff -r ce2272390558 src/cpu/x86/vm/stub
//------------------------------------------------------------------------------------------------------------------------
// entry points that are platform specific
-diff -r ce2272390558 src/cpu/x86/vm/templateInterpreterGenerator_x86.hpp
---- a/src/cpu/x86/vm/templateInterpreterGenerator_x86.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/templateInterpreterGenerator_x86.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/templateInterpreterGenerator_x86.hpp
+--- a/src/cpu/x86/vm/templateInterpreterGenerator_x86.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/templateInterpreterGenerator_x86.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -24,6 +24,6 @@
protected:
@@ -1578,9 +1464,9 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
+void generate_fixed_frame(bool native_call, bool disable_osr=false);
// address generate_asm_interpreter_entry(bool synchronized);
-diff -r ce2272390558 src/cpu/x86/vm/templateInterpreter_x86_32.cpp
---- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/templateInterpreter_x86_32.cpp
+--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -34,6 +34,53 @@ const int locals_offset = frame::interpr
const int locals_offset = frame::interpreter_frame_locals_offset * wordSize;
@@ -1635,29 +1521,37 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
address entry = __ pc();
-@@ -132,7 +179,8 @@ address TemplateInterpreterGenerator::ge
- address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
+@@ -168,7 +215,11 @@ address TemplateInterpreterGenerator::ge
+
Label interpreter_entry;
address compiled_entry = __ pc();
-
+ // Tail call invokes have wide prefix so their length is one bigger.
++ // TODO: Fix tail call invokedynamic path i.e. offsets relative to rsi and
++ // bcp offsets.
+ bool is_tail_call = (step == 4) || (step==6);
++ int bcp_offset = is_tail_call ? 2 : 1;
#ifdef COMPILER2
// The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
- if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
-@@ -180,7 +228,10 @@ address TemplateInterpreterGenerator::ge
-
- __ restore_bcp();
- __ restore_locals();
-- __ get_cache_and_index_at_bcp(rbx, rcx, 1);
-+ if (is_tail_call)
-+ __ get_cache_and_index_at_bcp(rbx, rcx, 2);
-+ else
-+ __ get_cache_and_index_at_bcp(rbx, rcx, 1);
+ if ((incoming_state == ftos && UseSSE < 1) || (incoming_state == dtos && UseSSE < 2)) {
+@@ -262,7 +313,7 @@ address TemplateInterpreterGenerator::ge
+ __ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic);
+ __ jcc(Assembler::equal, L_giant_index);
+ }
+- __ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
++ __ get_cache_and_index_at_bcp(rbx, rcx, bcp_offset, false);
+ __ bind(L_got_cache);
+ if (unbox && state == atos) {
+ // insert a casting conversion, to keep verifier sane
+@@ -290,6 +341,7 @@ address TemplateInterpreterGenerator::ge
+ __ pop(rax);
+ __ bind(L_ok);
+ }
++
__ movl(rbx, Address(rbx, rcx,
Address::times_ptr, constantPoolCacheOopDesc::base_offset() +
ConstantPoolCacheEntry::flags_offset()));
-@@ -427,7 +478,6 @@ void InterpreterGenerator::generate_stac
+@@ -552,7 +604,6 @@ void InterpreterGenerator::generate_stac
// for the additional locals.
__ cmpl(rdx, (page_size - overhead_size)/Interpreter::stackElementSize());
__ jcc(Assembler::belowEqual, after_frame_check);
@@ -1665,7 +1559,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
// compute rsp as if this were going to be the last frame on
// the stack before the red zone
-@@ -441,10 +491,8 @@ void InterpreterGenerator::generate_stac
+@@ -566,10 +617,8 @@ void InterpreterGenerator::generate_stac
const Address stack_base(thread, Thread::stack_base_offset());
const Address stack_size(thread, Thread::stack_size_offset());
@@ -1676,7 +1570,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
#ifdef ASSERT
Label stack_base_okay, stack_size_okay;
// verify that thread stack base is non-zero
-@@ -526,7 +574,7 @@ void InterpreterGenerator::lock_method(v
+@@ -651,7 +700,7 @@ void InterpreterGenerator::lock_method(v
// Generate a fixed interpreter frame. This is identical setup for interpreted methods
// and for native methods hence the shared code.
@@ -1685,7 +1579,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
// initialize fixed part of activation frame
__ push(rax); // save return address
__ enter(); // save old & set new rbp,
-@@ -558,6 +606,11 @@ void TemplateInterpreterGenerator::gener
+@@ -683,6 +732,11 @@ void TemplateInterpreterGenerator::gener
} else {
__ push(rsi); // set bcp
}
@@ -1697,7 +1591,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
__ push(0); // reserve word for pointer to expression stack bottom
__ movptr(Address(rsp, 0), rsp); // set expression stack bottom
}
-@@ -748,7 +801,6 @@ address InterpreterGenerator::generate_n
+@@ -873,7 +927,6 @@ address InterpreterGenerator::generate_n
if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
// initialize fixed part of activation frame
@@ -1705,7 +1599,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
generate_fixed_frame(true);
// make sure method is native & not abstract
-@@ -1193,7 +1245,39 @@ address InterpreterGenerator::generate_n
+@@ -1318,7 +1371,39 @@ address InterpreterGenerator::generate_n
if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
// initialize fixed part of activation frame
@@ -1745,7 +1639,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
// make sure method is not native & not abstract
#ifdef ASSERT
-@@ -1236,7 +1320,7 @@ address InterpreterGenerator::generate_n
+@@ -1361,7 +1446,7 @@ address InterpreterGenerator::generate_n
}
Label continue_after_compile;
__ bind(continue_after_compile);
@@ -1754,7 +1648,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
bang_stack_shadow_pages(false);
// reset the _do_not_unlock_if_synchronized flag
-@@ -1446,6 +1530,9 @@ int AbstractInterpreter::layout_activati
+@@ -1573,6 +1658,9 @@ int AbstractInterpreter::layout_activati
assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable");
assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)");
#endif
@@ -1764,9 +1658,9 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
interpreter_frame->interpreter_frame_set_method(method);
// NOTE the difference in using sender_sp and interpreter_frame_sender_sp
-diff -r ce2272390558 src/cpu/x86/vm/templateTable_x86_32.cpp
---- a/src/cpu/x86/vm/templateTable_x86_32.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/cpu/x86/vm/templateTable_x86_32.cpp
+--- a/src/cpu/x86/vm/templateTable_x86_32.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -1699,6 +1699,23 @@ void TemplateTable::branch(bool is_jsr,
// invocation counter overflow
@@ -1807,33 +1701,33 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
-void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) {
+void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index, bool is_tail_call) {
assert(byte_no == 1 || byte_no == 2, "byte_no out of range");
-
- Register temp = rbx;
-@@ -2112,7 +2129,10 @@ void TemplateTable::resolve_cache_and_in
+ bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic);
+
+@@ -2113,7 +2130,10 @@ void TemplateTable::resolve_cache_and_in
const int shift_count = (1 + byte_no)*BitsPerByte;
Label resolved;
-- __ get_cache_and_index_at_bcp(Rcache, index, 1);
+- __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
+ if (is_tail_call)
-+ __ get_cache_and_index_at_bcp(Rcache, index, 2); // Skip the wide instruction.
++ __ get_cache_and_index_at_bcp(Rcache, index, 2, is_invokedynamic); // Skip the wide instruction.
+ else
-+ __ get_cache_and_index_at_bcp(Rcache, index, 1);
- __ movl(temp, Address(Rcache,
- index,
- Address::times_ptr,
-@@ -2139,7 +2159,10 @@ void TemplateTable::resolve_cache_and_in
++ __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
+ 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);
+@@ -2144,7 +2164,10 @@ void TemplateTable::resolve_cache_and_in
__ movl(temp, (int)bytecode());
__ call_VM(noreg, entry, temp);
// Update registers with resolved info
-- __ get_cache_and_index_at_bcp(Rcache, index, 1);
+- __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
+ if (is_tail_call)
-+ __ get_cache_and_index_at_bcp(Rcache, index, 2);
++ __ get_cache_and_index_at_bcp(Rcache, index, 2, is_invokedynamic);
+ else
-+ __ get_cache_and_index_at_bcp(Rcache, index, 1);
++ __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
__ bind(resolved);
}
-@@ -2169,6 +2192,7 @@ void TemplateTable::load_field_cp_cache_
+@@ -2174,6 +2197,7 @@ void TemplateTable::load_field_cp_cache_
}
void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
@@ -1841,7 +1735,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
Register method,
Register itable_index,
Register flags,
-@@ -2195,13 +2219,30 @@ void TemplateTable::load_invoke_cp_cache
+@@ -2200,13 +2224,30 @@ void TemplateTable::load_invoke_cp_cache
const int index_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
ConstantPoolCacheEntry::f2_offset());
@@ -1873,7 +1767,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
}
-@@ -2255,7 +2296,7 @@ void TemplateTable::getfield_or_static(i
+@@ -2260,7 +2301,7 @@ void TemplateTable::getfield_or_static(i
const Register off = rbx;
const Register flags = rax;
@@ -1882,7 +1776,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
jvmti_post_field_access(cache, index, is_static, false);
load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
-@@ -2464,7 +2505,7 @@ void TemplateTable::putfield_or_static(i
+@@ -2469,7 +2510,7 @@ void TemplateTable::putfield_or_static(i
const Register off = rbx;
const Register flags = rax;
@@ -1891,16 +1785,16 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
jvmti_post_field_mod(cache, index, is_static);
load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
-@@ -2884,7 +2925,7 @@ void TemplateTable::count_calls(Register
+@@ -2889,7 +2930,7 @@ void TemplateTable::count_calls(Register
}
--void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, Bytecodes::Code code) {
-+void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, Bytecodes::Code code, bool is_tail_call) {
- // determine flags
- const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
- const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
-@@ -2900,7 +2941,7 @@ void TemplateTable::prepare_invoke(Regis
+-void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
++void TemplateTable::prepare_invoke(Register method, Register index, int byte_no, bool is_tail_call) {
+ bool is_invdyn_bootstrap = (byte_no < 0);
+ if (is_invdyn_bootstrap) byte_no = -byte_no;
+
+@@ -2912,7 +2953,7 @@ void TemplateTable::prepare_invoke(Regis
// save 'interpreter return address'
__ save_bcp();
@@ -1909,19 +1803,28 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
// load receiver if needed (note: no return address pushed yet)
if (load_receiver) {
-@@ -2926,8 +2967,9 @@ void TemplateTable::prepare_invoke(Regis
+@@ -2943,14 +2984,14 @@ void TemplateTable::prepare_invoke(Regis
ConstantPoolCacheEntry::verify_tosBits();
// load return address
{
-- ExternalAddress table(is_invokeinterface ? (address)Interpreter::return_5_addrs_by_index_table() :
-- (address)Interpreter::return_3_addrs_by_index_table());
+ int instruction_size = is_invokeinterface ? 5 : 3;
+ if (is_tail_call) instruction_size += 1;
+ ExternalAddress table((address)Interpreter::return_addrs_by_index_table(instruction_size));
+ address table_addr;
+- if (is_invdyn_bootstrap)
++ if (is_invdyn_bootstrap) {
+ table_addr = (address)Interpreter::return_5_unbox_addrs_by_index_table();
+- else 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);
++ table = ExternalAddress(table_addr);
++ }
__ movptr(flags, ArrayAddress(table, Address(noreg, flags, Address::times_ptr)));
}
-@@ -2942,15 +2984,45 @@ void TemplateTable::prepare_invoke(Regis
+@@ -2965,15 +3006,46 @@ void TemplateTable::prepare_invoke(Regis
}
}
@@ -1935,10 +1838,11 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
+ __ verify_oop(klass);
+}
+
-+void TemplateTable::jcc_protection_domain_mismatch(Register temp, Register temp2, Register recv_meth, Label& mismatch_cont) {
++void TemplateTable::jcc_protection_domain_mismatch(Register temp, Register temp2, Register recv_method, Label& mismatch_cont) {
+ // Check protection domains.
-+ // Get receiver PD.
-+ load_pool_holder_of_method(recv_meth, temp);
++ // Get receiver method PD.
++ load_pool_holder_of_method(recv_method, temp);
++ __ verify_oop(temp);
+ __ movl (temp, Address(temp, instanceKlass::protection_domain_offset() * wordSize));
+ __ verify_oop(temp);
+ // Get caller PD.
@@ -1968,7 +1872,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
__ movl(rax, flags);
__ andl(rax, (1 << ConstantPoolCacheEntry::vfinalMethod));
__ jcc(Assembler::zero, notFinal);
-@@ -2966,8 +3038,16 @@ void TemplateTable::invokevirtual_helper
+@@ -2989,8 +3061,16 @@ void TemplateTable::invokevirtual_helper
// profile this call
__ profile_final_call(rax);
@@ -1977,7 +1881,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
+
+ // Prepare for tail call.
+ if (is_tail_call) {
-+ if(TailCallsStackCompression)
++ if (TailCallsStackCompression)
+ jcc_protection_domain_mismatch(rax, rdx, method, regular_call_continuation);
+ else
+ jcc_protection_domain_mismatch(rax, rdx, method, protection_domain_mismatch_cont);
@@ -1987,15 +1891,17 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
__ bind(notFinal);
-@@ -2984,41 +3064,220 @@ void TemplateTable::invokevirtual_helper
+@@ -3007,41 +3087,220 @@ void TemplateTable::invokevirtual_helper
const int base = instanceKlass::vtable_start_offset() * wordSize;
assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below");
__ movptr(method, Address(rax, index, Address::times_ptr, base + vtableEntry::method_offset_in_bytes()));
- __ jump_from_interpreted(method, rdx);
+-}
+-
+
+ if (is_tail_call) {
+ // Check protection domain.
-+ if(TailCallsStackCompression)
++ if (TailCallsStackCompression)
+ jcc_protection_domain_mismatch(rax, rdx, method, regular_call_continuation);
+ else
+ jcc_protection_domain_mismatch(rax, rdx, method, protection_domain_mismatch_cont);
@@ -2013,8 +1919,8 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
+ __ restore_bcp();
+ __ call_VM(noreg, CAST_FROM_FN_PTR(address,
+ InterpreterRuntime::throw_TailCallException));
- }
-
++}
++
+void TemplateTable::tail_call(int byte_no, Label& regular_call_continuation) {
+ Register temp = rdx;
+ // Only tail call if parent frame is interpreted. Otherwise we might have an
@@ -2090,23 +1996,25 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
void TemplateTable::invokevirtual(int byte_no) {
transition(vtos, vtos);
-- prepare_invoke(rbx, noreg, byte_no, bytecode());
-+ prepare_invoke(rbx, noreg, byte_no, bytecode(), false);
+- prepare_invoke(rbx, noreg, byte_no);
++ prepare_invoke(rbx, noreg, byte_no, false);
// rbx,: index
// rcx: receiver
// rdx: flags
- invokevirtual_helper(rbx, rcx, rdx);
+-}
+-
+ invokevirtual_helper(rbx, rcx, rdx, byte_no);
- }
-
++}
++
+void TemplateTable::wide_invokevirtual(int byte_no) {
+ transition(vtos, vtos);
+ // Bcp points to wide, advance to invoke instruction.
+ //__ increment(rsi, 1);
+ if (TraceTailCalls) __ warn("Interpreter: wide_invokevirtual");
-+ prepare_invoke(rbx, noreg, byte_no, bytecode(), true);
++ prepare_invoke(rbx, noreg, byte_no, true);
+ // rbx,: index
+ // rcx: receiver
+ // rdx: flags
@@ -2115,8 +2023,8 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
void TemplateTable::invokespecial(int byte_no) {
transition(vtos, vtos);
-- prepare_invoke(rbx, noreg, byte_no, bytecode());
-+ prepare_invoke(rbx, noreg, byte_no, bytecode(), false);
+- prepare_invoke(rbx, noreg, byte_no);
++ prepare_invoke(rbx, noreg, byte_no, false);
// do the call
__ verify_oop(rbx);
__ profile_call(rax);
@@ -2129,7 +2037,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
+ Label protection_domain_mismatch_cont;
+ //__ increment(rsi, 1);
+ if (TraceTailCalls) __ warn("Interpreter: wide_invokespecial");
-+ prepare_invoke(rbx, noreg, byte_no, bytecode(), true);
++ prepare_invoke(rbx, noreg, byte_no, true);
+ // do the call
+ __ verify_oop(rbx);
+ __ profile_call(rax);
@@ -2155,8 +2063,8 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
void TemplateTable::invokestatic(int byte_no) {
transition(vtos, vtos);
-- prepare_invoke(rbx, noreg, byte_no, bytecode());
-+ prepare_invoke(rbx, noreg, byte_no, bytecode(), false);
+- prepare_invoke(rbx, noreg, byte_no);
++ prepare_invoke(rbx, noreg, byte_no, false);
// do the call
__ verify_oop(rbx);
__ profile_call(rax);
@@ -2171,7 +2079,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
+ // Bcp points to wide, advance to invoke instruction.
+ //__ increment(rsi, 1);
+ if (TraceTailCalls) __ warn("Interpreter: wide_invokestatic");
-+ prepare_invoke(rbx, noreg, byte_no, bytecode(), true);
++ prepare_invoke(rbx, noreg, byte_no, true);
+ // do the call
+ __ verify_oop(rbx);
+ __ profile_call(rax);
@@ -2213,10 +2121,12 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
void TemplateTable::fast_invokevfinal(int byte_no) {
transition(vtos, vtos);
-@@ -3027,8 +3286,18 @@ void TemplateTable::fast_invokevfinal(in
+@@ -3050,8 +3309,19 @@ void TemplateTable::fast_invokevfinal(in
void TemplateTable::invokeinterface(int byte_no) {
+- transition(vtos, vtos);
+- prepare_invoke(rax, rbx, byte_no);
+ invokeinterface_helper(byte_no, false);
+}
+
@@ -2226,14 +2136,14 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
+}
+
+void TemplateTable::invokeinterface_helper(int byte_no, bool is_tail_call) {
- transition(vtos, vtos);
-- prepare_invoke(rax, rbx, byte_no, bytecode());
-+
-+ prepare_invoke(rax, rbx, byte_no, bytecode(), is_tail_call);
++ transition(vtos, vtos);
++
++
++ prepare_invoke(rax, rbx, byte_no, is_tail_call);
// rax,: Interface
// rbx,: index
-@@ -3044,7 +3313,7 @@ void TemplateTable::invokeinterface(int
+@@ -3067,7 +3337,7 @@ void TemplateTable::invokeinterface(int
__ andl(rdi, (1 << ConstantPoolCacheEntry::methodInterface));
__ jcc(Assembler::zero, notMethod);
@@ -2242,10 +2152,11 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
__ bind(notMethod);
// Get receiver klass into rdx - also a null check
-@@ -3123,10 +3392,43 @@ void TemplateTable::invokeinterface(int
- __ bind(L);
- }
-
+@@ -3095,10 +3365,30 @@ void TemplateTable::invokeinterface(int
+ __ testptr(rbx, rbx);
+ __ jcc(Assembler::zero, no_such_method);
+
++ // Move parameters and remove frame if this is a tail-call.
+ Label regular_call_continuation;
+ Label regular_call_continuation_pd_mismatch;
+ Label protection_domain_mismatch_cont;
@@ -2270,14 +2181,22 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
// rbx,: methodOop
- __ jump_from_interpreted(rbx, rdx);
+ __ jump_from_interpreted(rbx, rdx, is_tail_call);
-+ // not a tail call
+ __ should_not_reach_here();
+
+ // exception handling code follows...
+@@ -3123,6 +3413,21 @@ void TemplateTable::invokeinterface(int
+ InterpreterRuntime::throw_IncompatibleClassChangeError));
+ // the call_VM checks for exception, so we should never return here.
+ __ should_not_reach_here();
++
++ // Not a tail call.
+ __ bind (regular_call_continuation);
+ __ jump_from_interpreted(rbx, rax, false);
+ __ bind (regular_call_continuation_pd_mismatch);
+ __ pop(rdx);
+ __ pop(rax);
+ __ jump_from_interpreted(rbx, rax, false);
-+// Tail call exception on protection domain mismatch
++ // Tail call exception on protection domain mismatch.
+ __ bind(protection_domain_mismatch_cont);
+ __ pop(rdx);
+ __ pop(rax);
@@ -2286,17 +2205,34 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
+ InterpreterRuntime::throw_TailCallException));
}
- //----------------------------------------------------------------------------------------------------
-diff -r ce2272390558 src/cpu/x86/vm/templateTable_x86_32.hpp
---- a/src/cpu/x86/vm/templateTable_x86_32.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/templateTable_x86_32.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -22,10 +22,21 @@
+ void TemplateTable::invokedynamic(int byte_no) {
+@@ -3139,7 +3444,7 @@ void TemplateTable::invokedynamic(int by
+ return;
+ }
+
+- prepare_invoke(rax, rbx, byte_no);
++ prepare_invoke(rax, rbx, byte_no, false);
+
+ // rax: CallSite object (f1)
+ // rbx: unused (f2)
+@@ -3173,7 +3478,7 @@ void TemplateTable::invokedynamic(int by
+
+ // recompute return address
+ __ restore_bcp(); // rsi must be correct for prepare_invoke
+- prepare_invoke(rax, rbx, -byte_no); // smashes rcx, rdx
++ prepare_invoke(rax, rbx, -byte_no, false); // smashes rcx, rdx
+ // rax: CallSite object (f1)
+ // rbx: unused (f2)
+ // rdi: bootstrap MH
+diff -r aa0c48844632 src/cpu/x86/vm/templateTable_x86_32.hpp
+--- a/src/cpu/x86/vm/templateTable_x86_32.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/templateTable_x86_32.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -22,9 +22,21 @@
*
*/
-- static void prepare_invoke(Register method, Register index, int byte_no,
-- Bytecodes::Code code);
-+static void prepare_invoke(Register method, Register index, int byte_no, Bytecodes::Code code, bool is_tail_call);
+- static void prepare_invoke(Register method, Register index, int byte_no);
++ static void prepare_invoke(Register method, Register index, int byte_no, bool is_tail_call);
+
static void invokevirtual_helper(Register index, Register recv,
- Register flags);
@@ -2305,7 +2241,7 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
+ static void invokeinterface_helper(int byte_no, bool is_tail_call = false);
+
+ static void load_pool_holder_of_method(Register method, Register klass);
-+ static void jcc_protection_domain_mismatch(Register temp, Register temp2, Register recv_method, Label& mismatch_cont);
++ static void jcc_protection_domain_mismatch(Register temp, Register temp2, Register recv, Label& mismatch_cont);
+
+ static void tail_call(int byte_no, Label& regular_call_continuation);
+ // Tail call helper.
@@ -2315,12 +2251,12 @@ diff -r ce2272390558 src/cpu/x86/vm/temp
static void volatile_barrier(Assembler::Membar_mask_bits order_constraint );
// Helpers
-diff -r ce2272390558 src/cpu/x86/vm/vtableStubs_x86_32.cpp
---- a/src/cpu/x86/vm/vtableStubs_x86_32.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/vtableStubs_x86_32.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -39,9 +39,9 @@ extern "C" void bad_compiled_vtable_inde
- // Leave receiver in rcx; required behavior when +OptoArgsInRegisters
- // is modifed to put first oop in rcx.
+diff -r aa0c48844632 src/cpu/x86/vm/vtableStubs_x86_32.cpp
+--- a/src/cpu/x86/vm/vtableStubs_x86_32.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/vtableStubs_x86_32.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -45,9 +45,9 @@ extern "C" void bad_compiled_vtable_inde
+ // rsi, rdi
+ // Note that rax and rdx are also used for return values.
//
-VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
+VtableStub* VtableStubs::create_vtable_stub(int vtable_index, bool is_tail_call, bool is_sibling) {
@@ -2330,7 +2266,7 @@ diff -r ce2272390558 src/cpu/x86/vm/vtab
ResourceMark rm;
CodeBuffer cb(s->entry_point(), i486_code_length);
MacroAssembler* masm = new MacroAssembler(&cb);
-@@ -58,9 +58,27 @@ VtableStub* VtableStubs::create_vtable_s
+@@ -64,9 +64,27 @@ VtableStub* VtableStubs::create_vtable_s
// get receiver klass
address npe_addr = __ pc();
@@ -2341,7 +2277,7 @@ diff -r ce2272390558 src/cpu/x86/vm/vtab
int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
+
+ Label pd_mismatch;
-+ // Check protection domains match. Clobbers: rdi, rbx.
++ // check protection domains match
+ if (is_tail_call) {
+ // Protection domain slot [esp+4] contains caller klass.
+ __ movl(rbx, Address(rsp, wordSize));
@@ -2358,11 +2294,11 @@ diff -r ce2272390558 src/cpu/x86/vm/vtab
#ifndef PRODUCT
if (DebugVtables) {
Label L;
-@@ -77,11 +95,21 @@ VtableStub* VtableStubs::create_vtable_s
+@@ -83,11 +101,21 @@ VtableStub* VtableStubs::create_vtable_s
// load methodOop and target address
__ movptr(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes()));
-+
++
+ ByteSize method_entry_offset = in_ByteSize(0);
+ if (is_tail_call && is_sibling) {
+ method_entry_offset = methodOopDesc::from_compiled_tail_call_offset();
@@ -2381,7 +2317,7 @@ diff -r ce2272390558 src/cpu/x86/vm/vtab
__ jcc(Assembler::notZero, L);
__ stop("Vtable entry is NULL");
__ bind(L);
-@@ -91,7 +119,23 @@ VtableStub* VtableStubs::create_vtable_s
+@@ -97,7 +125,20 @@ VtableStub* VtableStubs::create_vtable_s
// method (rbx): methodOop
// rcx: receiver
address ame_addr = __ pc();
@@ -2390,51 +2326,50 @@ diff -r ce2272390558 src/cpu/x86/vm/vtab
+
+ if (is_tail_call) {
+ __ bind(pd_mismatch); // Protection domain mismatch.
-+ if (TraceTailCalls) __ warn("Protection domain mismatch in vtable stub");
-+ if (TailCallsStackCompression==false) {
-+ // Throw exception.
++ if (TraceTailCalls) __ warn ("vtable tail call pd mismatch");
++ if (TailCallsStackCompression) {
++ // Jump to normal method entry. TODO: Need new exception point.
++ __ movptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes()));
++ __ movptr(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes()));
++ __ jmp(Address(method, methodOopDesc::from_compiled_offset()));
++ } else {
+ __ jump(RuntimeAddress(StubRoutines::throw_TailCallException_entry()));
-+ } else {
-+ // Vtable call - don't tail call.
-+ __ movptr(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes()));
-+ if (is_sibling)
-+ __ jmp( Address(method, methodOopDesc::from_compiled_pd_mismatch_offset()));
-+ else
-+ __ jmp( Address(method, methodOopDesc::from_compiled_offset()));
+ }
+ }
masm->flush();
- s->set_exception_points(npe_addr, ame_addr);
-@@ -99,11 +143,11 @@ VtableStub* VtableStubs::create_vtable_s
+
+@@ -117,11 +158,11 @@ VtableStub* VtableStubs::create_vtable_s
}
--VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
-+VtableStub* VtableStubs::create_itable_stub(int vtable_index, bool is_tail_call, bool is_sibling) {
+-VtableStub* VtableStubs::create_itable_stub(int itable_index) {
++VtableStub* VtableStubs::create_itable_stub(int itable_index, bool is_tail_call, bool is_sibling) {
// Note well: pd_code_size_limit is the absolute minimum we can get away with. If you
// add code here, bump the code stub size returned by pd_code_size_limit!
const int i486_code_length = VtableStub::pd_code_size_limit(false);
-- VtableStub* s = new(i486_code_length) VtableStub(false, vtable_index);
-+ VtableStub* s = new(i486_code_length) VtableStub(false, vtable_index, is_tail_call, is_sibling);
+- VtableStub* s = new(i486_code_length) VtableStub(false, itable_index);
++ VtableStub* s = new(i486_code_length) VtableStub(false, itable_index, is_tail_call, is_sibling);
ResourceMark rm;
CodeBuffer cb(s->entry_point(), i486_code_length);
MacroAssembler* masm = new MacroAssembler(&cb);
-@@ -123,6 +167,13 @@ VtableStub* VtableStubs::create_itable_s
-
+@@ -139,8 +180,15 @@ VtableStub* VtableStubs::create_itable_s
+
+ assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");
+
++#ifdef COMPILER2
++ if (is_tail_call) {
++ __ push(rsi); // Opto tail calls store the base pointer in rsi.
++ }
++#endif
++
// get receiver klass (also an implicit null-check)
address npe_addr = __ pc();
+
-+#ifdef COMPILER2
-+ if (is_tail_call) {
-+ __ movl(rdi, rsi); // Opto tail calls store the base pointer in rsi.
-+ }
-+#endif
-+
- __ movptr(rbx, Address(rcx, oopDesc::klass_offset_in_bytes()));
-
- __ mov(rsi, rbx); // Save klass in free register
-@@ -170,21 +221,49 @@ VtableStub* VtableStubs::create_itable_s
+ __ movptr(rsi, Address(rcx, oopDesc::klass_offset_in_bytes()));
+
+ // Most registers are in use; we'll use rax, rbx, rsi, rdi
+@@ -157,25 +205,63 @@ VtableStub* VtableStubs::create_itable_s
// method (rbx): methodOop
// rcx: receiver
@@ -2463,7 +2398,7 @@ diff -r ce2272390558 src/cpu/x86/vm/vtab
+#ifdef COMPILER2
+ if (is_tail_call) {
+ // restore rsi (contains base pointer for tail calls).
-+ __ movl (rsi, rdi);
++ __ pop(rsi);
+ }
+#endif
+
@@ -2485,29 +2420,22 @@ diff -r ce2272390558 src/cpu/x86/vm/vtab
+ __ jmp(Address(method, method_entry_offset));
__ bind(throw_icce);
- // Restore saved register
-@@ -192,6 +271,20 @@ VtableStub* VtableStubs::create_itable_s
__ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
-
masm->flush();
+
+ if (is_tail_call) {
+ __ bind(pd_mismatch); // Protection domain mismatch.
-+ if (TraceTailCalls) __ warn("Protection domain mismatch in itable stub");
-+ if (TailCallsStackCompression==false) {
++ if (TraceTailCalls) __ warn("itable tail call pd mismatch");
++ if (TailCallsStackCompression) {
++ __ jmp(Address(method, methodOopDesc::from_compiled_offset()));
++ } else {
+ __ jump(RuntimeAddress(StubRoutines::throw_TailCallException_entry()));
-+ } else {
-+ // Regular call - don't tail call.
-+ if (is_sibling)
-+ __ jmp( Address(method, methodOopDesc::from_compiled_pd_mismatch_offset()));
-+ else
-+ __ jmp( Address(method, methodOopDesc::from_compiled_offset()));
-+ }
-+ }
-
- guarantee(__ pc() <= s->code_end(), "overflowed buffer");
-
-@@ -204,10 +297,12 @@ int VtableStub::pd_code_size_limit(bool
++ }
++ }
+
+ if (PrintMiscellaneous && (WizardMode || Verbose)) {
+ tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
+@@ -197,10 +283,12 @@ int VtableStub::pd_code_size_limit(bool
int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
if (is_vtable_stub) {
// Vtable stub size
@@ -2517,14 +2445,14 @@ diff -r ce2272390558 src/cpu/x86/vm/vtab
+ return (TailCalls ? 256 : 0) + (DebugVtables ? 210 : 16) + (CountCompiledCalls ? 6 : 0);
} else {
// Itable stub size
-- return (DebugVtables ? 144 : 64) + (CountCompiledCalls ? 6 : 0);
-+ return (TailCalls ? 256 : 0) +(DebugVtables ? 144 : 64) + (CountCompiledCalls ? 6 : 0);
+- return (DebugVtables ? 256 : 66) + (CountCompiledCalls ? 6 : 0);
++ return (TailCalls ? 256+128 : 0) +(DebugVtables ? 144 : 64+16) + (CountCompiledCalls ? 6 : 0);
}
- }
-
-diff -r ce2272390558 src/cpu/x86/vm/x86_32.ad
---- a/src/cpu/x86/vm/x86_32.ad Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/cpu/x86/vm/x86_32.ad Mon Mar 16 11:42:47 2009 +0100
+ // In order to tune these parameters, run the JVM with VM options
+ // +PrintMiscellaneous and +WizardMode to see information about
+diff -r aa0c48844632 src/cpu/x86/vm/x86_32.ad
+--- a/src/cpu/x86/vm/x86_32.ad Thu May 14 10:57:58 2009 -0700
++++ b/src/cpu/x86/vm/x86_32.ad Thu Jun 04 10:20:29 2009 +0200
@@ -272,11 +272,11 @@ static jlong *double_signflip_pool = dou
// from the start of the call to the point where the return address
// will point.
@@ -2604,7 +2532,7 @@ diff -r ce2272390558 src/cpu/x86/vm/x86_
return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call
}
-@@ -1236,6 +1274,329 @@ uint size_deopt_handler() {
+@@ -1236,6 +1274,283 @@ uint size_deopt_handler() {
// Note that this value is also credited (in output.cpp) to
// the size of the code section.
return 5 + NativeJump::instruction_size; // pushl(); jmp;
@@ -2718,58 +2646,6 @@ diff -r ce2272390558 src/cpu/x86/vm/x86_
+ __ end_a_stub();
+}
+
-+void emit_pd_mismatch_verified_tail_call_stub(Compile * C, CodeBuffer& cbuf, int arg_slots, int frame_size, CodeOffsets & code_offsets) {
-+ MacroAssembler _masm(&cbuf);
-+ int stub_size = size_verified_tail_call_stub(arg_slots);
-+ address handler_base = __ start_a_stub(stub_size);
-+ if (handler_base == NULL) {
-+ // not enough space left for the handler
-+ return;
-+ }
-+#ifdef ASSERT
-+ int offset = __ offset();
-+#endif // ASSERT
-+
-+ code_offsets.set_value(CodeOffsets::Verified_Tail_Call_Move_Arguments, __ offset());
-+ if (TraceTailCalls) __ warn("verified tail call pd mismatch stub");
-+ // Compute target of jump. Verified entry point of current method.
-+ address vep_entry = cbuf.insts()->start() + code_offsets.value(CodeOffsets::Verified_Entry);
-+ RelocationHolder rh = section_call_Relocation::spec(vep_entry, CodeBuffer::SECT_INSTS);
-+ // Move arguments.
-+ __ move_args_to_outgoing_area(rsi, rsp, rbx, arg_slots, SharedRuntime::tail_call_protection_domain_slots());
-+ // Jump to vep.
-+ __ jump(AddressLiteral((address)vep_entry, rh));
-+ // TODO: adapt static_tail_call_stub_size
-+ assert(__ offset() - offset <= stub_size, "opto overflow");
-+ __ end_a_stub();
-+}
-+
-+void emit_pd_mismatch_tail_call_stub(Compile * C, CodeBuffer& cbuf, int arg_slots, int frame_size, CodeOffsets & code_offsets) {
-+ MacroAssembler _masm(&cbuf);
-+ int stub_size = size_verified_tail_call_stub(arg_slots);
-+ address handler_base = __ start_a_stub(stub_size);
-+ if (handler_base == NULL) {
-+ // not enough space left for the handler
-+ return;
-+ }
-+#ifdef ASSERT
-+ int offset = __ offset();
-+#endif // ASSERT
-+
-+ code_offsets.set_value(CodeOffsets::Tail_Call_Move_Arguments, __ offset());
-+ if (TraceTailCalls) __ warn("verified tail call pd mismatch stub");
-+ // Compute target of jump. Unverified entry point of current method.
-+ address uep_entry = cbuf.insts()->start() + code_offsets.value(CodeOffsets::Entry);
-+ RelocationHolder rh = section_call_Relocation::spec(uep_entry, CodeBuffer::SECT_INSTS);
-+ // Move arguments.
-+ __ move_args_to_outgoing_area(rsi, rsp, rbx, arg_slots, SharedRuntime::tail_call_protection_domain_slots());
-+ // Jump to uep.
-+ __ jump(AddressLiteral((address)uep_entry, rh));
-+ // TODO: adapt static_tail_call_stub_size
-+ assert(__ offset() - offset <= stub_size, "opto overflow");
-+ __ end_a_stub();
-+}
-+
+void emit_verified_tail_call_stub(Compile * C, CodeBuffer& cbuf, int arg_slots, int frame_size, CodeOffsets & code_offsets) {
+ MacroAssembler _masm(&cbuf);
+ int stub_size = size_verified_tail_call_stub(arg_slots);
@@ -2792,7 +2668,10 @@ diff -r ce2272390558 src/cpu/x86/vm/x86_
+ MacroAssembler masm(&cbuf);
+ masm.generate_stack_overflow_check(frame_size);
+ }
-+ // Remove stack frame.
++ // Move arguments.
++ emit_tail_call_argument_move(_masm, arg_slots);
++ // Remove tail calling caller's stack frame.
++ //tail_call_leave(_masm);
+ __ leal(rsp, Address(rsi, -frame_size));
+ // Compute target of jump. Verified entry point of current method.
+ address vep_entry = cbuf.insts()->start() +
@@ -2918,7 +2797,10 @@ diff -r ce2272390558 src/cpu/x86/vm/x86_
+ MacroAssembler masm(&cbuf);
+ masm.generate_stack_overflow_check(frame_size);
+ }
++ // Move arguments.
++ emit_tail_call_argument_move(_masm, arg_slots);
+ // Remove tail calling caller's stack frame.
++ //tail_call_leave(_masm);
+ __ leal(rsp, Address(rsi, -frame_size));
+
+ // Compute target of jump. Verified entry point of current method.
@@ -2934,7 +2816,7 @@ diff -r ce2272390558 src/cpu/x86/vm/x86_
}
// Emit deopt handler code.
-@@ -1789,37 +2150,94 @@ encode %{
+@@ -1782,37 +2097,94 @@ encode %{
enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
// who we intended to call.
@@ -3047,7 +2929,7 @@ diff -r ce2272390558 src/cpu/x86/vm/x86_
%}
enc_class Java_Compiled_Call (method meth) %{ // JAVA COMPILED CALL
-@@ -4564,8 +4982,8 @@ frame %{
+@@ -4819,8 +5191,8 @@ frame %{
// a new frame. The PROLOG must add this many slots to the stack. The
// EPILOG must remove this many slots. Intel needs one slot for
// return address and one for rbp, (must save rbp)
@@ -3057,9 +2939,20 @@ diff -r ce2272390558 src/cpu/x86/vm/x86_
// Number of outgoing stack slots killed above the out_preserve_stack_slots
// for calls to C. Supports the var-args backing area for register parms.
varargs_C_out_slots_killed(0);
-diff -r ce2272390558 src/os_cpu/linux_x86/vm/os_linux_x86.cpp
---- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/os/solaris/vm/os_solaris.cpp
+--- a/src/os/solaris/vm/os_solaris.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/os/solaris/vm/os_solaris.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -3803,6 +3803,7 @@ int set_lwp_priority (int ThreadID,
+ int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
+ iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
+ iaInfo->ia_uprilim = IA_NOCHANGE;
++ iaInfo->ia_nice = IA_NOCHANGE;
+ iaInfo->ia_mode = IA_NOCHANGE;
+ if (ThreadPriorityVerbose) {
+ tty->print_cr ("IA: [%d...%d] %d->%d\n",
+diff -r aa0c48844632 src/os_cpu/linux_x86/vm/os_linux_x86.cpp
+--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -261,7 +261,7 @@ JVM_handle_linux_signal(int sig,
// check if fault address is within thread stack
@@ -3069,28 +2962,17 @@ diff -r ce2272390558 src/os_cpu/linux_x8
// stack overflow
if (thread->in_stack_yellow_zone(addr)) {
thread->disable_stack_yellow_zone();
-diff -r ce2272390558 src/share/tools/hsdis/Makefile
---- a/src/share/tools/hsdis/Makefile Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/tools/hsdis/Makefile Mon Mar 16 11:42:47 2009 +0100
-@@ -65,6 +65,7 @@ OS = linux
- OS = linux
- CC = gcc
- CCFLAGS += -O
-+LDFLAGS += -ldl
- DLDFLAGS += -shared
- OUTFLAGS += -o $@
- LIB_EXT = .so
-diff -r ce2272390558 src/share/tools/hsdis/hsdis-demo.c
---- a/src/share/tools/hsdis/hsdis-demo.c Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/tools/hsdis/hsdis-demo.c Mon Mar 16 11:42:47 2009 +0100
-@@ -221,3 +221,4 @@ void disassemble(void* from, void* to) {
+diff -r aa0c48844632 src/share/tools/hsdis/hsdis-demo.c
+--- a/src/share/tools/hsdis/hsdis-demo.c Thu May 14 10:57:58 2009 -0700
++++ b/src/share/tools/hsdis/hsdis-demo.c Thu Jun 04 10:20:29 2009 +0200
+@@ -209,3 +209,4 @@ void disassemble(void* from, void* to) {
if (res != to)
printf("*** Result was %p!\n", res);
}
+
-diff -r ce2272390558 src/share/tools/hsdis/hsdis.c
---- a/src/share/tools/hsdis/hsdis.c Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/tools/hsdis/hsdis.c Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/tools/hsdis/hsdis.c
+--- a/src/share/tools/hsdis/hsdis.c Thu May 14 10:57:58 2009 -0700
++++ b/src/share/tools/hsdis/hsdis.c Thu Jun 04 10:20:29 2009 +0200
@@ -29,6 +29,7 @@
#include "hsdis.h"
@@ -3099,18 +2981,18 @@ diff -r ce2272390558 src/share/tools/hsd
#include <sysdep.h>
#include <libiberty.h>
#include <bfd.h>
-diff -r ce2272390558 src/share/tools/hsdis/hsdis.h
---- a/src/share/tools/hsdis/hsdis.h Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/tools/hsdis/hsdis.h Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/tools/hsdis/hsdis.h
+--- a/src/share/tools/hsdis/hsdis.h Thu May 14 10:57:58 2009 -0700
++++ b/src/share/tools/hsdis/hsdis.h Thu Jun 04 10:20:29 2009 +0200
@@ -65,3 +65,4 @@ typedef void* (*decode_instructions_ftyp
decode_instructions_printf_callback_ftype printf_callback,
void* printf_stream,
const char* options);
+
-diff -r ce2272390558 src/share/vm/asm/codeBuffer.hpp
---- a/src/share/vm/asm/codeBuffer.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/asm/codeBuffer.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -39,6 +39,14 @@ public:
+diff -r aa0c48844632 src/share/vm/asm/codeBuffer.hpp
+--- a/src/share/vm/asm/codeBuffer.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/asm/codeBuffer.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -39,6 +39,12 @@ public:
Dtrace_trap = OSR_Entry, // dtrace probes can never have an OSR entry so reuse it
Exceptions, // Offset where exception handler lives
Deopt, // Offset where deopt handler lives
@@ -3120,12 +3002,10 @@ diff -r ce2272390558 src/share/vm/asm/co
+ Not_Sibling_Tail_Call_Entry,
+ Verified_Not_Sibling_Tail_Call_Set_Data_Entry,
+ Not_Sibling_Tail_Call_Set_Data_Entry,
-+ Tail_Call_Move_Arguments, // Move arguments in case of a pd check failure.
-+ Verified_Tail_Call_Move_Arguments,
max_Entries };
// special value to note codeBlobs where profile (forte) stack walking is
-@@ -57,6 +65,14 @@ public:
+@@ -57,6 +63,12 @@ public:
_values[OSR_Entry] = 0;
_values[Exceptions] = -1;
_values[Deopt] = -1;
@@ -3135,20 +3015,17 @@ diff -r ce2272390558 src/share/vm/asm/co
+ _values[Verified_Not_Sibling_Tail_Call_Entry] = 0;
+ _values[Verified_Not_Sibling_Tail_Call_Set_Data_Entry] = 0;
+ _values[Not_Sibling_Tail_Call_Set_Data_Entry] = 0;
-+ _values[Verified_Tail_Call_Move_Arguments] = 0;
-+ _values[Tail_Call_Move_Arguments] = 0;
}
int value(Entries e) { return _values[e]; }
-diff -r ce2272390558 src/share/vm/c1/c1_Compilation.cpp
---- a/src/share/vm/c1/c1_Compilation.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_Compilation.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -218,8 +218,19 @@ void Compilation::emit_code_epilog(LIR_A
+diff -r aa0c48844632 src/share/vm/c1/c1_Compilation.cpp
+--- a/src/share/vm/c1/c1_Compilation.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_Compilation.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -218,7 +218,14 @@ void Compilation::emit_code_epilog(LIR_A
CHECK_BAILOUT();
assembler->emit_deopt_handler();
CHECK_BAILOUT();
-
-- // done
+ assembler->emit_static_tail_call_stub();
+ CHECK_BAILOUT();
+ assembler->emit_monomorphic_tail_call_stub();
@@ -3157,15 +3034,10 @@ diff -r ce2272390558 src/share/vm/c1/c1_
+ CHECK_BAILOUT();
+ assembler->emit_static_not_sibling_tail_call_stub();
+ CHECK_BAILOUT();
-+ assembler->emit_verified_tail_call_pd_mismatch_stub();
-+ CHECK_BAILOUT();
-+ assembler->emit_tail_call_pd_mismatch_stub();
-+ CHECK_BAILOUT();
-+// done
+ // done
masm()->flush();
}
-
-@@ -274,8 +285,13 @@ int Compilation::compile_java_method() {
+@@ -274,8 +281,13 @@ int Compilation::compile_java_method() {
{
PhaseTraceTime timeit(_t_emit_lir);
@@ -3181,9 +3053,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
emit_lir();
}
CHECK_BAILOUT_(no_frame_size);
-diff -r ce2272390558 src/share/vm/c1/c1_FrameMap.cpp
---- a/src/share/vm/c1/c1_FrameMap.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_FrameMap.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_FrameMap.cpp
+--- a/src/share/vm/c1/c1_FrameMap.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_FrameMap.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -49,7 +49,7 @@ BasicTypeArray* FrameMap::signature_type
}
@@ -3193,20 +3065,15 @@ diff -r ce2272390558 src/share/vm/c1/c1_
// compute the size of the arguments first. The signature array
// that java_calling_convention takes includes a T_VOID after double
// work items but our signatures do not.
-@@ -76,12 +76,18 @@ CallingConvention* FrameMap::java_callin
+@@ -76,12 +76,14 @@ CallingConvention* FrameMap::java_callin
BasicType t = sig_bt[i];
assert(t != T_VOID, "should be skipping these");
- LIR_Opr opr = map_to_opr(t, regs + i, outgoing);
+ LIR_Opr opr = map_to_opr(t, regs + i, outgoing, is_tail_call);
-+ LIR_Opr opr_not_tail_call = map_to_opr(t, regs+i, outgoing, false);
args->append(opr);
if (opr->is_address()) {
-- LIR_Address* addr = opr->as_address_ptr();
-+ // Use not tail call version to compute out_preserve.
-+ LIR_Address* addr = is_tail_call ?
-+ opr_not_tail_call->as_address_ptr() :
-+ opr->as_address_ptr();
+ LIR_Address* addr = opr->as_address_ptr();
assert(addr->disp() == (int)addr->disp(), "out of range value");
+ assert(MAX2(out_preserve, (intptr_t)addr->disp() / 4) == out_preserve, "c1 different from java_call_conv");
out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4);
@@ -3214,7 +3081,7 @@ diff -r ce2272390558 src/share/vm/c1/c1_
}
i += type2size[t];
}
-@@ -90,7 +96,10 @@ CallingConvention* FrameMap::java_callin
+@@ -90,7 +92,10 @@ CallingConvention* FrameMap::java_callin
if (outgoing) {
// update the space reserved for arguments.
@@ -3226,7 +3093,7 @@ diff -r ce2272390558 src/share/vm/c1/c1_
}
return new CallingConvention(args, out_preserve);
}
-@@ -161,7 +170,8 @@ FrameMap::FrameMap(ciMethod* method, int
+@@ -161,7 +166,8 @@ FrameMap::FrameMap(ciMethod* method, int
assert(monitors >= 0, "not set");
_num_monitors = monitors;
assert(reserved_argument_area_size >= 0, "not set");
@@ -3236,9 +3103,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
_argcount = method->arg_size();
_argument_locations = new intArray(_argcount, -1);
-diff -r ce2272390558 src/share/vm/c1/c1_FrameMap.hpp
---- a/src/share/vm/c1/c1_FrameMap.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_FrameMap.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_FrameMap.hpp
+--- a/src/share/vm/c1/c1_FrameMap.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_FrameMap.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -144,7 +144,7 @@ class FrameMap : public CompilationResou
// stack addresses are expressable in a simm13.
bool validate_frame();
@@ -3257,9 +3124,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
// deopt support
ByteSize sp_offset_for_orig_pc() { return sp_offset_for_monitor_base(_num_monitors); }
-diff -r ce2272390558 src/share/vm/c1/c1_GraphBuilder.cpp
---- a/src/share/vm/c1/c1_GraphBuilder.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_GraphBuilder.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_GraphBuilder.cpp
+--- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_GraphBuilder.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -1504,6 +1504,8 @@ Dependencies* GraphBuilder::dependency_r
void GraphBuilder::invoke(Bytecodes::Code code) {
@@ -3269,7 +3136,7 @@ diff -r ce2272390558 src/share/vm/c1/c1_
ciMethod* target = stream()->get_method(will_link);
// we have to make sure the argument size (incl. the receiver)
// is correct for compilation (the call would fail later during
-@@ -1718,7 +1720,7 @@ void GraphBuilder::invoke(Bytecodes::Cod
+@@ -1723,7 +1725,7 @@ void GraphBuilder::invoke(Bytecodes::Cod
profile_call(recv, target_klass);
}
@@ -3278,7 +3145,7 @@ diff -r ce2272390558 src/share/vm/c1/c1_
// push result
append_split(result);
-@@ -3332,7 +3334,7 @@ bool GraphBuilder::try_inline_full(ciMet
+@@ -3338,7 +3340,7 @@ bool GraphBuilder::try_inline_full(ciMet
!InlineSynchronizedMethods ) INLINE_BAILOUT("callee is synchronized");
if (!callee->holder()->is_initialized()) INLINE_BAILOUT("callee's klass not initialized yet");
if (!callee->has_balanced_monitors()) INLINE_BAILOUT("callee's monitors do not match");
@@ -3287,9 +3154,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
// Proper inlining of methods with jsrs requires a little more work.
if (callee->has_jsrs() ) INLINE_BAILOUT("jsrs not handled properly by inliner yet");
-diff -r ce2272390558 src/share/vm/c1/c1_Instruction.cpp
---- a/src/share/vm/c1/c1_Instruction.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_Instruction.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_Instruction.cpp
+--- a/src/share/vm/c1/c1_Instruction.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_Instruction.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -334,7 +334,7 @@ void Intrinsic::state_values_do(void f(V
@@ -3308,9 +3175,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
assert(args != NULL, "args must exist");
#ifdef ASSERT
values_do(assert_value);
-diff -r ce2272390558 src/share/vm/c1/c1_Instruction.hpp
---- a/src/share/vm/c1/c1_Instruction.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_Instruction.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_Instruction.hpp
+--- a/src/share/vm/c1/c1_Instruction.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_Instruction.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -312,7 +312,8 @@ class Instruction: public CompilationRes
NeedsPatchingFlag,
ThrowIncompatibleClassChangeErrorFlag,
@@ -3340,9 +3207,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
// generic
virtual bool can_trap() const { return true; }
-diff -r ce2272390558 src/share/vm/c1/c1_LIR.hpp
---- a/src/share/vm/c1/c1_LIR.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_LIR.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_LIR.hpp
+--- a/src/share/vm/c1/c1_LIR.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_LIR.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -1032,25 +1032,28 @@ class LIR_OpJavaCall: public LIR_OpCall
private:
ciMethod* _method;
@@ -3406,9 +3273,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
}
void get_thread(LIR_Opr result) { append(new LIR_Op0(lir_get_thread, result)); }
-diff -r ce2272390558 src/share/vm/c1/c1_LIRAssembler.cpp
---- a/src/share/vm/c1/c1_LIRAssembler.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_LIRAssembler.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_LIRAssembler.cpp
+--- a/src/share/vm/c1/c1_LIRAssembler.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_LIRAssembler.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -411,10 +411,11 @@ void LIR_Assembler::emit_rtcall(LIR_OpRT
void LIR_Assembler::emit_call(LIR_OpJavaCall* op) {
@@ -3441,10 +3308,10 @@ diff -r ce2272390558 src/share/vm/c1/c1_
offsets()->set_value(CodeOffsets::OSR_Entry, _masm->offset());
_masm->align(CodeEntryAlignment);
if (needs_icache(compilation()->method())) {
-diff -r ce2272390558 src/share/vm/c1/c1_LIRAssembler.hpp
---- a/src/share/vm/c1/c1_LIRAssembler.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_LIRAssembler.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -129,6 +129,12 @@ class LIR_Assembler: public CompilationR
+diff -r aa0c48844632 src/share/vm/c1/c1_LIRAssembler.hpp
+--- a/src/share/vm/c1/c1_LIRAssembler.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_LIRAssembler.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -129,6 +129,10 @@ class LIR_Assembler: public CompilationR
// stubs
void emit_slow_case_stubs();
void emit_static_call_stub();
@@ -3452,12 +3319,10 @@ diff -r ce2272390558 src/share/vm/c1/c1_
+ void emit_static_not_sibling_tail_call_stub();
+ void emit_monomorphic_tail_call_stub();
+ void emit_not_sibling_monomorphic_tail_call_stub();
-+ void emit_tail_call_pd_mismatch_stub();
-+ void emit_verified_tail_call_pd_mismatch_stub();
void emit_code_stub(CodeStub* op);
void add_call_info_here(CodeEmitInfo* info) { add_call_info(code_offset(), info); }
-@@ -205,7 +211,10 @@ class LIR_Assembler: public CompilationR
+@@ -205,7 +209,10 @@ class LIR_Assembler: public CompilationR
void comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr result, LIR_Op2* op);
void cmove(LIR_Condition code, LIR_Opr left, LIR_Opr right, LIR_Opr result);
@@ -3469,7 +3334,7 @@ diff -r ce2272390558 src/share/vm/c1/c1_
void vtable_call(int vtable_offset, CodeEmitInfo* info);
void call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info);
-@@ -217,7 +226,7 @@ class LIR_Assembler: public CompilationR
+@@ -217,7 +224,7 @@ class LIR_Assembler: public CompilationR
void monitor_address(int monitor_ix, LIR_Opr dst);
void align_backward_branch_target();
@@ -3478,9 +3343,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
void negate(LIR_Opr left, LIR_Opr dest);
void leal(LIR_Opr left, LIR_Opr dest);
-diff -r ce2272390558 src/share/vm/c1/c1_LIRGenerator.cpp
---- a/src/share/vm/c1/c1_LIRGenerator.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_LIRGenerator.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_LIRGenerator.cpp
+--- a/src/share/vm/c1/c1_LIRGenerator.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_LIRGenerator.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -2257,6 +2257,18 @@ void LIRGenerator::do_OsrEntry(OsrEntry*
__ move(LIR_Assembler::osrBufferPointer(), result);
}
@@ -3535,37 +3400,16 @@ diff -r ce2272390558 src/share/vm/c1/c1_
CallingConvention* cc = frame_map()->java_calling_convention(x->signature(), true);
+ bool is_tail = x->is_tail_call();
+ bool is_sibling = is_tail? is_sibling_call(cc) : false;
-+ CallingConvention* cc_tail = frame_map()->java_calling_convention(x->signature(), true, is_sibling);
-+ cc = is_sibling ? cc_tail : cc;
++ //CallingConvention* cc_tail = frame_map()->java_calling_convention(x->signature(), true, is_sibling);
++ //cc = is_sibling ? cc_tail : cc;
LIR_OprList* arg_list = cc->args();
- LIRItemList* args = invoke_visit_arguments(x);
-+ LIRItemList* args = invoke_visit_arguments(x, is_sibling);
++ LIRItemList* args = invoke_visit_arguments(x, false);
LIR_Opr receiver = LIR_OprFact::illegalOpr;
// setup result register
-@@ -2346,12 +2372,19 @@ void LIRGenerator::do_Invoke(Invoke* x)
-
- CodeEmitInfo* info = state_for(x, x->state());
-
-- invoke_load_arguments(x, args, arg_list);
-+ // Sibling tail calls need to load the receiver before the other arguments.
-+ // Otherwise the source (i.e the incoming parameter stack slot) might already
-+ // be overwritten by an (outgoing) parameter move.
-+ if (!is_sibling)
-+ invoke_load_arguments(x, args, arg_list);
-
- if (x->has_receiver()) {
- args->at(0)->load_item_force(LIR_Assembler::receiverOpr());
- receiver = args->at(0)->result();
- }
-+
-+ if (is_sibling)
-+ invoke_load_arguments(x, args, arg_list);
-
- // emit invoke code
- bool optimized = x->target_is_loaded() && x->target_is_final();
-@@ -2359,9 +2392,19 @@ void LIRGenerator::do_Invoke(Invoke* x)
+@@ -2359,9 +2385,19 @@ void LIRGenerator::do_Invoke(Invoke* x)
switch (x->code()) {
case Bytecodes::_invokestatic:
@@ -3588,7 +3432,7 @@ diff -r ce2272390558 src/share/vm/c1/c1_
break;
case Bytecodes::_invokespecial:
case Bytecodes::_invokevirtual:
-@@ -2369,13 +2412,32 @@ void LIRGenerator::do_Invoke(Invoke* x)
+@@ -2369,13 +2405,32 @@ void LIRGenerator::do_Invoke(Invoke* x)
// for final target we still produce an inline cache, in order
// to be able to call mixed mode
if (x->code() == Bytecodes::_invokespecial || optimized) {
@@ -3626,9 +3470,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
} else {
int entry_offset = instanceKlass::vtable_start_offset() + x->vtable_index() * vtableEntry::size();
int vtable_offset = entry_offset * wordSize + vtableEntry::method_offset_in_bytes();
-diff -r ce2272390558 src/share/vm/c1/c1_LIRGenerator.hpp
---- a/src/share/vm/c1/c1_LIRGenerator.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_LIRGenerator.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_LIRGenerator.hpp
+--- a/src/share/vm/c1/c1_LIRGenerator.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_LIRGenerator.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -30,6 +30,7 @@ class Invoke;
class Invoke;
class SwitchRange;
@@ -3649,9 +3493,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
void trace_block_entry(BlockBegin* block);
-diff -r ce2272390558 src/share/vm/c1/c1_Runtime1.cpp
---- a/src/share/vm/c1/c1_Runtime1.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/c1/c1_Runtime1.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/c1/c1_Runtime1.cpp
+--- a/src/share/vm/c1/c1_Runtime1.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/c1/c1_Runtime1.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -140,9 +140,18 @@ void Runtime1::setup_code_buffer(CodeBuf
locs_buffer_size / sizeof(relocInfo));
code->initialize_consts_size(desired_max_constant_size());
@@ -3672,9 +3516,9 @@ diff -r ce2272390558 src/share/vm/c1/c1_
}
-diff -r ce2272390558 src/share/vm/ci/ciMethod.cpp
---- a/src/share/vm/ci/ciMethod.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/ci/ciMethod.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/ci/ciMethod.cpp
+--- a/src/share/vm/ci/ciMethod.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/ci/ciMethod.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -49,6 +49,9 @@ ciMethod::ciMethod(methodHandle h_m) : c
_handler_count = h_m()->exception_table()->length() / 4;
_uses_monitors = h_m()->access_flags().has_monitor_bytecodes();
@@ -3742,9 +3586,9 @@ diff -r ce2272390558 src/share/vm/ci/ciM
}
return true;
}
-diff -r ce2272390558 src/share/vm/ci/ciMethod.hpp
---- a/src/share/vm/ci/ciMethod.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/ci/ciMethod.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/ci/ciMethod.hpp
+--- a/src/share/vm/ci/ciMethod.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/ci/ciMethod.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -62,6 +62,8 @@ class ciMethod : public ciObject {
bool _balanced_monitors;
bool _is_compilable;
@@ -3762,9 +3606,9 @@ diff -r ce2272390558 src/share/vm/ci/ciM
MethodLivenessResult liveness_at_bci(int bci);
-diff -r ce2272390558 src/share/vm/ci/ciStreams.cpp
---- a/src/share/vm/ci/ciStreams.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/ci/ciStreams.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/ci/ciStreams.cpp
+--- a/src/share/vm/ci/ciStreams.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/ci/ciStreams.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -88,10 +88,9 @@ Bytecodes::Code ciBytecodeStream::wide()
{
// Get following bytecode; do not return wide
@@ -3779,41 +3623,40 @@ diff -r ce2272390558 src/share/vm/ci/ciS
_was_wide = _pc; // Flag last wide bytecode found
return bc;
}
-@@ -303,11 +302,15 @@ int ciBytecodeStream::get_method_index()
- int ciBytecodeStream::get_method_index() {
- switch (cur_bc()) {
- case Bytecodes::_invokeinterface:
-+ // This should also work for wide invokeinterfaces.
- return Bytes::get_Java_u2(_pc-4);
- case Bytecodes::_invokevirtual:
- case Bytecodes::_invokespecial:
- case Bytecodes::_invokestatic:
-- return get_index_big();
-+ if(!is_wide())
-+ return get_index_big();
-+ else
-+ return Bytes::get_Java_u2(_bc_start+2);
- default:
- ShouldNotReachHere();
- return 0;
-diff -r ce2272390558 src/share/vm/ci/ciStreams.hpp
---- a/src/share/vm/ci/ciStreams.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/ci/ciStreams.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -121,7 +121,7 @@ public:
+diff -r aa0c48844632 src/share/vm/ci/ciStreams.hpp
+--- a/src/share/vm/ci/ciStreams.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/ci/ciStreams.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -122,7 +122,7 @@ public:
return check_java(_bc);
}
-- bool is_wide() { return ( _pc == _was_wide ); }
+- bool is_wide() const { return ( _pc == _was_wide ); }
+ bool is_wide() const { return ( _pc == _was_wide ); }
// Get a byte index following this bytecode.
// If prefixed with a wide bytecode, get a wide index.
-@@ -141,7 +141,17 @@ public:
+@@ -131,12 +131,6 @@ public:
+ return (_pc == _was_wide) // was widened?
+ ? Bytes::get_Java_u2(_bc_start+2) // yes, return wide index
+ : _bc_start[1]; // no, return narrow index
+- }
+-
+- // Get 2-byte index (getfield/putstatic/etc)
+- int get_index_big() const {
+- assert_index_size(2);
+- return Bytes::get_Java_u2(_bc_start+1);
}
- // Get 2-byte index (getfield/putstatic/etc)
-- int get_index_big() const { return Bytes::get_Java_u2(_bc_start+1); }
+ // Get 2-byte index (or 4-byte, for invokedynamic)
+@@ -148,6 +142,20 @@ public:
+ int get_index_giant() const {
+ assert_index_size(4);
+ return Bytes::get_native_u4(_bc_start+1);
++ }
++
++ // Get 2-byte index (getfield/putstatic/etc)
+ int get_index_big() const {
++ assert_index_size(is_wide() ? 2 : 1);
+ if (is_wide()) {
+ assert(_bc == Bytecodes::_invokestatic ||
+ _bc == Bytecodes::_invokespecial ||
@@ -3823,13 +3666,12 @@ diff -r ce2272390558 src/share/vm/ci/ciS
+ return Bytes::get_Java_u2(_bc_start+2);
+ }
+ return Bytes::get_Java_u2(_bc_start+1);
-+ }
-
- // Get dimensions byte (multinewarray)
- int get_dimensions() const { return *(unsigned char*)(_pc-1); }
-diff -r ce2272390558 src/share/vm/classfile/verifier.cpp
---- a/src/share/vm/classfile/verifier.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/classfile/verifier.cpp Mon Mar 16 11:42:47 2009 +0100
+ }
+
+ bool has_giant_index() const { return (cur_bc() == Bytecodes::_invokedynamic); }
+diff -r aa0c48844632 src/share/vm/classfile/verifier.cpp
+--- a/src/share/vm/classfile/verifier.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/classfile/verifier.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -323,6 +323,7 @@ void ClassVerifier::verify_method(method
bool no_control_flow = false; // Set to true when there is no direct control
// flow from current instruction to the next
@@ -3898,7 +3740,7 @@ diff -r ce2272390558 src/share/vm/classf
switch (opcode) {
case Bytecodes::_nop :
-@@ -1169,14 +1196,15 @@ void ClassVerifier::verify_method(method
+@@ -1169,15 +1196,16 @@ void ClassVerifier::verify_method(method
case Bytecodes::_invokevirtual :
case Bytecodes::_invokespecial :
case Bytecodes::_invokestatic :
@@ -3907,6 +3749,7 @@ diff -r ce2272390558 src/share/vm/classf
- &this_uninit, return_type, cp, CHECK_VERIFY(this));
- no_control_flow = false; break;
case Bytecodes::_invokeinterface :
+ case Bytecodes::_invokedynamic :
verify_invoke_instructions(
&bcs, code_length, ¤t_frame,
&this_uninit, return_type, cp, CHECK_VERIFY(this));
@@ -3918,7 +3761,7 @@ diff -r ce2272390558 src/share/vm/classf
no_control_flow = false; break;
case Bytecodes::_new :
{
-@@ -1278,8 +1306,10 @@ void ClassVerifier::verify_method(method
+@@ -1279,8 +1307,10 @@ void ClassVerifier::verify_method(method
// matches current_frame
if (bci >= ex_min && bci < ex_max) {
verify_exception_handler_targets(
@@ -3930,7 +3773,7 @@ diff -r ce2272390558 src/share/vm/classf
} // end while
// Make sure that control flow does not fall through end of the method
-@@ -1415,8 +1445,9 @@ u2 ClassVerifier::verify_stackmap_table(
+@@ -1416,8 +1446,9 @@ u2 ClassVerifier::verify_stackmap_table(
return stackmap_index;
}
@@ -3942,7 +3785,7 @@ diff -r ce2272390558 src/share/vm/classf
constantPoolHandle cp (THREAD, _method->constants());
typeArrayHandle exhandlers (THREAD, _method->exception_table());
if (exhandlers() != NULL) {
-@@ -1426,6 +1457,13 @@ void ClassVerifier::verify_exception_han
+@@ -1427,6 +1458,13 @@ void ClassVerifier::verify_exception_han
u2 handler_pc = exhandlers->int_at(i++);
int catch_type_index = exhandlers->int_at(i++);
if(bci >= start_pc && bci < end_pc) {
@@ -3956,7 +3799,7 @@ diff -r ce2272390558 src/share/vm/classf
u1 flags = current_frame->flags();
if (this_uninit) { flags |= FLAG_THIS_UNINIT; }
-@@ -1723,8 +1761,9 @@ void ClassVerifier::verify_field_instruc
+@@ -1724,8 +1762,9 @@ void ClassVerifier::verify_field_instruc
}
// Get referenced class type
@@ -3968,7 +3811,7 @@ diff -r ce2272390558 src/share/vm/classf
if (!ref_class_type.is_object()) {
verify_error(
"Expecting reference to class in class %s at constant pool index %d",
-@@ -1793,8 +1832,6 @@ void ClassVerifier::verify_field_instruc
+@@ -1794,8 +1833,6 @@ void ClassVerifier::verify_field_instruc
check_protected: {
if (_this_type == stack_object_type)
break; // stack_object_type must be assignable to _current_class_type
@@ -3977,7 +3820,7 @@ diff -r ce2272390558 src/share/vm/classf
if (!name_in_supers(ref_class_name(), current_class()))
// stack_object_type must be assignable to _current_class_type since:
// 1. stack_object_type must be assignable to ref_class.
-@@ -1890,13 +1927,20 @@ void ClassVerifier::verify_invoke_instru
+@@ -1891,6 +1928,7 @@ void ClassVerifier::verify_invoke_instru
RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
bool *this_uninit, VerificationType return_type,
constantPoolHandle cp, TRAPS) {
@@ -3985,24 +3828,7 @@ diff -r ce2272390558 src/share/vm/classf
// Make sure the constant pool item is the right type
u2 index = bcs->get_index_big();
Bytecodes::Code opcode = bcs->code();
-- unsigned int types = (opcode == Bytecodes::_invokeinterface
-- ? 1 << JVM_CONSTANT_InterfaceMethodref
-- : 1 << JVM_CONSTANT_Methodref);
-- verify_cp_type(index, cp, types, CHECK_VERIFY(this));
-+ switch (opcode) {
-+ case Bytecodes::_invokeinterface:
-+ verify_cp_type(index, cp, 1 << JVM_CONSTANT_InterfaceMethodref, CHECK_VERIFY(this));
-+ //nt_pair_index = cp->name_and_type_ref_index_at(raw_index);
-+ break;
-+ default:
-+ verify_cp_type(index, cp, 1 << JVM_CONSTANT_Methodref, CHECK_VERIFY(this));
-+ //nt_pair_index = cp->name_and_type_ref_index_at(raw_index);
-+ break;
-+ }
-
- // Get method name and signature
- symbolHandle method_name(THREAD, cp->name_ref_at(index));
-@@ -1955,7 +1999,7 @@ void ClassVerifier::verify_invoke_instru
+@@ -1976,7 +2014,7 @@ void ClassVerifier::verify_invoke_instru
// Check instruction operands
u2 bci = bcs->bci();
if (opcode == Bytecodes::_invokeinterface) {
@@ -4011,15 +3837,21 @@ diff -r ce2272390558 src/share/vm/classf
// 4905268: count operand in invokeinterface should be nargs+1, not nargs.
// JSR202 spec: The count operand of an invokeinterface instruction is valid if it is
// the difference between the size of the operand stack before and after the instruction
-@@ -1973,6 +2017,7 @@ void ClassVerifier::verify_invoke_instru
+@@ -2002,8 +2040,12 @@ void ClassVerifier::verify_invoke_instru
if (method_name->byte_at(0) == '<') {
// Make sure <init> can only be invoked by invokespecial
if (opcode != Bytecodes::_invokespecial ||
+ bcs->has_prefix() || // no tail-calls to <init>
method_name() != vmSymbols::object_initializer_name()) {
- verify_error(bci, "Illegal call to internal method");
+- verify_error(bci, "Illegal call to internal method");
++ if (bcs->has_prefix())
++ verify_error(bci, "Illegal tail-call to internal method");
++ else
++ verify_error(bci, "Illegal call to internal method");
return;
-@@ -2007,8 +2052,8 @@ void ClassVerifier::verify_invoke_instru
+ }
+ } else if (opcode == Bytecodes::_invokespecial
+@@ -2037,8 +2079,8 @@ void ClassVerifier::verify_invoke_instru
current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this));
if (current_type() != stack_object_type) {
assert(cp->cache() == NULL, "not rewritten yet");
@@ -4030,11 +3862,53 @@ diff -r ce2272390558 src/share/vm/classf
// See the comments in verify_field_instructions() for
// the rationale behind this.
if (name_in_supers(ref_class_name(), current_class())) {
-@@ -2053,6 +2098,43 @@ void ClassVerifier::verify_invoke_instru
+@@ -2083,6 +2125,97 @@ void ClassVerifier::verify_invoke_instru
for (int i = 0; i < n; i++) {
current_frame->push_stack(return_type[i], CHECK_VERIFY(this)); // push types backwards
}
+ }
++}
++
++// Follow a chain of gotos. Check that gotos are followed by a xxxreturn or
++// pop/return instruction. Returns false if this check fails.
++static bool verify_tail_call_chain_of_gotos(methodHandle& method, RawBytecodeStream& bcs) {
++ assert(bcs.code() == Bytecodes::_goto, "Expected a goto instruction");
++ RawBytecodeStream lookahead_bcs(method);
++ // Target of goto must be within method boundry.
++ if (bcs.dest () > lookahead_bcs.end_bci() ||
++ bcs.dest() < 0) return false;
++ lookahead_bcs.set_start(bcs.dest());
++ // Verify target. Must either be
++ // * further goto
++ // * return
++ // * pop followed by return
++ switch(lookahead_bcs.raw_next()) {
++ case Bytecodes::_pop:
++ // Pop of result because of void-return.
++ if (lookahead_bcs.raw_next()==Bytecodes::_return) {
++ return true;
++ }
++ break;
++ case Bytecodes::_goto:
++ // Follow a chain of gotos. Expect a return or a pop/return combination.
++ return verify_tail_call_chain_of_gotos(method, lookahead_bcs);
++ break;
++ case Bytecodes::_ireturn :
++ case Bytecodes::_lreturn :
++ case Bytecodes::_freturn :
++ case Bytecodes::_dreturn :
++ case Bytecodes::_areturn :
++ case Bytecodes::_return :
++ // Next iteration of main loop will verify compatibility of return value.
++ // Note: This allows a certain amount of "widening" of the result.
++ // A void method can tail-call a non-void method, etc.
++ return true;
++ break;
++ default:
++ // Fail.
++ break;
++ }
++ return false;
+}
+
+void ClassVerifier::verify_tail_call(
@@ -4051,6 +3925,18 @@ diff -r ce2272390558 src/share/vm/classf
+ RawBytecodeStream lookahead_bcs(_method);
+ lookahead_bcs.set_start(bcs->next_bci());
+ switch (lookahead_bcs.raw_next()) {
++ case Bytecodes::_pop:
++ // Pop of result because of void-return.
++ if (lookahead_bcs.raw_next()==Bytecodes::_return) {
++ break;
++ }
++ case Bytecodes::_goto:
++ // Follow a chain of gotos. Expect a return or a pop/return combination.
++ if (verify_tail_call_chain_of_gotos(_method, lookahead_bcs)==false) {
++ verify_error(bci, "Tail call must be followed by a return instruction");
++ return;
++ }
++ break;
+ case Bytecodes::_ireturn :
+ case Bytecodes::_lreturn :
+ case Bytecodes::_freturn :
@@ -4074,9 +3960,9 @@ diff -r ce2272390558 src/share/vm/classf
}
}
-diff -r ce2272390558 src/share/vm/classfile/verifier.hpp
---- a/src/share/vm/classfile/verifier.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/classfile/verifier.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/classfile/verifier.hpp
+--- a/src/share/vm/classfile/verifier.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/classfile/verifier.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -107,7 +107,7 @@ class ClassVerifier : public StackObj {
StackMapTable* stackmap_table, bool no_control_flow, TRAPS);
@@ -4096,10 +3982,10 @@ diff -r ce2272390558 src/share/vm/classf
VerificationType get_newarray_type(u2 index, u2 bci, TRAPS);
void verify_anewarray(
-diff -r ce2272390558 src/share/vm/classfile/vmSymbols.hpp
---- a/src/share/vm/classfile/vmSymbols.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/classfile/vmSymbols.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -151,6 +151,8 @@
+diff -r aa0c48844632 src/share/vm/classfile/vmSymbols.hpp
+--- a/src/share/vm/classfile/vmSymbols.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/classfile/vmSymbols.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -153,6 +153,8 @@
template(java_lang_RuntimeException, "java/lang/RuntimeException") \
template(java_io_IOException, "java/io/IOException") \
template(java_security_PrivilegedActionException, "java/security/PrivilegedActionException") \
@@ -4108,9 +3994,9 @@ diff -r ce2272390558 src/share/vm/classf
\
/* error klasses: at least all errors thrown by the VM have entries here */ \
template(java_lang_AbstractMethodError, "java/lang/AbstractMethodError") \
-diff -r ce2272390558 src/share/vm/code/codeBlob.cpp
---- a/src/share/vm/code/codeBlob.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/codeBlob.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/codeBlob.cpp
+--- a/src/share/vm/code/codeBlob.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/codeBlob.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -375,6 +375,7 @@ DeoptimizationBlob::DeoptimizationBlob(
int unpack_offset,
int unpack_with_exception_offset,
@@ -4143,9 +4029,9 @@ diff -r ce2272390558 src/share/vm/code/c
frame_size);
}
-diff -r ce2272390558 src/share/vm/code/codeBlob.hpp
---- a/src/share/vm/code/codeBlob.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/codeBlob.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/codeBlob.hpp
+--- a/src/share/vm/code/codeBlob.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/codeBlob.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -339,6 +339,7 @@ class DeoptimizationBlob: public Singlet
int _unpack_offset;
int _unpack_with_exception;
@@ -4178,9 +4064,9 @@ diff -r ce2272390558 src/share/vm/code/c
// Alternate entry point for C1 where the exception and issuing pc
// are in JavaThread::_exception_oop and JavaThread::_exception_pc
-diff -r ce2272390558 src/share/vm/code/compiledIC.cpp
---- a/src/share/vm/code/compiledIC.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/compiledIC.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/compiledIC.cpp
+--- a/src/share/vm/code/compiledIC.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/compiledIC.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -116,12 +116,37 @@ address CompiledIC::stub_address() const
return _ic_call->destination();
}
@@ -4310,17 +4196,16 @@ diff -r ce2272390558 src/share/vm/code/c
methodHandle method (thread, (methodOop)info.cached_oop()());
csc->set_to_interpreted(method, info.entry());
if (TraceICs) {
-@@ -370,6 +428,9 @@ void CompiledIC::compute_monomorphic_ent
+@@ -370,6 +428,8 @@ void CompiledIC::compute_monomorphic_ent
KlassHandle receiver_klass,
bool is_optimized,
bool static_bound,
+ bool is_tail_call,
+ bool is_sibling,
-+ bool pd_mismatch,
CompiledICInfo& info,
TRAPS) {
info._is_optimized = is_optimized;
-@@ -379,9 +440,47 @@ void CompiledIC::compute_monomorphic_ent
+@@ -379,9 +439,41 @@ void CompiledIC::compute_monomorphic_ent
if (method_code != NULL) {
// Call to compiled code
if (static_bound || is_optimized) {
@@ -4331,10 +4216,7 @@ diff -r ce2272390558 src/share/vm/code/c
+ method->print_value_string();
+ tty->print_cr(" to compiled: verified_tail_call_entry_point");
+ }
-+ if (pd_mismatch)
-+ entry = method_code->verified_tail_call_pd_check_failed_entry_point();
-+ else
-+ entry = method_code->verified_tail_call_entry_point();
++ entry = method_code->verified_tail_call_entry_point();
+ } else if (is_tail_call) {
+ if (TraceTailCalls){
+ tty->print("CompiledIC::compute_monomorphic_entry():");
@@ -4353,10 +4235,7 @@ diff -r ce2272390558 src/share/vm/code/c
+ method->print_value_string();
+ tty->print_cr(" to compiled: monomorphic_tail_call_entry_point");
+ }
-+ if (pd_mismatch)
-+ entry = method_code->tail_call_pd_check_failed_entry_point();
-+ else
-+ entry = method_code->tail_call_entry_point();
++ entry = method_code->tail_call_entry_point();
+ } else if (is_tail_call) {
+ if (TraceTailCalls){
+ tty->print("CompiledIC::compute_monomorphic_entry():");
@@ -4370,7 +4249,7 @@ diff -r ce2272390558 src/share/vm/code/c
}
}
if (entry != NULL) {
-@@ -429,36 +528,80 @@ void CompiledIC::compute_monomorphic_ent
+@@ -429,36 +521,74 @@ void CompiledIC::compute_monomorphic_ent
#endif // COMPILER2
if (is_optimized) {
// Use stub entry
@@ -4381,10 +4260,7 @@ diff -r ce2272390558 src/share/vm/code/c
+ method->print_value_string();
+ tty->print_cr(" to interpreter: get_c2i_verified_tail_call_entry_point");
+ }
-+ if (pd_mismatch)
-+ info._entry = method()->adapter()->get_pd_check_failed_entry();
-+ else
-+ info._entry = method()->get_c2i_verified_tail_call_entry();
++ info._entry = method()->get_c2i_verified_tail_call_entry();
+ } else if(is_tail_call) {
+ if (TraceTailCalls){
+ tty->print("CompiledIC::compute_monomorphic_entry():");
@@ -4406,10 +4282,7 @@ diff -r ce2272390558 src/share/vm/code/c
+ method->print_value_string();
+ tty->print_cr(" to interpreter: get_c2i_unverified_tail_call_entry_point");
+ }
-+ if (pd_mismatch)
-+ info._entry = method()->adapter()->get_pd_check_failed_unverified_entry();
-+ else
-+ info._entry = method()->get_c2i_unverified_tail_call_entry();
++ info._entry = method()->get_c2i_unverified_tail_call_entry();
+ } else if (is_tail_call) {
+ if (TraceTailCalls){
+ tty->print("CompiledIC::compute_monomorphic_entry():");
@@ -4459,7 +4332,7 @@ diff -r ce2272390558 src/share/vm/code/c
assert(ic_reloc->type() == relocInfo::virtual_call_type ||
ic_reloc->type() == relocInfo::opt_virtual_call_type, "wrong reloc. info");
}
-@@ -474,8 +617,17 @@ void CompiledStaticCall::set_to_clean()
+@@ -474,8 +604,17 @@ void CompiledStaticCall::set_to_clean()
CodeBlob* cb = CodeCache::find_blob_unsafe(this);
assert(cb != NULL && cb->is_nmethod(), "must be nmethod");
#endif
@@ -4479,7 +4352,7 @@ diff -r ce2272390558 src/share/vm/code/c
// Do not reset stub here: It is too expensive to call find_stub.
// Instead, rely on caller (nmethod::clear_inline_caches) to clear
// both the call and its stub.
-@@ -486,6 +638,14 @@ bool CompiledStaticCall::is_clean() cons
+@@ -486,6 +625,14 @@ bool CompiledStaticCall::is_clean() cons
return destination() == SharedRuntime::get_resolve_static_call_stub();
}
@@ -4494,7 +4367,7 @@ diff -r ce2272390558 src/share/vm/code/c
bool CompiledStaticCall::is_call_to_compiled() const {
return CodeCache::contains(destination());
}
-@@ -495,7 +655,13 @@ bool CompiledStaticCall::is_call_to_inte
+@@ -495,7 +642,13 @@ bool CompiledStaticCall::is_call_to_inte
// It is a call to interpreted, if it calls to a stub. Hence, the destination
// must be in the stub part of the nmethod that contains the call
nmethod* nm = CodeCache::find_nmethod(instruction_address());
@@ -4509,7 +4382,7 @@ diff -r ce2272390558 src/share/vm/code/c
}
-@@ -532,7 +698,7 @@ void CompiledStaticCall::set(const Stati
+@@ -532,7 +685,7 @@ void CompiledStaticCall::set(const Stati
// to track down - if cache entry gets invalid - we just clean it. In
// this way it is always the same code path that is responsible for
// updating and resolving an inline cache
@@ -4518,7 +4391,7 @@ diff -r ce2272390558 src/share/vm/code/c
if (info._to_interpreter) {
// Call to interpreted code
-@@ -550,20 +716,82 @@ void CompiledStaticCall::set(const Stati
+@@ -550,20 +703,76 @@ void CompiledStaticCall::set(const Stati
}
}
@@ -4551,7 +4424,7 @@ diff -r ce2272390558 src/share/vm/code/c
// Compute settings for a CompiledStaticCall. Since we might have to set
// the stub when calling to the interpreter, we need to return arguments.
-void CompiledStaticCall::compute_entry(methodHandle m, StaticCallInfo& info) {
-+void CompiledStaticCall::compute_entry(methodHandle m, StaticCallInfo& info, bool is_tail_call, bool is_sibling_call, bool pd_mismatch) {
++void CompiledStaticCall::compute_entry(methodHandle m, StaticCallInfo& info, bool is_tail_call, bool is_sibling_call) {
nmethod* m_code = m->code();
info._callee = m;
if (m_code != NULL) {
@@ -4563,10 +4436,7 @@ diff -r ce2272390558 src/share/vm/code/c
+ m->print_value_string();
+ tty->print_cr(" to compiled: verified_tail_call_entry_point");
+ }
-+ if (pd_mismatch)
-+ info._entry = m_code->verified_tail_call_pd_check_failed_entry_point();
-+ else
-+ info._entry = m_code->verified_tail_call_entry_point();
++ info._entry = m_code->verified_tail_call_entry_point();
+ } else if (is_tail_call) {
+ if (TraceTailCalls){
+ tty->print("CompiledStaticCall:compute_entry() ");
@@ -4588,10 +4458,7 @@ diff -r ce2272390558 src/share/vm/code/c
+ m->print_value_string();
+ tty->print_cr(" to interpreter: get_c2i_verified_tail_call_entry");
+ }
-+ if (pd_mismatch)
-+ info._entry = m()->adapter()->get_pd_check_failed_entry();
-+ else
-+ info._entry = m()->get_c2i_verified_tail_call_entry();
++ info._entry = m()->get_c2i_verified_tail_call_entry();
+ } else if (is_tail_call) {
+ if (TraceTailCalls){
+ tty->print("CompiledStaticCall:compute_entry() ");
@@ -4604,7 +4471,7 @@ diff -r ce2272390558 src/share/vm/code/c
}
}
-@@ -607,9 +835,11 @@ address CompiledStaticCall::find_stub()
+@@ -607,9 +816,11 @@ address CompiledStaticCall::find_stub()
// Non-product mode code
#ifndef PRODUCT
@@ -4618,7 +4485,7 @@ diff -r ce2272390558 src/share/vm/code/c
if (os::is_MP()) {
_ic_call->verify_alignment();
}
-@@ -640,6 +870,23 @@ void CompiledStaticCall::print() {
+@@ -640,6 +851,23 @@ void CompiledStaticCall::print() {
tty->print("interpreted");
}
tty->cr();
@@ -4642,7 +4509,7 @@ diff -r ce2272390558 src/share/vm/code/c
}
void CompiledStaticCall::verify() {
-@@ -654,7 +901,6 @@ void CompiledStaticCall::verify() {
+@@ -654,7 +882,6 @@ void CompiledStaticCall::verify() {
assert(stub != NULL, "no stub found for static call");
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub); // creation also verifies the object
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
@@ -4650,9 +4517,9 @@ diff -r ce2272390558 src/share/vm/code/c
// Verify state
assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
}
-diff -r ce2272390558 src/share/vm/code/compiledIC.hpp
---- a/src/share/vm/code/compiledIC.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/compiledIC.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/compiledIC.hpp
+--- a/src/share/vm/code/compiledIC.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/compiledIC.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -76,15 +76,20 @@ class CompiledIC: public ResourceObj {
oop* _oop_addr; // patchable oop cell for this IC
RelocIterator _oops; // iteration over any and all set-oop instructions
@@ -4710,7 +4577,7 @@ diff -r ce2272390558 src/share/vm/code/c
static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass,
- bool is_optimized, bool static_bound, CompiledICInfo& info, TRAPS);
+ bool is_optimized, bool static_bound, bool is_tail_call,
-+ bool is_sibling, bool pd_mismatch, CompiledICInfo& info, TRAPS);
++ bool is_sibling, CompiledICInfo& info, TRAPS);
// Location
address instruction_address() const { return _ic_call->instruction_address(); }
@@ -4780,29 +4647,17 @@ diff -r ce2272390558 src/share/vm/code/c
// Compute entry point given a method
- static void compute_entry(methodHandle m, StaticCallInfo& info);
-+ static void compute_entry(methodHandle m, StaticCallInfo& info, bool is_tail_call=false, bool is_sibling_call=false, bool pd_mismatch = false);
++ static void compute_entry(methodHandle m, StaticCallInfo& info, bool is_tail_call=false, bool is_sibling_call=false);
// Stub support
address find_stub();
-@@ -221,21 +238,43 @@ class CompiledStaticCall: public NativeC
+@@ -221,21 +238,31 @@ class CompiledStaticCall: public NativeC
// Misc.
void print() PRODUCT_RETURN;
void verify() PRODUCT_RETURN;
+ void verify_static_tail_call() PRODUCT_RETURN;
};
-+inline bool is_sibling_tail_call_before(address pc) {
-+ NativeJump * tailjmp = nativeJump_before(pc);
-+ address jmp_addr = tailjmp->instruction_address();
-+ nmethod * caller_nm = CodeCache::find_nmethod(pc);
-+ RelocIterator iter (caller_nm, jmp_addr, jmp_addr+1);
-+ int ret = iter.next();
-+ assert(ret, "Reloc info must exist");
-+ assert(iter.addr() == jmp_addr, "oops");
-+ if (iter.tail_call_type()==relocInfo::sibling_tail_call_type)
-+ return true;
-+ return false;
-+}
-inline CompiledStaticCall* compiledStaticCall_before(address return_addr) {
- CompiledStaticCall* st = (CompiledStaticCall*)nativeCall_before(return_addr);
@@ -4835,9 +4690,9 @@ diff -r ce2272390558 src/share/vm/code/c
+inline CompiledStaticCall* compiledStaticCall_at(Relocation* call_site, bool is_tail_call) {
+ return compiledStaticCall_at(call_site->addr(), is_tail_call);
}
-diff -r ce2272390558 src/share/vm/code/icBuffer.cpp
---- a/src/share/vm/code/icBuffer.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/icBuffer.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/icBuffer.cpp
+--- a/src/share/vm/code/icBuffer.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/icBuffer.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -35,7 +35,9 @@ void ICStub::finalize() {
void ICStub::finalize() {
if (!is_empty()) {
@@ -4849,9 +4704,9 @@ diff -r ce2272390558 src/share/vm/code/i
assert(CodeCache::find_nmethod(ic->instruction_address()) != NULL, "inline cache in non-nmethod?");
assert(this == ICStub_from_destination_address(ic->stub_address()), "wrong owner of ic buffer");
-diff -r ce2272390558 src/share/vm/code/nmethod.cpp
---- a/src/share/vm/code/nmethod.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/nmethod.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/nmethod.cpp
+--- a/src/share/vm/code/nmethod.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/nmethod.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -1,3 +1,4 @@
+
/*
@@ -4878,7 +4733,7 @@ diff -r ce2272390558 src/share/vm/code/n
_consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start());
_scopes_data_offset = data_offset();
_scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize);
-@@ -797,6 +805,20 @@ nmethod::nmethod(
+@@ -797,6 +805,19 @@ nmethod::nmethod(
_entry_point = instructions_begin();
_verified_entry_point = instructions_begin() + offsets->value(CodeOffsets::Verified_Entry);
_osr_entry_point = instructions_begin() + offsets->value(CodeOffsets::OSR_Entry);
@@ -4886,8 +4741,7 @@ diff -r ce2272390558 src/share/vm/code/n
+ _verified_not_sibling_tail_call_entry_point = verified_not_sibling_tail_call_begin();
+ _tail_call_entry_point = tail_call_begin();
+ _not_sibling_tail_call_entry_point = not_sibling_tail_call_begin();
-+ _tail_call_pd_check_failed_entry_point = header_begin() + _stub_offset + offsets->value(CodeOffsets::Tail_Call_Move_Arguments);
-+ _tail_call_pd_check_failed_verified_entry_point = header_begin() + _stub_offset + offsets->value(CodeOffsets::Verified_Tail_Call_Move_Arguments);
++
+#if ASSERT
+ // Check entry point alignment: when making the nmethod not entrant or
+ // zombie the tail call entry points need to be aligned properly.
@@ -4899,7 +4753,7 @@ diff -r ce2272390558 src/share/vm/code/n
_exception_cache = NULL;
_pc_desc_cache.reset_to(scopes_pcs_begin());
-@@ -970,6 +992,43 @@ ScopeDesc* nmethod::scope_desc_at(addres
+@@ -970,6 +991,43 @@ ScopeDesc* nmethod::scope_desc_at(addres
}
@@ -4943,7 +4797,7 @@ diff -r ce2272390558 src/share/vm/code/n
void nmethod::clear_inline_caches() {
assert(SafepointSynchronize::is_at_safepoint(), "cleaning of IC's only allowed at safepoint");
if (is_zombie()) {
-@@ -1009,7 +1068,8 @@ void nmethod::cleanup_inline_caches() {
+@@ -1009,7 +1067,8 @@ void nmethod::cleanup_inline_caches() {
switch(iter.type()) {
case relocInfo::virtual_call_type:
case relocInfo::opt_virtual_call_type: {
@@ -4953,7 +4807,7 @@ diff -r ce2272390558 src/share/vm/code/n
// Ok, to lookup references to zombies here
CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination());
if( cb != NULL && cb->is_nmethod() ) {
-@@ -1020,7 +1080,8 @@ void nmethod::cleanup_inline_caches() {
+@@ -1020,7 +1079,8 @@ void nmethod::cleanup_inline_caches() {
break;
}
case relocInfo::static_call_type: {
@@ -4963,7 +4817,7 @@ diff -r ce2272390558 src/share/vm/code/n
CodeBlob *cb = CodeCache::find_blob_unsafe(csc->destination());
if( cb != NULL && cb->is_nmethod() ) {
nmethod* nm = (nmethod*)cb;
-@@ -1173,6 +1234,18 @@ void nmethod::make_not_entrant_or_zombie
+@@ -1173,6 +1233,18 @@ void nmethod::make_not_entrant_or_zombie
// The caller can be calling the method statically or through an inline
// cache call.
if (!is_not_entrant()) {
@@ -4982,7 +4836,7 @@ diff -r ce2272390558 src/share/vm/code/n
NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
SharedRuntime::get_handle_wrong_method_stub());
assert (NativeJump::instruction_size == nmethod::_zombie_instruction_size, "");
-@@ -1456,7 +1529,8 @@ void nmethod::do_unloading(BoolObjectClo
+@@ -1456,7 +1528,8 @@ void nmethod::do_unloading(BoolObjectClo
RelocIterator iter(this, low_boundary);
while(iter.next()) {
if (iter.type() == relocInfo::virtual_call_type) {
@@ -4992,7 +4846,7 @@ diff -r ce2272390558 src/share/vm/code/n
oop ic_oop = ic->cached_oop();
if (ic_oop != NULL && !is_alive->do_object_b(ic_oop)) {
// The only exception is compiledICHolder oops which may
-@@ -1510,7 +1584,8 @@ void nmethod::do_unloading(BoolObjectClo
+@@ -1510,7 +1583,8 @@ void nmethod::do_unloading(BoolObjectClo
RelocIterator iter(this, low_boundary);
while (iter.next()) {
if (iter.type() == relocInfo::virtual_call_type) {
@@ -5002,18 +4856,7 @@ diff -r ce2272390558 src/share/vm/code/n
oop ic_oop = ic->cached_oop();
assert(ic_oop == NULL || is_alive->do_object_b(ic_oop),
"Found unmarked ic_oop in reachable nmethod");
-@@ -1571,8 +1646,9 @@ void nmethod::preserve_callee_argument_o
- SimpleScopeDesc ssd(this, fr.pc());
- Bytecode_invoke* call = Bytecode_invoke_at(ssd.method(), ssd.bci());
- bool is_static = call->is_invokestatic();
-+ bool is_tailcall = call->is_tailcall();
- symbolOop signature = call->signature();
-- fr.oops_compiled_arguments_do(signature, is_static, reg_map, f);
-+ fr.oops_compiled_arguments_do(signature, is_static, is_tailcall, reg_map, f);
- }
- }
-
-@@ -1923,11 +1999,13 @@ void nmethod::verify_interrupt_point(add
+@@ -1923,11 +1997,13 @@ void nmethod::verify_interrupt_point(add
if (CompiledIC_lock->owner() == cur ||
((cur->is_VM_thread() || cur->is_ConcurrentGC_thread()) &&
SafepointSynchronize::is_at_safepoint())) {
@@ -5029,7 +4872,7 @@ diff -r ce2272390558 src/share/vm/code/n
}
PcDesc* pd = pc_desc_at(ic->end_of_call());
assert(pd != NULL, "PcDesc must exist");
-@@ -2171,6 +2249,7 @@ const char* nmethod::reloc_string_for(u_
+@@ -2171,6 +2247,7 @@ const char* nmethod::reloc_string_for(u_
case relocInfo::poll_type: return "poll";
case relocInfo::poll_return_type: return "poll_return";
case relocInfo::type_mask: return "type_bit_mask";
@@ -5037,7 +4880,7 @@ diff -r ce2272390558 src/share/vm/code/n
}
}
return have_one ? "other" : NULL;
-@@ -2220,8 +2299,9 @@ void nmethod::print_code_comment_on(outp
+@@ -2220,8 +2297,9 @@ void nmethod::print_code_comment_on(outp
st->print("method is native");
} else {
address bcp = sd->method()->bcp_from(sd->bci());
@@ -5049,7 +4892,7 @@ diff -r ce2272390558 src/share/vm/code/n
switch (bc) {
case Bytecodes::_invokevirtual:
case Bytecodes::_invokespecial:
-@@ -2302,12 +2382,13 @@ void nmethod::print_calls(outputStream*
+@@ -2302,12 +2380,13 @@ void nmethod::print_calls(outputStream*
case relocInfo::virtual_call_type:
case relocInfo::opt_virtual_call_type: {
VerifyMutexLocker mc(CompiledIC_lock);
@@ -5065,9 +4908,9 @@ diff -r ce2272390558 src/share/vm/code/n
break;
}
}
-diff -r ce2272390558 src/share/vm/code/nmethod.hpp
---- a/src/share/vm/code/nmethod.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/nmethod.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/nmethod.hpp
+--- a/src/share/vm/code/nmethod.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/nmethod.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -151,7 +151,12 @@ class nmethod : public CodeBlob {
int _handler_table_offset;
int _nul_chk_table_offset;
@@ -5082,7 +4925,7 @@ diff -r ce2272390558 src/share/vm/code/n
// location in frame (offset for sp) that deopt can store the original
// pc during a deopt.
int _orig_pc_offset;
-@@ -163,6 +168,17 @@ class nmethod : public CodeBlob {
+@@ -163,6 +168,14 @@ class nmethod : public CodeBlob {
address _entry_point; // entry point with class check
address _verified_entry_point; // entry point without class check
address _osr_entry_point; // entry point for on stack replacement
@@ -5094,13 +4937,10 @@ diff -r ce2272390558 src/share/vm/code/n
+ // With class, without protection domain check.
+ address _tail_call_entry_point;
+ address _not_sibling_tail_call_entry_point;
-+ // Move arguments from caller's caller to caller because pd check failed.
-+ address _tail_call_pd_check_failed_entry_point;
-+ address _tail_call_pd_check_failed_verified_entry_point;
nmFlags flags; // various flags to keep track of nmethod state
bool _markedForDeoptimization; // Used for stack deoptimization
-@@ -338,7 +354,10 @@ class nmethod : public CodeBlob {
+@@ -338,7 +351,10 @@ class nmethod : public CodeBlob {
address handler_table_end () const { return header_begin() + _nul_chk_table_offset ; }
address nul_chk_table_begin() const { return header_begin() + _nul_chk_table_offset ; }
address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; }
@@ -5112,7 +4952,7 @@ diff -r ce2272390558 src/share/vm/code/n
int code_size () const { return code_end () - code_begin (); }
int stub_size () const { return stub_end () - stub_begin (); }
int consts_size () const { return consts_end () - consts_begin (); }
-@@ -361,7 +380,12 @@ class nmethod : public CodeBlob {
+@@ -361,7 +377,10 @@ class nmethod : public CodeBlob {
// entry points
address entry_point() const { return _entry_point; } // normal entry point
address verified_entry_point() const { return _verified_entry_point; } // if klass is correct
@@ -5121,12 +4961,10 @@ diff -r ce2272390558 src/share/vm/code/n
+ address verified_not_sibling_tail_call_entry_point() const { return _verified_not_sibling_tail_call_entry_point; } // If klass and pd is korrect.
+ address tail_call_entry_point() const { return _tail_call_entry_point; } // Klass check
+ address not_sibling_tail_call_entry_point() const { return _not_sibling_tail_call_entry_point; }
-+ address tail_call_pd_check_failed_entry_point() const { return _tail_call_pd_check_failed_entry_point; }
-+ address verified_tail_call_pd_check_failed_entry_point() const { return _tail_call_pd_check_failed_verified_entry_point; }
// flag accessing and manipulation
bool is_in_use() const { return flags.state == alive; }
bool is_alive() const { return flags.state == alive || flags.state == not_entrant; }
-@@ -432,6 +456,8 @@ class nmethod : public CodeBlob {
+@@ -432,6 +451,8 @@ class nmethod : public CodeBlob {
// note: native wrappers cannot be deoptimized.
bool can_be_deoptimized() const { return is_java_method(); }
@@ -5135,7 +4973,7 @@ diff -r ce2272390558 src/share/vm/code/n
// Inline cache support
void clear_inline_caches();
void cleanup_inline_caches();
-@@ -581,7 +607,7 @@ class nmethod : public CodeBlob {
+@@ -581,7 +602,7 @@ class nmethod : public CodeBlob {
static int verified_entry_point_offset() { return offset_of(nmethod, _verified_entry_point); }
static int osr_entry_point_offset() { return offset_of(nmethod, _osr_entry_point); }
static int entry_bci_offset() { return offset_of(nmethod, _entry_bci); }
@@ -5144,10 +4982,50 @@ diff -r ce2272390558 src/share/vm/code/n
};
// Locks an nmethod so its code will not get removed, even if it is a zombie/not_entrant method
-diff -r ce2272390558 src/share/vm/code/relocInfo.cpp
---- a/src/share/vm/code/relocInfo.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/relocInfo.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -404,6 +404,31 @@ Relocation* RelocIterator::reloc() {
+diff -r aa0c48844632 src/share/vm/code/relocInfo.cpp
+--- a/src/share/vm/code/relocInfo.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/relocInfo.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -106,6 +106,39 @@ void relocInfo::change_reloc_info_for_ad
+ assert(found, "no relocInfo found for pc");
+ }
+
++// TODO: arnold remove dead code
++#if 0
++void relocInfo::change_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type, relocType new_type, address target, int section) {
++ bool found = false;
++ assert(old_type == relocInfo::static_call_type, "only works for static call");
++ assert(new_type == relocInfo::section_call_type, "only works for inter section call");
++ while (itr->next() && !found) {
++ if (itr->addr() == pc) {
++ assert(itr->type()==old_type, "wrong relocInfo type found");
++ itr->current()->set_type(new_type);
++ // Set relocation info.
++ short* p = (short*)itr->data();
++ assert(itr->datalen() == 2, "Sanity check.");
++ assert(itr->code()->is_nmethod(), "oops");
++ nmethod * code = (nmethod*)itr->code();
++ int sindex = section;
++
++ assert(sindex != CodeBuffer::SECT_NONE, "must belong somewhere");
++ assert(target != NULL, "sanity");
++ assert(sindex == CodeBuffer::SECT_STUBS, "assume section stub");
++ address base = code->stub_begin();
++ jint offset = Relocation::scaled_offset(target, base);
++ assert((uint)sindex < (uint)CodeBuffer::SECT_LIMIT, "sanity");
++ assert(CodeBuffer::SECT_LIMIT <= (1 << section_call_Relocation::section_width), "section_width++");
++ p = Relocation::add_jint(p, (offset << section_call_Relocation::section_width) | sindex);
++
++ // TODO: end
++ found=true;
++ }
++ }
++ assert(found, "no relocInfo found for pc");
++}
++#endif
+
+ void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type) {
+ change_reloc_info_for_address(itr, pc, old_type, none);
+@@ -404,6 +437,31 @@ Relocation* RelocIterator::reloc() {
}
@@ -5179,7 +5057,7 @@ diff -r ce2272390558 src/share/vm/code/r
//////// Methods for flyweight Relocation types
-@@ -579,18 +604,43 @@ void virtual_call_Relocation::pack_data_
+@@ -579,18 +637,43 @@ void virtual_call_Relocation::pack_data_
normalize_address(_oop_limit, dest);
jint x0 = scaled_offset_null_special(_first_oop, point);
jint x1 = scaled_offset_null_special(_oop_limit, point);
@@ -5225,7 +5103,7 @@ diff -r ce2272390558 src/share/vm/code/r
void static_stub_Relocation::pack_data_to(CodeSection* dest) {
short* p = (short*) dest->locs_end();
-@@ -702,6 +752,62 @@ void section_word_Relocation::unpack_dat
+@@ -702,6 +785,62 @@ void section_word_Relocation::unpack_dat
_target = address_from_scaled_offset(offset, base);
}
@@ -5288,7 +5166,7 @@ diff -r ce2272390558 src/share/vm/code/r
void breakpoint_Relocation::pack_data_to(CodeSection* dest) {
short* p = (short*) dest->locs_end();
-@@ -775,9 +881,21 @@ void oop_Relocation::fix_oop_relocation(
+@@ -775,9 +914,21 @@ void oop_Relocation::fix_oop_relocation(
}
}
@@ -5312,7 +5190,7 @@ diff -r ce2272390558 src/share/vm/code/r
assert(ic_call != NULL, "ic_call address must be set");
assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input");
if (code == NULL) {
-@@ -803,12 +921,15 @@ RelocIterator virtual_call_Relocation::p
+@@ -803,12 +954,15 @@ RelocIterator virtual_call_Relocation::p
virtual_call_Relocation* r = iter.virtual_call_reloc();
first_oop = r->first_oop();
oop_limit = r->oop_limit();
@@ -5328,7 +5206,7 @@ diff -r ce2272390558 src/share/vm/code/r
return iter;
}
}
-@@ -865,22 +986,27 @@ address virtual_call_Relocation::oop_lim
+@@ -865,22 +1019,27 @@ address virtual_call_Relocation::oop_lim
return _oop_limit;
}
@@ -5359,7 +5237,7 @@ diff -r ce2272390558 src/share/vm/code/r
icache->set_to_clean();
}
-@@ -893,6 +1019,9 @@ address opt_virtual_call_Relocation::sta
+@@ -893,6 +1052,9 @@ address opt_virtual_call_Relocation::sta
if (iter.type() == relocInfo::static_stub_type) {
if (iter.static_stub_reloc()->static_call() == static_call_addr) {
return iter.addr();
@@ -5369,7 +5247,7 @@ diff -r ce2272390558 src/share/vm/code/r
}
}
}
-@@ -900,9 +1029,14 @@ address opt_virtual_call_Relocation::sta
+@@ -900,9 +1062,14 @@ address opt_virtual_call_Relocation::sta
}
@@ -5385,7 +5263,7 @@ diff -r ce2272390558 src/share/vm/code/r
handler->set_to_clean();
}
-@@ -914,6 +1048,9 @@ address static_call_Relocation::static_s
+@@ -914,6 +1081,9 @@ address static_call_Relocation::static_s
while (iter.next()) {
if (iter.type() == relocInfo::static_stub_type) {
if (iter.static_stub_reloc()->static_call() == static_call_addr) {
@@ -5395,9 +5273,9 @@ diff -r ce2272390558 src/share/vm/code/r
return iter.addr();
}
}
-diff -r ce2272390558 src/share/vm/code/relocInfo.hpp
---- a/src/share/vm/code/relocInfo.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/relocInfo.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/relocInfo.hpp
+--- a/src/share/vm/code/relocInfo.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/relocInfo.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -261,12 +261,17 @@ class relocInfo VALUE_OBJ_CLASS_SPEC {
poll_type = 10, // polling instruction for safepoints
poll_return_type = 11, // polling instruction for safepoints at return
@@ -5616,9 +5494,9 @@ diff -r ce2272390558 src/share/vm/code/r
class poll_Relocation : public Relocation {
bool is_data() { return true; }
relocInfo::relocType type() { return relocInfo::poll_type; }
-diff -r ce2272390558 src/share/vm/code/vtableStubs.cpp
---- a/src/share/vm/code/vtableStubs.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/vtableStubs.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/vtableStubs.cpp
+--- a/src/share/vm/code/vtableStubs.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/vtableStubs.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -96,17 +96,17 @@ void VtableStubs::initialize() {
}
@@ -5639,10 +5517,10 @@ diff -r ce2272390558 src/share/vm/code/v
}
- enter(is_vtable_stub, vtable_index, s);
+ enter(is_vtable_stub, vtable_index, s, is_tail_call, is_sibling);
- #ifndef PRODUCT
if (PrintAdapterHandlers) {
tty->print_cr("Decoding VtableStub %s[%d]@%d",
-@@ -119,26 +119,28 @@ address VtableStubs::create_stub(bool is
+ is_vtable_stub? "vtbl": "itbl", vtable_index, VtableStub::receiver_location());
+@@ -117,26 +117,28 @@ address VtableStubs::create_stub(bool is
}
@@ -5678,7 +5556,7 @@ diff -r ce2272390558 src/share/vm/code/v
// enter s at the beginning of the corresponding list
s->set_next(_table[h]);
_table[h] = s;
-@@ -149,7 +151,7 @@ bool VtableStubs::is_entry_point(address
+@@ -147,7 +149,7 @@ bool VtableStubs::is_entry_point(address
bool VtableStubs::is_entry_point(address pc) {
MutexLocker ml(VtableStubs_lock);
VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset());
@@ -5687,9 +5565,9 @@ diff -r ce2272390558 src/share/vm/code/v
VtableStub* s;
for (s = _table[hash]; s != NULL && s != stub; s = s->next()) {}
return s == stub;
-diff -r ce2272390558 src/share/vm/code/vtableStubs.hpp
---- a/src/share/vm/code/vtableStubs.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/code/vtableStubs.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/code/vtableStubs.hpp
+--- a/src/share/vm/code/vtableStubs.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/code/vtableStubs.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -37,14 +37,18 @@ class VtableStub {
const short _index; // vtable index
short _ame_offset; // Where an AbstractMethodError might occur
@@ -5754,9 +5632,9 @@ diff -r ce2272390558 src/share/vm/code/v
static bool is_entry_point(address pc); // is pc a vtable stub entry point?
static bool contains(address pc); // is pc within any stub?
static VtableStub* stub_containing(address pc); // stub containing pc or NULL
-diff -r ce2272390558 src/share/vm/compiler/disassembler.cpp
---- a/src/share/vm/compiler/disassembler.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/compiler/disassembler.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/compiler/disassembler.cpp
+--- a/src/share/vm/compiler/disassembler.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/compiler/disassembler.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -293,6 +293,10 @@ void decode_env::print_insn_labels() {
if (p == nm->exception_begin()) st->print_cr("[Exception Handler]");
if (p == nm->stub_begin()) st->print_cr("[Stub Code]");
@@ -5768,9 +5646,9 @@ diff -r ce2272390558 src/share/vm/compil
}
CodeBlob* cb = _code;
if (cb != NULL) {
-diff -r ce2272390558 src/share/vm/compiler/disassembler.hpp
---- a/src/share/vm/compiler/disassembler.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/compiler/disassembler.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/compiler/disassembler.hpp
+--- a/src/share/vm/compiler/disassembler.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/compiler/disassembler.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -29,7 +29,7 @@ class decode_env;
class Disassembler {
@@ -5789,43 +5667,10 @@ diff -r ce2272390558 src/share/vm/compil
// points to the library.
static void* _library;
// bailout
-diff -r ce2272390558 src/share/vm/compiler/oopMap.cpp
---- a/src/share/vm/compiler/oopMap.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/compiler/oopMap.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -375,9 +375,9 @@ void OopMapSet::all_do(const frame *fr,
- MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag);
- do {
- omv = oms.current();
-- oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
-+ oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map, false);
- if ( loc != NULL ) {
-- oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
-+ oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map, false);
- oop *derived_loc = loc;
- derived_oop_fn(base_loc, derived_loc);
- }
-@@ -391,7 +391,7 @@ void OopMapSet::all_do(const frame *fr,
- {
- for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
- omv = oms.current();
-- oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
-+ oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map, false);
- if ( loc != NULL ) {
- if ( omv.type() == OopMapValue::oop_value ) {
- #ifdef ASSERT
-@@ -465,7 +465,7 @@ void OopMapSet::update_register_map(cons
- omv = oms.current();
- assert(nof_callee < 2*max_saved_on_entry_reg_count, "overflow");
- regs[nof_callee] = omv.content_reg();
-- locs[nof_callee] = fr->oopmapreg_to_location(omv.reg(),reg_map);
-+ locs[nof_callee] = fr->oopmapreg_to_location(omv.reg(),reg_map, false);
- nof_callee++;
- }
-
-diff -r ce2272390558 src/share/vm/includeDB_core
---- a/src/share/vm/includeDB_core Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/includeDB_core Mon Mar 16 11:42:47 2009 +0100
-@@ -1123,11 +1123,14 @@ compiledIC.cpp
+diff -r aa0c48844632 src/share/vm/includeDB_core
+--- a/src/share/vm/includeDB_core Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/includeDB_core Thu Jun 04 10:20:29 2009 +0200
+@@ -1125,11 +1125,14 @@ compiledIC.cpp
compiledIC.cpp systemDictionary.hpp
compiledIC.cpp vtableStubs.hpp
@@ -5840,23 +5685,7 @@ diff -r ce2272390558 src/share/vm/includ
compiledICHolderKlass.cpp collectedHeap.hpp
compiledICHolderKlass.cpp collectedHeap.inline.hpp
-@@ -1428,6 +1431,7 @@ deoptimization.cpp
- deoptimization.cpp allocation.inline.hpp
- deoptimization.cpp biasedLocking.hpp
- deoptimization.cpp bytecode.hpp
-+deoptimization.cpp compiledIC.hpp
- deoptimization.cpp debugInfoRec.hpp
- deoptimization.cpp deoptimization.hpp
- deoptimization.cpp events.hpp
-@@ -1617,6 +1621,7 @@ fprofiler.hpp
- fprofiler.hpp timer.hpp
-
- frame.cpp collectedHeap.inline.hpp
-+frame.cpp compiledIC.hpp
- frame.cpp frame.inline.hpp
- frame.cpp handles.inline.hpp
- frame.cpp interpreter.hpp
-@@ -4415,6 +4420,7 @@ verifier.cpp
+@@ -4448,6 +4451,7 @@ verifier.cpp
verifier.cpp typeArrayOop.hpp
verifier.cpp verifier.hpp
verifier.cpp vmSymbols.hpp
@@ -5864,7 +5693,7 @@ diff -r ce2272390558 src/share/vm/includ
verifier.hpp exceptions.hpp
verifier.hpp gcLocker.hpp
-@@ -4472,6 +4478,7 @@ vframeArray.cpp
+@@ -4505,6 +4509,7 @@ vframeArray.cpp
vframeArray.cpp vframeArray.hpp
vframeArray.cpp vframe_hp.hpp
vframeArray.cpp vmSymbols.hpp
@@ -5872,10 +5701,10 @@ diff -r ce2272390558 src/share/vm/includ
vframeArray.hpp arrayOop.hpp
vframeArray.hpp deoptimization.hpp
-diff -r ce2272390558 src/share/vm/interpreter/abstractInterpreter.hpp
---- a/src/share/vm/interpreter/abstractInterpreter.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/abstractInterpreter.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -73,7 +73,9 @@ class AbstractInterpreter: AllStatic {
+diff -r aa0c48844632 src/share/vm/interpreter/abstractInterpreter.hpp
+--- a/src/share/vm/interpreter/abstractInterpreter.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/abstractInterpreter.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -74,7 +74,9 @@ class AbstractInterpreter: AllStatic {
};
enum SomeConstants {
@@ -5886,20 +5715,20 @@ diff -r ce2272390558 src/share/vm/interp
};
protected:
-@@ -91,7 +93,11 @@ class AbstractInterpreter: AllStatic {
+@@ -92,6 +94,12 @@ class AbstractInterpreter: AllStatic {
static address _rethrow_exception_entry; // rethrows an activation in previous frame
--
+ // Tail calls in interpreter need to check whether parent frame is an
+ // interpreter frame. To support this we need the address range of interpreter
+ // code.
+ static address _interpreter_code_begin;
+ static address _interpreter_code_end;
-
++
friend class AbstractInterpreterGenerator;
friend class InterpreterGenerator;
-@@ -118,6 +124,10 @@ class AbstractInterpreter: AllStatic {
+ friend class InterpreterMacroAssembler;
+@@ -117,6 +125,10 @@ class AbstractInterpreter: AllStatic {
static address rethrow_exception_entry() { return _rethrow_exception_entry; }
@@ -5910,10 +5739,10 @@ diff -r ce2272390558 src/share/vm/interp
// Activation size in words for a method that is just being called.
// Parameters haven't been pushed so count them too.
static int size_top_interpreter_activation(methodOop method);
-diff -r ce2272390558 src/share/vm/interpreter/bytecode.hpp
---- a/src/share/vm/interpreter/bytecode.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/bytecode.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -167,10 +167,20 @@ inline Bytecode_tableswitch* Bytecode_ta
+diff -r aa0c48844632 src/share/vm/interpreter/bytecode.hpp
+--- a/src/share/vm/interpreter/bytecode.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/bytecode.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -175,10 +175,20 @@ inline Bytecode_tableswitch* Bytecode_ta
class Bytecode_invoke: public ResourceObj {
protected:
@@ -5937,7 +5766,7 @@ diff -r ce2272390558 src/share/vm/interp
public:
void verify() const;
-@@ -191,6 +201,7 @@ class Bytecode_invoke: public ResourceOb
+@@ -199,6 +209,7 @@ class Bytecode_invoke: public ResourceOb
methodHandle static_target(TRAPS); // "specified" method (from constant pool)
// Testers
@@ -5945,9 +5774,9 @@ diff -r ce2272390558 src/share/vm/interp
bool is_invokeinterface() const { return adjusted_invoke_code() == Bytecodes::_invokeinterface; }
bool is_invokevirtual() const { return adjusted_invoke_code() == Bytecodes::_invokevirtual; }
bool is_invokestatic() const { return adjusted_invoke_code() == Bytecodes::_invokestatic; }
-diff -r ce2272390558 src/share/vm/interpreter/bytecodeStream.cpp
---- a/src/share/vm/interpreter/bytecodeStream.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/bytecodeStream.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/bytecodeStream.cpp
+--- a/src/share/vm/interpreter/bytecodeStream.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/bytecodeStream.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -37,14 +37,24 @@ Bytecodes::Code RawBytecodeStream::raw_n
_next_bci += l;
assert(_bci < _next_bci, "length must be > 0");
@@ -5975,9 +5804,9 @@ diff -r ce2272390558 src/share/vm/interp
}
}
}
-diff -r ce2272390558 src/share/vm/interpreter/bytecodeStream.hpp
---- a/src/share/vm/interpreter/bytecodeStream.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/bytecodeStream.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/bytecodeStream.hpp
+--- a/src/share/vm/interpreter/bytecodeStream.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/bytecodeStream.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -47,16 +47,17 @@ class RawBytecodeStream: StackObj {
int _bci; // bci if current bytecode
int _next_bci; // bci of next bytecode
@@ -6025,21 +5854,33 @@ diff -r ce2272390558 src/share/vm/interp
+ int prefix_length() const { return has_prefix() ? 1 : 0; } // all prefixes are 1 byte
+ bool is_wide_index() const { return _prefix == Bytecodes::Prefix_wide_index; }
+ bool is_tail_call() const { return _prefix == Bytecodes::Prefix_tail_call;}
+ int instruction_size() const { return (_next_bci - _bci); }
bool is_last_bytecode() const { return _next_bci >= _end_bci; }
- address bcp() const { return method()->code_base() + _bci; }
-@@ -122,8 +127,8 @@ class RawBytecodeStream: StackObj {
+@@ -123,10 +128,10 @@ class RawBytecodeStream: StackObj {
int dest_w() const { return bci() + (int )Bytes::get_Java_u4(bcp() + 1); }
// Unsigned indices, widening
-- int get_index() const { return (is_wide()) ? Bytes::get_Java_u2(bcp() + 2) : bcp()[1]; }
-- int get_index_big() const { return (int)Bytes::get_Java_u2(bcp() + 1); }
-+ int get_index() const { return (is_wide_index()) ? Bytes::get_Java_u2(bcp() + 2) : bcp()[1]; }
-+ int get_index_big() const { return (int)Bytes::get_Java_u2(bcp() + prefix_length() + 1); }
- };
-
- // In BytecodeStream, non-java bytecodes will be translated into the
-@@ -151,18 +156,23 @@ class BytecodeStream: public RawBytecode
+- int get_index() const { assert_index_size(is_wide() ? 2 : 1);
+- return (is_wide()) ? Bytes::get_Java_u2(bcp() + 2) : bcp()[1]; }
++ int get_index() const { assert_index_size(is_wide_index() ? 2 : 1);
++ return (is_wide_index()) ? Bytes::get_Java_u2(bcp() + 2) : bcp()[1]; }
+ int get_index_big() const { assert_index_size(2);
+- return (int)Bytes::get_Java_u2(bcp() + 1); }
++ return (int)Bytes::get_Java_u2(bcp() + prefix_length() + 1); }
+ int get_index_int() const { return has_giant_index() ? get_index_giant() : get_index_big(); }
+ int get_index_giant() const { assert_index_size(4); return Bytes::get_native_u4(bcp() + 1); }
+ int has_giant_index() const { return (code() == Bytecodes::_invokedynamic); }
+@@ -134,7 +139,7 @@ class RawBytecodeStream: StackObj {
+ private:
+ void assert_index_size(int required_size) const {
+ #ifdef ASSERT
+- int isize = instruction_size() - (int)_is_wide - 1;
++ int isize = instruction_size() - (int)is_wide_index() - 1;
+ if (isize == 2 && code() == Bytecodes::_iinc)
+ isize = 1;
+ else if (isize <= 2)
+@@ -173,18 +178,23 @@ class BytecodeStream: public RawBytecode
// note that we cannot advance before having the
// tty bytecode otherwise the stepping is wrong!
// (carefull: length_for(...) must be used first!)
@@ -6074,9 +5915,9 @@ diff -r ce2272390558 src/share/vm/interp
}
_code = code;
return _code;
-diff -r ce2272390558 src/share/vm/interpreter/bytecodeTracer.cpp
---- a/src/share/vm/interpreter/bytecodeTracer.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/bytecodeTracer.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/bytecodeTracer.cpp
+--- a/src/share/vm/interpreter/bytecodeTracer.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/bytecodeTracer.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -38,7 +38,7 @@ class BytecodePrinter: public BytecodeCl
// operations on the pointer, except within a critical section.
// (Also, ensure that occasional false positives are benign.)
@@ -6086,12 +5927,13 @@ diff -r ce2272390558 src/share/vm/interp
address _next_pc; // current decoding position
void align() { _next_pc = (address)round_to((intptr_t)_next_pc, sizeof(jint)); }
-@@ -48,10 +48,11 @@ class BytecodePrinter: public BytecodeCl
+@@ -48,11 +48,12 @@ class BytecodePrinter: public BytecodeCl
int get_index() { return *(address)_next_pc++; }
int get_big_index() { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; }
++ int get_index_special() { return (is_wide_index()) ? get_big_index() : get_index(); }
+ int get_giant_index() { int i=Bytes::get_native_u4(_next_pc); _next_pc+=4; return i; }
- int get_index_special() { return (is_wide()) ? get_big_index() : get_index(); }
-+ int get_index_special() { return (is_wide_index()) ? get_big_index() : get_index(); }
methodOop method() { return _current_method; }
- bool is_wide() { return _is_wide; }
-
@@ -6099,9 +5941,9 @@ diff -r ce2272390558 src/share/vm/interp
+ int prefix_length() const { return has_prefix() ? 1 : 0; }
+ bool is_wide_index() const { return _prefix == Bytecodes::Prefix_wide_index; }
+ bool check_index(int i, bool in_cp_cache, int& cp_index, outputStream* st = tty);
void print_constant(int i, outputStream* st = tty);
- void print_attributes(Bytecodes::Code code, int bci, outputStream* st = tty);
-@@ -59,7 +60,7 @@ class BytecodePrinter: public BytecodeCl
+@@ -62,7 +63,7 @@ class BytecodePrinter: public BytecodeCl
public:
BytecodePrinter() {
@@ -6110,7 +5952,7 @@ diff -r ce2272390558 src/share/vm/interp
}
// This method is called while executing the raw bytecodes, so none of
-@@ -80,26 +81,32 @@ class BytecodePrinter: public BytecodeCl
+@@ -83,26 +84,32 @@ class BytecodePrinter: public BytecodeCl
_current_method = method();
}
Bytecodes::Code code;
@@ -6152,7 +5994,7 @@ diff -r ce2272390558 src/share/vm/interp
}
// Used for methodOop::print_codes(). The input bcp comes from
-@@ -108,19 +115,18 @@ class BytecodePrinter: public BytecodeCl
+@@ -111,19 +118,18 @@ class BytecodePrinter: public BytecodeCl
_current_method = method();
ResourceMark rm;
Bytecodes::Code code = Bytecodes::code_at(bcp);
@@ -6180,7 +6022,7 @@ diff -r ce2272390558 src/share/vm/interp
print_attributes(code, bci, st);
bytecode_epilog(bci, st);
}
-@@ -250,7 +256,7 @@ void BytecodePrinter::print_attributes(B
+@@ -341,7 +347,7 @@ void BytecodePrinter::print_attributes(B
case Bytecodes::_iinc:
{ int index = get_index_special();
@@ -6189,9 +6031,9 @@ diff -r ce2272390558 src/share/vm/interp
st->print_cr(" #%d " INT32_FORMAT, index, offset);
}
break;
-diff -r ce2272390558 src/share/vm/interpreter/bytecodes.cpp
---- a/src/share/vm/interpreter/bytecodes.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/bytecodes.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/bytecodes.cpp
+--- a/src/share/vm/interpreter/bytecodes.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/bytecodes.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -40,6 +40,8 @@ BasicType Bytecodes::_result_type
BasicType Bytecodes::_result_type [Bytecodes::number_of_codes];
s_char Bytecodes::_depth [Bytecodes::number_of_codes];
@@ -6315,12 +6157,12 @@ diff -r ce2272390558 src/share/vm/interp
+ def(_invokespecial , "invokespecial" , "bjj" , "Twbjj" , T_ILLEGAL, -1, true); // w=tailcall
+ def(_invokestatic , "invokestatic" , "bjj" , "Twbjj" , T_ILLEGAL, 0, true); // w=tailcall
+ def(_invokeinterface , "invokeinterface" , "bjj__", "Twbjj__", T_ILLEGAL, -1, true); // w=tailcall
- def(_xxxunusedxxx , "xxxunusedxxx" , NULL , NULL , T_VOID , 0, false);
+ def(_invokedynamic , "invokedynamic" , "bjjjj", NULL , T_ILLEGAL, -1, true );
def(_new , "new" , "bii" , NULL , T_OBJECT , 1, true );
def(_newarray , "newarray" , "bc" , NULL , T_OBJECT , 0, true );
-diff -r ce2272390558 src/share/vm/interpreter/bytecodes.hpp
---- a/src/share/vm/interpreter/bytecodes.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/bytecodes.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/bytecodes.hpp
+--- a/src/share/vm/interpreter/bytecodes.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/bytecodes.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -280,6 +280,16 @@ class Bytecodes: AllStatic {
number_of_codes
};
@@ -6421,9 +6263,9 @@ diff -r ce2272390558 src/share/vm/interp
static int length_at (address bcp) { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
static int java_length_at (address bcp) { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
static bool is_java_code (Code code) { return 0 <= code && code < number_of_java_codes; }
-diff -r ce2272390558 src/share/vm/interpreter/interpreter.cpp
---- a/src/share/vm/interpreter/interpreter.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/interpreter.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/interpreter.cpp
+--- a/src/share/vm/interpreter/interpreter.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/interpreter.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -130,6 +130,9 @@ address AbstractInterpreter::_slow_si
address AbstractInterpreter::_slow_signature_handler;
address AbstractInterpreter::_entry_table [AbstractInterpreter::number_of_method_entries];
@@ -6434,7 +6276,7 @@ diff -r ce2272390558 src/share/vm/interp
//------------------------------------------------------------------------------------------------------------------------
// Generation of complete interpreter
-@@ -356,11 +359,13 @@ address AbstractInterpreter::continuatio
+@@ -361,11 +364,13 @@ address AbstractInterpreter::continuatio
Thread *thread = Thread::current();
ResourceMark rm(thread);
methodHandle mh(thread, method);
@@ -6450,7 +6292,7 @@ diff -r ce2272390558 src/share/vm/interp
method->constants()->cache()->entry_at(index)->set_parameter_size(callee_parameters);
}
break;
-@@ -374,7 +379,33 @@ address AbstractInterpreter::continuatio
+@@ -379,7 +384,33 @@ address AbstractInterpreter::continuatio
case Bytecodes::_ldc2_w:
type = constant_pool_type( method, Bytes::get_Java_u2(bcp+1) );
break;
@@ -6485,9 +6327,9 @@ diff -r ce2272390558 src/share/vm/interp
default:
type = Bytecodes::result_type(code);
break;
-diff -r ce2272390558 src/share/vm/interpreter/interpreterRuntime.cpp
---- a/src/share/vm/interpreter/interpreterRuntime.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/interpreterRuntime.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/interpreterRuntime.cpp
+--- a/src/share/vm/interpreter/interpreterRuntime.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -235,6 +235,23 @@ IRT_ENTRY(void, InterpreterRuntime::thro
THROW_HANDLE(exception);
IRT_END
@@ -6512,7 +6354,7 @@ diff -r ce2272390558 src/share/vm/interp
IRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* name, char* message))
// lookup exception klass
-@@ -430,6 +447,10 @@ IRT_END
+@@ -448,6 +465,10 @@ IRT_END
IRT_ENTRY(void, InterpreterRuntime::throw_IncompatibleClassChangeError(JavaThread* thread))
THROW(vmSymbols::java_lang_IncompatibleClassChangeError());
@@ -6523,9 +6365,9 @@ diff -r ce2272390558 src/share/vm/interp
IRT_END
-diff -r ce2272390558 src/share/vm/interpreter/interpreterRuntime.hpp
---- a/src/share/vm/interpreter/interpreterRuntime.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/interpreterRuntime.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/interpreterRuntime.hpp
+--- a/src/share/vm/interpreter/interpreterRuntime.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/interpreterRuntime.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -33,7 +33,13 @@ class InterpreterRuntime: AllStatic {
// Helper functions to access current interpreter state
static frame last_frame(JavaThread *thread) { return thread->last_frame(); }
@@ -6541,7 +6383,7 @@ diff -r ce2272390558 src/share/vm/interp
static void set_bcp_and_mdp(address bcp, JavaThread*thread);
static Bytecodes::Code code(JavaThread *thread) {
// pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
-@@ -70,7 +76,10 @@ class InterpreterRuntime: AllStatic {
+@@ -74,7 +80,10 @@ class InterpreterRuntime: AllStatic {
static void create_klass_exception(JavaThread* thread, char* name, oopDesc* obj);
static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception);
static void throw_pending_exception(JavaThread* thread);
@@ -6552,9 +6394,9 @@ diff -r ce2272390558 src/share/vm/interp
// Statics & fields
static void resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode);
-diff -r ce2272390558 src/share/vm/interpreter/linkResolver.hpp
---- a/src/share/vm/interpreter/linkResolver.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/linkResolver.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/linkResolver.hpp
+--- a/src/share/vm/interpreter/linkResolver.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/linkResolver.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -69,7 +69,7 @@ class CallInfo: public LinkInfo {
methodHandle _resolved_method; // static target method
methodHandle _selected_method; // dynamic (actual) target method
@@ -6573,9 +6415,9 @@ diff -r ce2272390558 src/share/vm/interp
bool has_vtable_index() const { return _vtable_index >= 0; }
bool is_statically_bound() const { return _vtable_index == methodOopDesc::nonvirtual_vtable_index; }
int vtable_index() const {
-diff -r ce2272390558 src/share/vm/interpreter/oopMapCache.cpp
---- a/src/share/vm/interpreter/oopMapCache.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/oopMapCache.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/oopMapCache.cpp
+--- a/src/share/vm/interpreter/oopMapCache.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/oopMapCache.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -33,7 +33,7 @@ class OopMapCacheEntry: private Interpre
protected:
@@ -6659,9 +6501,9 @@ diff -r ce2272390558 src/share/vm/interp
entry->resource_copy(tmp);
FREE_C_HEAP_ARRAY(OopMapCacheEntry, tmp);
}
-diff -r ce2272390558 src/share/vm/interpreter/oopMapCache.hpp
---- a/src/share/vm/interpreter/oopMapCache.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/oopMapCache.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/oopMapCache.hpp
+--- a/src/share/vm/interpreter/oopMapCache.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/oopMapCache.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -177,7 +177,7 @@ class OopMapCache : public CHeapObj {
void lookup(methodHandle method, int bci, InterpreterOopMap* entry);
@@ -6671,10 +6513,10 @@ diff -r ce2272390558 src/share/vm/interp
// Helpers
// Iterate over the entries in the cached OopMapCacheEntry's
-diff -r ce2272390558 src/share/vm/interpreter/rewriter.cpp
---- a/src/share/vm/interpreter/rewriter.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/rewriter.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -113,7 +113,7 @@ methodHandle Rewriter::rewrite_method(me
+diff -r aa0c48844632 src/share/vm/interpreter/rewriter.cpp
+--- a/src/share/vm/interpreter/rewriter.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/rewriter.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -154,7 +154,7 @@ void Rewriter::scan_method(methodOop met
// moves, the bytecodes will also move.
No_Safepoint_Verifier nsv;
Bytecodes::Code c;
@@ -6683,34 +6525,25 @@ diff -r ce2272390558 src/share/vm/interp
// Bytecodes and their length
const address code_base = method->code_base();
const int code_length = method->code_size();
-@@ -122,6 +122,7 @@ methodHandle Rewriter::rewrite_method(me
- for (int bci = 0; bci < code_length; bci += bc_length) {
+@@ -164,6 +164,7 @@ void Rewriter::scan_method(methodOop met
address bcp = code_base + bci;
+ int prefix_length = 0;
c = (Bytecodes::Code)(*bcp);
+ is_wide = false;
// Since we have the code, see if we can get the length
// directly. Some more complicated bytecodes will report
-@@ -135,6 +136,7 @@ methodHandle Rewriter::rewrite_method(me
+@@ -177,6 +178,7 @@ void Rewriter::scan_method(methodOop met
// by 'wide'. We don't currently examine any of the bytecodes
// modified by wide, but in case we do in the future...
if (c == Bytecodes::_wide) {
+ is_wide = true;
+ prefix_length = 1;
c = (Bytecodes::Code)bcp[1];
}
- }
-@@ -162,6 +164,8 @@ methodHandle Rewriter::rewrite_method(me
- case Bytecodes::_invokestatic : // fall through
- case Bytecodes::_invokeinterface: {
- address p = bcp + 1;
-+ // Skip wide prefix
-+ if (is_wide) p++;
- Bytes::put_native_u2(p, index_map[Bytes::get_Java_u2(p)]);
- break;
- }
-diff -r ce2272390558 src/share/vm/interpreter/templateInterpreter.cpp
---- a/src/share/vm/interpreter/templateInterpreter.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/templateInterpreter.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/templateInterpreter.cpp
+--- a/src/share/vm/interpreter/templateInterpreter.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/templateInterpreter.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -50,6 +50,10 @@ void TemplateInterpreter::initialize() {
if (PrintInterpreter) print();
}
@@ -6722,7 +6555,7 @@ diff -r ce2272390558 src/share/vm/interp
// initialize dispatch table
_active_table = _normal_table;
}
-@@ -171,6 +175,8 @@ address TemplateInterpreter::_throw_N
+@@ -172,6 +176,8 @@ address TemplateInterpreter::_throw_N
address TemplateInterpreter::_throw_NullPointerException_entry = NULL;
address TemplateInterpreter::_throw_StackOverflowError_entry = NULL;
address TemplateInterpreter::_throw_exception_entry = NULL;
@@ -6731,7 +6564,7 @@ diff -r ce2272390558 src/share/vm/interp
#ifndef PRODUCT
EntryPoint TemplateInterpreter::_trace_code;
-@@ -181,8 +187,8 @@ EntryPoint TemplateInterpreter::_continu
+@@ -183,8 +189,8 @@ EntryPoint TemplateInterpreter::_continu
EntryPoint TemplateInterpreter::_continuation_entry;
EntryPoint TemplateInterpreter::_safept_entry;
@@ -6739,32 +6572,33 @@ diff -r ce2272390558 src/share/vm/interp
-address TemplateInterpreter::_return_5_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
+address TemplateInterpreter::_return_addr_tables[TemplateInterpreter::number_of_invoke_lengths]
+ [TemplateInterpreter::number_of_return_addrs];
+ address TemplateInterpreter::_return_5_unbox_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
DispatchTable TemplateInterpreter::_active_table;
- DispatchTable TemplateInterpreter::_normal_table;
-@@ -297,8 +303,11 @@ void TemplateInterpreterGenerator::gener
+@@ -316,9 +322,12 @@ void TemplateInterpreterGenerator::gener
for (int j = 0; j < number_of_states; j++) {
const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos};
-- Interpreter::_return_3_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 3);
-- Interpreter::_return_5_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 5);
+ for (int k = Interpreter::min_invoke_length; k <= Interpreter::max_invoke_length; k++) {
+ if (!TailCalls && k != 3 && k != 5) continue;
+ int jx = Interpreter::TosState_as_index(states[j]);
+ Interpreter::return_addrs_by_index_table(k)[jx] = Interpreter::return_entry(states[j], k);
+ }
+ int index = Interpreter::TosState_as_index(states[j]);
+- Interpreter::_return_3_addrs_by_index[index] = Interpreter::return_entry(states[j], 3);
+- Interpreter::_return_5_addrs_by_index[index] = Interpreter::return_entry(states[j], 5);
+ if (EnableInvokeDynamic)
+ Interpreter::_return_5_unbox_addrs_by_index[index] = Interpreter::return_unbox_entry(states[j], 5);
}
-
- { CodeletMark cm(_masm, "continuation entry points");
-@@ -343,6 +352,7 @@ void TemplateInterpreterGenerator::gener
- Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler();
+@@ -366,6 +375,7 @@ void TemplateInterpreterGenerator::gener
+ Interpreter::_throw_WrongMethodType_entry = generate_WrongMethodType_handler();
Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL );
Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler();
+ Interpreter::_tail_call_handle_stack_overflow_entry = generate_tail_call_stack_overflow_handler();
}
-@@ -438,11 +448,13 @@ void TemplateInterpreterGenerator::set_e
+@@ -462,11 +472,13 @@ void TemplateInterpreterGenerator::set_e
Template* t = TemplateTable::template_for(code);
assert(t->is_valid(), "just checking");
set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);
@@ -6783,7 +6617,7 @@ diff -r ce2272390558 src/share/vm/interp
}
// set entry points
EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep);
-@@ -489,7 +501,7 @@ void TemplateInterpreterGenerator::gener
+@@ -513,7 +525,7 @@ void TemplateInterpreterGenerator::gener
#endif // !PRODUCT
int step;
if (!t->does_dispatch()) {
@@ -6792,7 +6626,7 @@ diff -r ce2272390558 src/share/vm/interp
if (tos_out == ilgl) tos_out = t->tos_out();
// compute bytecode size
assert(step > 0, "just checkin'");
-@@ -519,6 +531,12 @@ void TemplateInterpreterGenerator::gener
+@@ -543,6 +555,12 @@ void TemplateInterpreterGenerator::gener
address TemplateInterpreter::return_entry(TosState state, int length) {
guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length");
@@ -6805,20 +6639,20 @@ diff -r ce2272390558 src/share/vm/interp
return _return_entry[length].entry(state);
}
-diff -r ce2272390558 src/share/vm/interpreter/templateInterpreter.hpp
---- a/src/share/vm/interpreter/templateInterpreter.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/templateInterpreter.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -84,7 +84,8 @@ class TemplateInterpreter: public Abstra
+diff -r aa0c48844632 src/share/vm/interpreter/templateInterpreter.hpp
+--- a/src/share/vm/interpreter/templateInterpreter.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/templateInterpreter.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -85,7 +85,8 @@ class TemplateInterpreter: public Abstra
enum MoreConstants {
- number_of_return_entries = 9, // number of return entry points
- number_of_deopt_entries = 9, // number of deoptimization entry points
-- number_of_return_addrs = 9 // number of return addresses
-+ number_of_return_addrs = 9, // number of return addresses
+ number_of_return_entries = number_of_states, // number of return entry points
+ number_of_deopt_entries = number_of_states, // number of deoptimization entry points
+- number_of_return_addrs = number_of_states // number of return addresses
++ number_of_return_addrs = number_of_states, // number of return addresses
+ number_of_invoke_lengths = 4 // 3 - 6
};
protected:
-@@ -97,7 +98,8 @@ class TemplateInterpreter: public Abstra
+@@ -99,7 +100,8 @@ class TemplateInterpreter: public Abstra
static address _throw_exception_entry;
static address _throw_StackOverflowError_entry;
@@ -6828,20 +6662,18 @@ diff -r ce2272390558 src/share/vm/interp
static address _remove_activation_entry; // continuation address if an exception is not handled by current frame
#ifdef HOTSWAP
static address _remove_activation_preserving_args_entry; // continuation address when current frame is being popped
-@@ -112,8 +114,11 @@ class TemplateInterpreter: public Abstra
+@@ -115,8 +117,7 @@ class TemplateInterpreter: public Abstra
static EntryPoint _continuation_entry;
static EntryPoint _safept_entry;
-+#if 0
- static address _return_3_addrs_by_index[number_of_return_addrs]; // for invokevirtual return entries
- static address _return_5_addrs_by_index[number_of_return_addrs]; // for invokeinterface return entries
-+#endif
+- static address _return_3_addrs_by_index[number_of_return_addrs]; // for invokevirtual return entries
+- static address _return_5_addrs_by_index[number_of_return_addrs]; // for invokeinterface return entries
+ static address _return_addr_tables[number_of_invoke_lengths][number_of_return_addrs];
+ static address _return_5_unbox_addrs_by_index[number_of_return_addrs]; // for invokedynamic bootstrap methods
static DispatchTable _active_table; // the active dispatch table (used by the interpreter for dispatch)
- static DispatchTable _normal_table; // the normal dispatch table (used to set the active table in normal mode)
-@@ -139,7 +144,9 @@ class TemplateInterpreter: public Abstra
- static address throw_ArithmeticException_entry() { return _throw_ArithmeticException_entry; }
+@@ -144,7 +145,9 @@ class TemplateInterpreter: public Abstra
+ static address throw_WrongMethodType_entry() { return _throw_WrongMethodType_entry; }
static address throw_NullPointerException_entry() { return _throw_NullPointerException_entry; }
static address throw_StackOverflowError_entry() { return _throw_StackOverflowError_entry; }
-
@@ -6851,7 +6683,7 @@ diff -r ce2272390558 src/share/vm/interp
// Code generation
#ifndef PRODUCT
static address trace_code (TosState state) { return _trace_code.entry(state); }
-@@ -152,14 +159,15 @@ class TemplateInterpreter: public Abstra
+@@ -157,8 +160,9 @@ class TemplateInterpreter: public Abstra
static address* normal_table() { return _normal_table.table_for(); }
// Support for invokes
@@ -6860,19 +6692,21 @@ diff -r ce2272390558 src/share/vm/interp
+ static address* return_3_addrs_by_index_table() { return return_addrs_by_index_table(3); }
+ static address* return_5_addrs_by_index_table() { return return_addrs_by_index_table(5); }
+ static address* return_addrs_by_index_table(int inst_size) { assert(inst_size >= 3 && inst_size <=6, "wrong size"); return _return_addr_tables[inst_size-AbstractInterpreter::min_invoke_length];}
+ static address* return_5_unbox_addrs_by_index_table() { return _return_5_unbox_addrs_by_index; }
static int TosState_as_index(TosState state); // computes index into return_3_entry_by_index table
- static address return_entry (TosState state, int length);
+@@ -166,7 +170,7 @@ class TemplateInterpreter: public Abstra
static address deopt_entry (TosState state, int length);
+ static address return_unbox_entry(TosState state, int length);
- // Safepoint support
+ // Safepoint supportx
static void notice_safepoints(); // stops the thread when reaching a safepoint
static void ignore_safepoints(); // ignores safepoints
-diff -r ce2272390558 src/share/vm/interpreter/templateInterpreterGenerator.hpp
---- a/src/share/vm/interpreter/templateInterpreterGenerator.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/templateInterpreterGenerator.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/templateInterpreterGenerator.hpp
+--- a/src/share/vm/interpreter/templateInterpreterGenerator.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/templateInterpreterGenerator.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -40,6 +40,7 @@ class TemplateInterpreterGenerator: publ
address generate_slow_signature_handler();
address generate_error_exit(const char* msg);
@@ -6881,9 +6715,9 @@ diff -r ce2272390558 src/share/vm/interp
address generate_exception_handler(const char* name, const char* message) {
return generate_exception_handler_common(name, message, false);
}
-diff -r ce2272390558 src/share/vm/interpreter/templateTable.cpp
---- a/src/share/vm/interpreter/templateTable.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/templateTable.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/templateTable.cpp
+--- a/src/share/vm/interpreter/templateTable.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/templateTable.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -37,19 +37,21 @@ void templateTable_init() {
// Implementation of Template
@@ -6967,7 +6801,7 @@ diff -r ce2272390558 src/share/vm/interp
def(Bytecodes::_nop , ____|____|____|____, vtos, vtos, nop , _ );
def(Bytecodes::_aconst_null , ____|____|____|____, vtos, atos, aconst_null , _ );
def(Bytecodes::_iconst_m1 , ____|____|____|____, vtos, itos, iconst , -1 );
-@@ -473,6 +483,13 @@ void TemplateTable::initialize() {
+@@ -474,6 +484,13 @@ void TemplateTable::initialize() {
def(Bytecodes::_ret , ubcp|disp|____|iswd, vtos, vtos, wide_ret , _ );
def(Bytecodes::_breakpoint , ubcp|disp|clvm|____, vtos, vtos, _breakpoint , _ );
@@ -6995,9 +6829,9 @@ diff -r ce2272390558 src/share/vm/interp
+ _masm->unimplemented(buf);
}
#endif /* !CC_INTERP */
-diff -r ce2272390558 src/share/vm/interpreter/templateTable.hpp
---- a/src/share/vm/interpreter/templateTable.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/interpreter/templateTable.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/interpreter/templateTable.hpp
+--- a/src/share/vm/interpreter/templateTable.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/interpreter/templateTable.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -47,14 +47,19 @@ class Template VALUE_OBJ_CLASS_SPEC {
TosState _tos_in; // tos cache state before template execution
TosState _tos_out; // tos cache state after template execution
@@ -7033,9 +6867,9 @@ diff -r ce2272390558 src/share/vm/interp
Register method,
Register itable_index,
Register flags,
-@@ -262,6 +268,15 @@ class TemplateTable: AllStatic {
- static void invokestatic(int byte_no);
+@@ -263,6 +269,15 @@ class TemplateTable: AllStatic {
static void invokeinterface(int byte_no);
+ static void invokedynamic(int byte_no);
static void fast_invokevfinal(int byte_no);
+ // Tail calls
+ static void wide_invokevirtual(int byte_no);
@@ -7049,7 +6883,7 @@ diff -r ce2272390558 src/share/vm/interp
static void getfield_or_static(int byte_no, bool is_static);
static void putfield_or_static(int byte_no, bool is_static);
-@@ -322,7 +337,16 @@ class TemplateTable: AllStatic {
+@@ -323,7 +338,16 @@ class TemplateTable: AllStatic {
// Templates
static Template* template_for (Bytecodes::Code code) { Bytecodes::check (code); return &_template_table [code]; }
@@ -7067,9 +6901,9 @@ diff -r ce2272390558 src/share/vm/interp
// Platform specifics
#include "incls/_templateTable_pd.hpp.incl"
-diff -r ce2272390558 src/share/vm/memory/space.cpp
---- a/src/share/vm/memory/space.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/memory/space.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/memory/space.cpp
+--- a/src/share/vm/memory/space.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/memory/space.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -790,6 +790,9 @@ size_t ContiguousSpace::block_size(const
assert(MemRegion(bottom(), end()).contains(p), "p not in space");
HeapWord* current_top = top();
@@ -7080,9 +6914,9 @@ diff -r ce2272390558 src/share/vm/memory
assert(p == current_top || oop(p)->is_oop(), "p is not a block start");
if (p < current_top)
return oop(p)->size();
-diff -r ce2272390558 src/share/vm/oops/generateOopMap.cpp
---- a/src/share/vm/oops/generateOopMap.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/oops/generateOopMap.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/oops/generateOopMap.cpp
+--- a/src/share/vm/oops/generateOopMap.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/oops/generateOopMap.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -549,7 +549,7 @@ bool GenerateOopMap::jump_targets_do(Byt
break;
}
@@ -7092,7 +6926,7 @@ diff -r ce2272390558 src/share/vm/oops/g
(*jmpFct)(this, bcs->dest(), data);
-@@ -1319,7 +1319,14 @@ void GenerateOopMap::interp1(BytecodeStr
+@@ -1322,7 +1322,14 @@ void GenerateOopMap::interp1(BytecodeStr
break;
}
}
@@ -7108,7 +6942,7 @@ diff -r ce2272390558 src/share/vm/oops/g
// abstract interpretation of current opcode
switch(itr->code()) {
case Bytecodes::_nop: break;
-@@ -1921,6 +1928,13 @@ void GenerateOopMap::do_method(int is_st
+@@ -1925,6 +1932,13 @@ void GenerateOopMap::do_method(int is_st
int arg_length = cse.compute_for_parameters(is_static != 0, in);
assert(arg_length<=MAXARGSIZE, "too many locals");
@@ -7122,7 +6956,7 @@ diff -r ce2272390558 src/share/vm/oops/g
// Pop arguments
for (int i = arg_length - 1; i >= 0; i--) ppop1(in[i]);// Do args in reverse order.
-@@ -2007,7 +2021,7 @@ GenerateOopMap::GenerateOopMap(methodHan
+@@ -2011,7 +2025,7 @@ GenerateOopMap::GenerateOopMap(methodHan
_method = method;
_max_locals=0;
_init_vars = NULL;
@@ -7131,7 +6965,7 @@ diff -r ce2272390558 src/share/vm/oops/g
#ifndef PRODUCT
// If we are doing a detailed trace, include the regular trace information.
if (TraceNewOopMapGenerationDetailed) {
-@@ -2016,7 +2030,7 @@ GenerateOopMap::GenerateOopMap(methodHan
+@@ -2020,7 +2034,7 @@ GenerateOopMap::GenerateOopMap(methodHan
#endif
}
@@ -7140,7 +6974,7 @@ diff -r ce2272390558 src/share/vm/oops/g
#ifndef PRODUCT
if (TimeOopMap2) {
method()->print_short_name(tty);
-@@ -2039,10 +2053,12 @@ void GenerateOopMap::compute_map(TRAPS)
+@@ -2043,10 +2057,12 @@ void GenerateOopMap::compute_map(TRAPS)
_init_vars = new GrowableArray<intptr_t>(5); // There are seldom more than 5 init_vars
_report_result = false;
_report_result_for_send = false;
@@ -7153,9 +6987,9 @@ diff -r ce2272390558 src/share/vm/oops/g
if (TraceNewOopMapGeneration) {
tty->print("Method name: %s\n", method()->name()->as_C_string());
-diff -r ce2272390558 src/share/vm/oops/generateOopMap.hpp
---- a/src/share/vm/oops/generateOopMap.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/oops/generateOopMap.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/oops/generateOopMap.hpp
+--- a/src/share/vm/oops/generateOopMap.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/oops/generateOopMap.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -298,7 +298,9 @@ class GenerateOopMap VALUE_OBJ_CLASS_SPE
bool _did_relocation; // was relocation neccessary
bool _monitor_safe; // The monitors in this method have been determined
@@ -7212,10 +7046,10 @@ diff -r ce2272390558 src/share/vm/oops/g
+
+ // Call compute_map(CHECK) to generate info.
+};
-diff -r ce2272390558 src/share/vm/oops/instanceKlass.hpp
---- a/src/share/vm/oops/instanceKlass.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/oops/instanceKlass.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -578,6 +578,7 @@ class instanceKlass: public Klass {
+diff -r aa0c48844632 src/share/vm/oops/instanceKlass.hpp
+--- a/src/share/vm/oops/instanceKlass.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/oops/instanceKlass.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -603,6 +603,7 @@ class instanceKlass: public Klass {
int object_size() const { return object_size(align_object_offset(vtable_length()) + align_object_offset(itable_length()) + static_field_size() + nonstatic_oop_map_size()); }
static int vtable_start_offset() { return header_size(); }
static int vtable_length_offset() { return oopDesc::header_size() + offset_of(instanceKlass, _vtable_len) / HeapWordSize; }
@@ -7223,9 +7057,9 @@ diff -r ce2272390558 src/share/vm/oops/i
static int object_size(int extra) { return align_object_size(header_size() + extra); }
intptr_t* start_of_vtable() const { return ((intptr_t*)as_klassOop()) + vtable_start_offset(); }
-diff -r ce2272390558 src/share/vm/oops/methodKlass.cpp
---- a/src/share/vm/oops/methodKlass.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/oops/methodKlass.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/oops/methodKlass.cpp
+--- a/src/share/vm/oops/methodKlass.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/oops/methodKlass.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -72,6 +72,7 @@ methodOop methodKlass::allocate(constMet
m->set_method_data(NULL);
m->set_interpreter_throwout_count(0);
@@ -7234,9 +7068,9 @@ diff -r ce2272390558 src/share/vm/oops/m
// Fix and bury in methodOop
m->set_interpreter_entry(NULL); // sets i2i entry and from_int
-diff -r ce2272390558 src/share/vm/oops/methodOop.cpp
---- a/src/share/vm/oops/methodOop.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/oops/methodOop.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/oops/methodOop.cpp
+--- a/src/share/vm/oops/methodOop.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/oops/methodOop.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -41,6 +41,26 @@ address methodOopDesc::get_c2i_unverifie
address methodOopDesc::get_c2i_unverified_entry() {
assert(_adapter != NULL, "must have");
@@ -7282,44 +7116,49 @@ diff -r ce2272390558 src/share/vm/oops/m
#endif
instanceKlass::cast(method_holder())->mask_for(h_this, bci, mask);
return;
-@@ -608,8 +630,14 @@ void methodOopDesc::clear_code() {
+@@ -619,8 +641,12 @@ void methodOopDesc::clear_code() {
// Only should happen at allocate time.
if (_adapter == NULL) {
_from_compiled_entry = NULL;
+ _from_compiled_tail_call_entry = NULL;
+ _from_compiled_not_sibling_tail_call_entry = NULL;
-+ _from_compiled_pd_mismatch_entry = NULL;
} else {
_from_compiled_entry = _adapter->get_c2i_entry();
+ _from_compiled_tail_call_entry = _adapter->get_c2i_verified_tail_call_entry();
+ _from_compiled_not_sibling_tail_call_entry = _adapter->get_c2i_verified_not_sibling_tail_call_entry();
-+ _from_compiled_pd_mismatch_entry = _adapter->get_pd_check_failed_entry();
}
OrderAccess::storestore();
_from_interpreted_entry = _i2i_entry;
-@@ -631,6 +659,9 @@ void methodOopDesc::unlink_method() {
+@@ -642,6 +668,8 @@ void methodOopDesc::unlink_method() {
backedge_counter()->reset();
_adapter = NULL;
_from_compiled_entry = NULL;
+ _from_compiled_tail_call_entry = NULL;
+ _from_compiled_not_sibling_tail_call_entry = NULL;
-+ _from_compiled_pd_mismatch_entry = NULL;
assert(_method_data == NULL, "unexpected method data?");
set_method_data(NULL);
set_interpreter_throwout_count(0);
-@@ -682,6 +713,11 @@ address methodOopDesc::make_adapters(met
+@@ -682,7 +710,7 @@ void methodOopDesc::link_method(methodHa
+
+ }
+
+-address methodOopDesc::make_adapters(methodHandle mh, TRAPS) {
++ address methodOopDesc::make_adapters(methodHandle mh, TRAPS) {
+ // Adapters for compiled code are made eagerly here. They are fairly
+ // small (generally < 100 bytes) and quick to make (and cached and shared)
+ // so making them eagerly shouldn't be too expensive.
+@@ -693,6 +721,10 @@ address methodOopDesc::make_adapters(met
mh->set_adapter_entry(adapter);
mh->_from_compiled_entry = adapter->get_c2i_entry();
+ mh->_from_compiled_tail_call_entry = adapter->get_c2i_verified_tail_call_entry();
+ mh->_from_compiled_not_sibling_tail_call_entry =
+ adapter->get_c2i_verified_not_sibling_tail_call_entry();
-+ mh->_from_compiled_pd_mismatch_entry =
-+ adapter->get_pd_check_failed_entry();
++
return adapter->get_c2i_entry();
}
-@@ -696,6 +732,19 @@ address methodOopDesc::verified_code_ent
+@@ -707,6 +739,19 @@ address methodOopDesc::verified_code_ent
debug_only(No_Safepoint_Verifier nsv;)
assert(_from_compiled_entry != NULL, "must be set");
return _from_compiled_entry;
@@ -7339,7 +7178,7 @@ diff -r ce2272390558 src/share/vm/oops/m
}
// Check that if an nmethod ref exists, it has a backlink to this or no backlink at all
-@@ -725,13 +774,22 @@ void methodOopDesc::set_code(methodHandl
+@@ -736,13 +781,19 @@ void methodOopDesc::set_code(methodHandl
if (comp_level > highest_tier_compile()) {
set_highest_tier_compile(comp_level);
}
@@ -7353,9 +7192,6 @@ diff -r ce2272390558 src/share/vm/oops/m
+ mh->_from_compiled_tail_call_entry = code->verified_tail_call_entry_point();
+ OrderAccess::storestore();
+ mh->_from_compiled_not_sibling_tail_call_entry = code->verified_not_sibling_tail_call_entry_point();
-+ OrderAccess::storestore();
-+ mh->_from_compiled_pd_mismatch_entry = code->verified_tail_call_pd_check_failed_entry_point();
-+
// Instantly compiled code can execute.
mh->_from_interpreted_entry = mh->get_i2c_entry();
-
@@ -7363,37 +7199,34 @@ diff -r ce2272390558 src/share/vm/oops/m
}
-diff -r ce2272390558 src/share/vm/oops/methodOop.hpp
---- a/src/share/vm/oops/methodOop.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/oops/methodOop.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -128,6 +128,14 @@ class methodOopDesc : public oopDesc {
+diff -r aa0c48844632 src/share/vm/oops/methodOop.hpp
+--- a/src/share/vm/oops/methodOop.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/oops/methodOop.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -128,6 +128,12 @@ class methodOopDesc : public oopDesc {
nmethod* volatile _code; // Points to the corresponding piece of native code
volatile address _from_interpreted_entry; // Cache of _code ? _adapter->i2c_entry() : _i2i_entry
+ // Entry point for tail calling from compiled code.
+ volatile address _from_compiled_tail_call_entry;
+ volatile address _from_compiled_not_sibling_tail_call_entry;
-+ volatile address _from_compiled_pd_mismatch_entry;
-+
+ // Probably should go in access flags but i am unsure whether there is a bit
+ // left.
+ bool _contains_tail_call;
public:
static const bool IsUnsafeConc = false;
-@@ -140,7 +148,11 @@ class methodOopDesc : public oopDesc {
+@@ -140,7 +146,10 @@ class methodOopDesc : public oopDesc {
static address make_adapters(methodHandle mh, TRAPS);
volatile address from_compiled_entry() const { return (address)OrderAccess::load_ptr_acquire(&_from_compiled_entry); }
+ volatile address from_compiled_tail_call_entry() const { return (address)OrderAccess::load_ptr_acquire(&_from_compiled_tail_call_entry); }
-+ volatile address from_compiled_pd_mismatch_entry() const { return (address)OrderAccess::load_ptr_acquire(&_from_compiled_pd_mismatch_entry); }
+ volatile address from_compiled_not_sibling_tail_call_entry() const { return (address)OrderAccess::load_ptr_acquire(&_from_compiled_not_sibling_tail_call_entry); }
volatile address from_interpreted_entry() const{ return (address)OrderAccess::load_ptr_acquire(&_from_interpreted_entry); }
+
// access flag
AccessFlags access_flags() const { return _access_flags; }
-@@ -302,6 +314,9 @@ class methodOopDesc : public oopDesc {
+@@ -302,6 +311,9 @@ class methodOopDesc : public oopDesc {
// nmethod/verified compiler entry
address verified_code_entry();
@@ -7403,7 +7236,7 @@ diff -r ce2272390558 src/share/vm/oops/m
bool check_code() const; // Not inline to avoid circular ref
nmethod* volatile code() const { assert( check_code(), "" ); return (nmethod *)OrderAccess::load_ptr_acquire(&_code); }
void clear_code(); // Clear out any compiled code
-@@ -310,6 +325,11 @@ class methodOopDesc : public oopDesc {
+@@ -310,6 +322,11 @@ class methodOopDesc : public oopDesc {
address get_i2c_entry();
address get_c2i_entry();
address get_c2i_unverified_entry();
@@ -7415,7 +7248,7 @@ diff -r ce2272390558 src/share/vm/oops/m
AdapterHandlerEntry* adapter() { return _adapter; }
// setup entry points
void link_method(methodHandle method, TRAPS);
-@@ -458,6 +478,11 @@ class methodOopDesc : public oopDesc {
+@@ -459,6 +476,11 @@ class methodOopDesc : public oopDesc {
bool guaranteed_monitor_matching() const { return access_flags().is_monitor_matching(); }
void set_guaranteed_monitor_matching() { _access_flags.set_monitor_matching(); }
@@ -7427,20 +7260,19 @@ diff -r ce2272390558 src/share/vm/oops/m
// returns true if the method is an accessor function (setter/getter).
bool is_accessor() const;
-@@ -486,6 +511,10 @@ class methodOopDesc : public oopDesc {
+@@ -487,6 +509,9 @@ class methodOopDesc : public oopDesc {
static ByteSize size_of_locals_offset() { return byte_offset_of(methodOopDesc, _max_locals ); }
static ByteSize size_of_parameters_offset() { return byte_offset_of(methodOopDesc, _size_of_parameters); }
static ByteSize from_compiled_offset() { return byte_offset_of(methodOopDesc, _from_compiled_entry); }
-+ static ByteSize from_compiled_tail_call_offset() { return byte_offset_of(methodOopDesc, _from_compiled_tail_call_entry); }
++ static ByteSize from_compiled_tail_call_offset() { return byte_offset_of(methodOopDesc, _from_compiled_tail_call_entry); }
+ static ByteSize from_compiled_not_sibling_tail_call_offset() { return byte_offset_of(methodOopDesc, _from_compiled_not_sibling_tail_call_entry); }
-+ static ByteSize from_compiled_pd_mismatch_offset() { return byte_offset_of(methodOopDesc, _from_compiled_pd_mismatch_entry); }
+
static ByteSize code_offset() { return byte_offset_of(methodOopDesc, _code); }
static ByteSize invocation_counter_offset() { return byte_offset_of(methodOopDesc, _invocation_counter); }
static ByteSize backedge_counter_offset() { return byte_offset_of(methodOopDesc, _backedge_counter); }
-diff -r ce2272390558 src/share/vm/opto/callGenerator.cpp
---- a/src/share/vm/opto/callGenerator.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/callGenerator.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/opto/callGenerator.cpp
+--- a/src/share/vm/opto/callGenerator.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/opto/callGenerator.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -25,8 +25,10 @@
#include "incls/_precompiled.incl"
#include "incls/_callGenerator.cpp.incl"
@@ -7602,9 +7434,9 @@ diff -r ce2272390558 src/share/vm/opto/c
}
-diff -r ce2272390558 src/share/vm/opto/callGenerator.hpp
---- a/src/share/vm/opto/callGenerator.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/callGenerator.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/opto/callGenerator.hpp
+--- a/src/share/vm/opto/callGenerator.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/opto/callGenerator.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -34,14 +34,16 @@ class CallGenerator : public ResourceObj
private:
@@ -7642,10 +7474,10 @@ diff -r ce2272390558 src/share/vm/opto/c
// How to make a call but defer the decision whether to inline or not.
static CallGenerator* for_warm_call(WarmCallInfo* ci,
-diff -r ce2272390558 src/share/vm/opto/callnode.hpp
---- a/src/share/vm/opto/callnode.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/callnode.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -522,12 +522,16 @@ protected:
+diff -r aa0c48844632 src/share/vm/opto/callnode.hpp
+--- a/src/share/vm/opto/callnode.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/opto/callnode.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -526,12 +526,16 @@ protected:
virtual uint size_of() const; // Size is bigger
bool _optimized_virtual;
@@ -7664,7 +7496,7 @@ diff -r ce2272390558 src/share/vm/opto/c
{
init_class_id(Class_CallJava);
}
-@@ -536,8 +540,11 @@ public:
+@@ -540,8 +544,11 @@ public:
ciMethod* method() const { return _method; }
void set_method(ciMethod *m) { _method = m; }
void set_optimized_virtual(bool f) { _optimized_virtual = f; }
@@ -7677,7 +7509,7 @@ diff -r ce2272390558 src/share/vm/opto/c
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
#endif
-@@ -551,8 +558,8 @@ class CallStaticJavaNode : public CallJa
+@@ -555,8 +562,8 @@ class CallStaticJavaNode : public CallJa
virtual uint cmp( const Node &n ) const;
virtual uint size_of() const; // Size is bigger
public:
@@ -7688,7 +7520,7 @@ diff -r ce2272390558 src/share/vm/opto/c
init_class_id(Class_CallStaticJava);
}
CallStaticJavaNode(const TypeFunc* tf, address addr, const char* name, int bci,
-@@ -580,7 +587,9 @@ class CallDynamicJavaNode : public CallJ
+@@ -584,7 +591,9 @@ class CallDynamicJavaNode : public CallJ
virtual uint cmp( const Node &n ) const;
virtual uint size_of() const; // Size is bigger
public:
@@ -7699,9 +7531,9 @@ diff -r ce2272390558 src/share/vm/opto/c
init_class_id(Class_CallDynamicJava);
}
-diff -r ce2272390558 src/share/vm/opto/compile.cpp
---- a/src/share/vm/opto/compile.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/compile.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/opto/compile.cpp
+--- a/src/share/vm/opto/compile.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/opto/compile.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -524,7 +524,7 @@ Compile::Compile( ciEnv* ci_env, C2Compi
init_start(s);
float past_uses = method()->interpreter_invocation_count();
@@ -7711,9 +7543,9 @@ diff -r ce2272390558 src/share/vm/opto/c
}
if (failing()) return;
if (cg == NULL) {
-diff -r ce2272390558 src/share/vm/opto/compile.hpp
---- a/src/share/vm/opto/compile.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/compile.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/opto/compile.hpp
+--- a/src/share/vm/opto/compile.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/opto/compile.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -473,7 +473,7 @@ class Compile : public Phase {
// Decide how to build a call.
@@ -7723,9 +7555,9 @@ diff -r ce2272390558 src/share/vm/opto/c
// Report if there were too many traps at a current method and bci.
// Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded.
-diff -r ce2272390558 src/share/vm/opto/doCall.cpp
---- a/src/share/vm/opto/doCall.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/doCall.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/opto/doCall.cpp
+--- a/src/share/vm/opto/doCall.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/opto/doCall.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -43,7 +43,7 @@ void trace_type_profile(ciMethod *method
}
#endif
@@ -7817,7 +7649,7 @@ diff -r ce2272390558 src/share/vm/opto/d
}
}
-@@ -266,7 +270,8 @@ void Parse::do_call() {
+@@ -274,7 +278,8 @@ void Parse::do_call() {
bool is_virtual = bc() == Bytecodes::_invokevirtual;
bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface;
bool has_receiver = is_virtual_or_interface || bc() == Bytecodes::_invokespecial;
@@ -7827,7 +7659,7 @@ diff -r ce2272390558 src/share/vm/opto/d
// Find target being called
bool will_link;
ciMethod* dest_method = iter().get_method(will_link);
-@@ -275,7 +280,10 @@ void Parse::do_call() {
+@@ -283,7 +288,10 @@ void Parse::do_call() {
ciInstanceKlass* klass = ciEnv::get_instance_klass_for_declared_method_holder(holder);
int nargs = dest_method->arg_size();
@@ -7839,7 +7671,7 @@ diff -r ce2272390558 src/share/vm/opto/d
// uncommon-trap when callee is unloaded, uninitialized or will not link
// bailout when too many arguments for register representation
if (!will_link || can_not_compile_call_site(dest_method, klass)) {
-@@ -336,7 +344,7 @@ void Parse::do_call() {
+@@ -344,7 +352,7 @@ void Parse::do_call() {
// Decide call tactic.
// This call checks with CHA, the interpreter profile, intrinsics table, etc.
// It decides whether inlining is desirable or not.
@@ -7848,9 +7680,9 @@ diff -r ce2272390558 src/share/vm/opto/d
// ---------------------
// Round double arguments before call
-diff -r ce2272390558 src/share/vm/opto/machnode.hpp
---- a/src/share/vm/opto/machnode.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/machnode.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/opto/machnode.hpp
+--- a/src/share/vm/opto/machnode.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/opto/machnode.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -661,7 +661,10 @@ public:
public:
ciMethod* _method; // Method being direct called
@@ -7863,9 +7695,9 @@ diff -r ce2272390558 src/share/vm/opto/m
MachCallJavaNode() : MachCallNode() {
init_class_id(Class_MachCallJava);
}
-diff -r ce2272390558 src/share/vm/opto/matcher.cpp
---- a/src/share/vm/opto/matcher.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/matcher.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/opto/matcher.cpp
+--- a/src/share/vm/opto/matcher.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/opto/matcher.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -244,6 +244,15 @@ void Matcher::match( ) {
// Saved biased stack-slot register number
@@ -7882,74 +7714,16 @@ diff -r ce2272390558 src/share/vm/opto/m
}
// Finally, make sure the incoming arguments take up an even number of
-@@ -955,6 +964,29 @@ OptoReg::Name Matcher::warp_outgoing_stk
- return OptoReg::as_OptoReg(reg);
- }
-
-+OptoReg::Name Matcher::warp_outgoing_stk_arg_tailcall( VMReg reg, OptoReg::Name begin_out_arg_area, OptoReg::Name &out_arg_limit_per_call ) {
-+ // Convert outgoing argument location to a pre-biased stack offset
-+ if (reg->is_stack()) {
-+ OptoReg::Name warped = reg->reg2stack();
-+ OptoReg::Name warped_tailcall = reg->reg2stack();
-+
-+ // Adjust the stack slot offset to be the register number used
-+ // by the allocator.
-+ warped = OptoReg::add(begin_out_arg_area, warped);
-+ warped_tailcall = OptoReg::add(_old_SP, warped_tailcall);
-+ // Keep track of the largest numbered stack slot used for an arg.
-+ // Largest used slot per call-site indicates the amount of stack
-+ // that is killed by the call.
-+ if( warped >= out_arg_limit_per_call )
-+ out_arg_limit_per_call = OptoReg::add(warped,1);
-+ if (!RegMask::can_represent(warped)) {
-+ C->record_method_not_compilable_all_tiers("unsupported calling sequence");
-+ return OptoReg::Bad;
-+ }
-+ return warped_tailcall;
-+ }
-+ return OptoReg::as_OptoReg(reg);
-+}
-
- //------------------------------match_sfpt-------------------------------------
- // Helper function to match call instructions. Calls match special.
-@@ -968,6 +1000,7 @@ MachNode *Matcher::match_sfpt( SafePoint
- CallNode *call;
- const TypeTuple *domain;
- ciMethod* method = NULL;
-+ bool is_sibling_tailcall = false;
- if( sfpt->is_Call() ) {
- call = sfpt->as_Call();
- domain = call->tf()->domain();
-@@ -992,6 +1025,10 @@ MachNode *Matcher::match_sfpt( SafePoint
+@@ -1009,6 +1018,8 @@ MachNode *Matcher::match_sfpt( SafePoint
mcall_java->_method = method;
mcall_java->_bci = call_java->_bci;
mcall_java->_optimized_virtual = call_java->is_optimized_virtual();
+ mcall_java->_is_tail_call = call_java->is_tail_call();
+ mcall_java->_is_sibling = call_java->is_sibling();
-+ if (call_java->is_tail_call()&&call_java->is_sibling())
-+ is_sibling_tailcall = true;
if( mcall_java->is_MachCallStaticJava() )
mcall_java->as_MachCallStaticJava()->_name =
call_java->as_CallStaticJava()->_name;
-@@ -1091,11 +1128,15 @@ MachNode *Matcher::match_sfpt( SafePoint
- continue; // Avoid Halves
- }
- // Grab first register, adjust stack slots and insert in mask.
-- OptoReg::Name reg1 = warp_outgoing_stk_arg(parm_regs[i].first(), begin_out_arg_area, out_arg_limit_per_call );
-+ OptoReg::Name reg1 = is_sibling_tailcall ?
-+ warp_outgoing_stk_arg_tailcall(parm_regs[i].first(), begin_out_arg_area, out_arg_limit_per_call ):
-+ warp_outgoing_stk_arg(parm_regs[i].first(), begin_out_arg_area, out_arg_limit_per_call );
- if (OptoReg::is_valid(reg1))
- rm->Insert( reg1 );
- // Grab second register (if any), adjust stack slots and insert in mask.
-- OptoReg::Name reg2 = warp_outgoing_stk_arg(parm_regs[i].second(), begin_out_arg_area, out_arg_limit_per_call );
-+ OptoReg::Name reg2 = is_sibling_tailcall ?
-+ warp_outgoing_stk_arg_tailcall(parm_regs[i].second(), begin_out_arg_area, out_arg_limit_per_call ):
-+ warp_outgoing_stk_arg(parm_regs[i].second(), begin_out_arg_area, out_arg_limit_per_call );
- if (OptoReg::is_valid(reg2))
- rm->Insert( reg2 );
- } // End of for all arguments
-@@ -1103,6 +1144,15 @@ MachNode *Matcher::match_sfpt( SafePoint
+@@ -1120,6 +1131,15 @@ MachNode *Matcher::match_sfpt( SafePoint
// Compute number of stack slots needed to restore stack in case of
// Pascal-style argument popping.
mcall->_argsize = out_arg_limit_per_call - begin_out_arg_area;
@@ -7965,20 +7739,9 @@ diff -r ce2272390558 src/share/vm/opto/m
}
// Compute the max stack slot killed by any call. These will not be
-diff -r ce2272390558 src/share/vm/opto/matcher.hpp
---- a/src/share/vm/opto/matcher.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/matcher.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -185,6 +185,7 @@ public:
- MachNode *match_sfpt( SafePointNode *sfpt );
- // Helper for match_sfpt
- OptoReg::Name warp_outgoing_stk_arg( VMReg reg, OptoReg::Name begin_out_arg_area, OptoReg::Name &out_arg_limit_per_call );
-+ OptoReg::Name warp_outgoing_stk_arg_tailcall( VMReg reg, OptoReg::Name begin_out_arg_area, OptoReg::Name &out_arg_limit_per_call );
-
- // Initialize first stack mask and related masks.
- void init_first_stack_mask();
-diff -r ce2272390558 src/share/vm/opto/output.cpp
---- a/src/share/vm/opto/output.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/opto/output.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/opto/output.cpp
+--- a/src/share/vm/opto/output.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/opto/output.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -29,6 +29,10 @@ extern uint reloc_java_to_interp();
extern uint reloc_java_to_interp();
extern uint size_exception_handler();
@@ -7990,20 +7753,19 @@ diff -r ce2272390558 src/share/vm/opto/o
#ifndef PRODUCT
#define DEBUG_ARG(x) , x
-@@ -38,6 +42,12 @@ extern uint size_deopt_handler();
+@@ -38,7 +42,10 @@ extern uint size_deopt_handler();
extern int emit_exception_handler(CodeBuffer &cbuf);
extern int emit_deopt_handler(CodeBuffer &cbuf);
+-
+extern void emit_verified_tail_call_stub(Compile *C, CodeBuffer& cbuf, int arg_slots, int frame_size, CodeOffsets& code_offsets);
+extern void emit_tail_call_stub(Compile* C, CodeBuffer& cbuf, int arg_slots, int frame_size, CodeOffsets& code_offsets);
+extern void emit_verified_not_sib_tail_call_stub(CodeBuffer& cbuf, int arg_slots, int VEP_offset, CodeOffsets& code_offsets);
+extern void emit_not_sib_tail_call_stub(CodeBuffer& cbuf, int arg_slots, int VEP_offset, CodeOffsets& code_offsets);
-+extern void emit_pd_mismatch_tail_call_stub(Compile* C, CodeBuffer& cbuf, int arg_slots, int frame_size, CodeOffsets& code_offsets);
-+extern void emit_pd_mismatch_verified_tail_call_stub(Compile* C, CodeBuffer& cbuf, int arg_slots, int frame_size, CodeOffsets& code_offsets);
-
//------------------------------Output-----------------------------------------
// Convert Nodes to instruction bits and pass off to the VM
-@@ -529,7 +539,7 @@ void Compile::Shorten_branches(Label *la
+ void Compile::Output() {
+@@ -529,7 +536,7 @@ void Compile::Shorten_branches(Label *la
// Relocation records
reloc_size += 1; // Relo entry for exception handler
@@ -8012,7 +7774,7 @@ diff -r ce2272390558 src/share/vm/opto/o
// Adjust reloc_size to number of record of relocation info
// Min is 2 bytes, max is probably 6 or 8, with a tax up to 25% for
// a relocation index.
-@@ -1018,6 +1028,19 @@ void Compile::Fill_buffer() {
+@@ -1018,6 +1025,19 @@ void Compile::Fill_buffer() {
int stub_req = TraceJumps ? initial_stub_capacity * 10 : initial_stub_capacity;
int const_req = initial_const_capacity;
bool labels_not_set = true;
@@ -8032,11 +7794,11 @@ diff -r ce2272390558 src/share/vm/opto/o
int pad_req = NativeCall::instruction_size;
// The extra spacing after the code is necessary on some platforms.
-@@ -1067,13 +1090,17 @@ void Compile::Fill_buffer() {
+@@ -1067,13 +1087,17 @@ void Compile::Fill_buffer() {
// nmethod and CodeBuffer count stubs & constants as part of method's code.
int exception_handler_req = size_exception_handler();
int deopt_handler_req = size_deopt_handler();
-+ int tail_call_stubs_rq = 3*size_verified_tail_call_stub(arg_slots) +
++ int tail_call_stubs_rq = size_verified_tail_call_stub(arg_slots) +
+ size_verified_not_sib_tail_call_stub(arg_slots) +
+ size_tail_call_stub(arg_slots) +
+ size_not_sib_tail_call_stub(arg_slots);
@@ -8051,7 +7813,7 @@ diff -r ce2272390558 src/share/vm/opto/o
CodeBuffer* cb = code_buffer();
cb->initialize(total_req, locs_req);
-@@ -1417,6 +1444,14 @@ void Compile::Fill_buffer() {
+@@ -1417,6 +1441,12 @@ void Compile::Fill_buffer() {
_code_offsets.set_value(CodeOffsets::Exceptions, emit_exception_handler(*cb));
// Emit the deopt handler code.
_code_offsets.set_value(CodeOffsets::Deopt, emit_deopt_handler(*cb));
@@ -8061,14 +7823,12 @@ diff -r ce2272390558 src/share/vm/opto/o
+ emit_tail_call_stub(C, *cb, arg_slots, framesize, _code_offsets);
+ emit_verified_not_sib_tail_call_stub(*cb, arg_slots, _first_block_size, _code_offsets);
+ emit_not_sib_tail_call_stub(*cb, arg_slots, _first_block_size, _code_offsets);
-+ emit_pd_mismatch_verified_tail_call_stub(C, *cb, arg_slots, framesize, _code_offsets);
-+ emit_pd_mismatch_tail_call_stub(C, *cb, arg_slots, framesize, _code_offsets);
}
// One last check for failed CodeBuffer::expand:
-diff -r ce2272390558 src/share/vm/prims/jvmtiClassFileReconstituter.cpp
---- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/prims/jvmtiClassFileReconstituter.cpp
+--- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -642,7 +642,7 @@ void JvmtiClassFileReconstituter::copy_b
assert(len > 0, "length must be > 0");
@@ -8078,9 +7838,9 @@ diff -r ce2272390558 src/share/vm/prims/
if (len > 1) {
memcpy(p+1, bcp+1, len-1);
}
-diff -r ce2272390558 src/share/vm/prims/methodComparator.cpp
---- a/src/share/vm/prims/methodComparator.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/prims/methodComparator.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/prims/methodComparator.cpp
+--- a/src/share/vm/prims/methodComparator.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/prims/methodComparator.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -236,7 +236,7 @@ bool MethodComparator::args_same(Bytecod
case Bytecodes::_lload : // fall through
case Bytecodes::_lstore : // fall through
@@ -8102,9 +7862,9 @@ diff -r ce2272390558 src/share/vm/prims/
if (_s_old->get_index_big() != _s_new->get_index_big())
return false;
} else {
-diff -r ce2272390558 src/share/vm/runtime/deoptimization.cpp
---- a/src/share/vm/runtime/deoptimization.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/deoptimization.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/runtime/deoptimization.cpp
+--- a/src/share/vm/runtime/deoptimization.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/deoptimization.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -375,7 +375,7 @@ Deoptimization::UnrollBlock* Deoptimizat
tty->print_cr("Deoptimizing method containing inlining");
}
@@ -8165,7 +7925,7 @@ diff -r ce2272390558 src/share/vm/runtim
ScopeDesc* trap_scope = cvf->scope();
methodHandle trap_method = trap_scope->method();
int trap_bci = trap_scope->bci();
-@@ -1845,3 +1843,524 @@ const char* Deoptimization::format_trap_
+@@ -1845,3 +1843,510 @@ const char* Deoptimization::format_trap_
}
#endif // COMPILER2
@@ -8238,6 +7998,7 @@ diff -r ce2272390558 src/share/vm/runtim
+ JRT_BLOCK { //nice formatting
+ RegisterMap reg_map(_thread, true);
+ vframe * vf = _thread->last_java_vframe(®_map);
++
+ while ( vf != NULL ) {
+ if (vf->is_java_frame()) {
+ javaVFrame * jf = javaVFrame::cast(vf);
@@ -8246,10 +8007,7 @@ diff -r ce2272390558 src/share/vm/runtim
+ _is_top_of_stack_frame = false;
+ _callee_parameters = jf->method()->size_of_parameters();
+ } else {
-+ break;
-+ // assert(false, "not a java frame");
-+ // ShouldNotReachHere();
-+ // Should handle this more gracefully.
++ break; // Stop compression.
+ }
+ // Get parent.
+ vf = vf->sender();
@@ -8335,9 +8093,9 @@ diff -r ce2272390558 src/share/vm/runtim
+ return result;
+}
+
-+static StackValueCollection * top_compiled_frame_with_parms(javaVFrame * jframe) {
-+ assert(jframe->is_compiled_frame(), "Must be compiled");
-+ compiledVFrame * cvf = compiledVFrame::cast(jframe);
++static StackValueCollection * top_compiled_frame_with_parms(javaVFrame * frame) {
++ assert(frame->is_compiled_frame(), "Must be compiled");
++ compiledVFrame * cvf = compiledVFrame::cast(frame);
+ StackValueCollection * result = cvf->expressions();
+ SimpleScopeDesc ssd(cvf->code(), cvf->fr().pc());
+ Bytecode_invoke* call = Bytecode_invoke_at(ssd.method(), ssd.bci());
@@ -8348,16 +8106,6 @@ diff -r ce2272390558 src/share/vm/runtim
+ // Compute signature.
+ VMRegPair *_regs = SharedRuntime::find_callee_arguments(signature, is_static, &arg_size, sig_bt);
+ StackValue * sv = NULL;
-+ // A sibling tail call stores it's arguments in the caller's caller frame.
-+ frame fr = cvf->fr();
-+ // Get location of arguments.
-+ intptr_t* arg_pointer = NULL;
-+ if (NativeJump::is_jump_before(fr.pc()) &&
-+ is_sibling_tail_call_before(fr.pc())) {
-+ // Using opto frame.sender_sp() seems to return a wrong value.
-+ address sender_sp = ((address)fr.unextended_sp()) + (fr.frame_size()*VMRegImpl::stack_slot_size);
-+ arg_pointer = (intptr_t*)sender_sp;
-+ } else arg_pointer = (intptr_t*)fr.sp();
+ // Add parameters.
+ bool prev_reg = false;
+ bool prev_stack = false;
@@ -8367,7 +8115,7 @@ diff -r ce2272390558 src/share/vm/runtim
+ VMReg reg = _regs[i].first();
+ // Compute address on stack.
+ if (reg->is_stack()) {
-+ value_addr = (intptr_t*) (arg_pointer + reg->reg2stack());
++ value_addr = (intptr_t*) ((intptr_t*)cvf->fr().sp() + reg->reg2stack());
+ prev_reg = false;
+ prev_stack = true;
+ } else if( reg->is_reg()) {
@@ -8485,9 +8233,7 @@ diff -r ce2272390558 src/share/vm/runtim
+ //No safepoint starts in compress_frames function;
+ StackCompressor * compressor = new StackCompressor(thread);
+ vframeArray* array = compressor->compress_frames();
-+
+ if (TraceTailCalls) tty->print_cr("Compressing the stack");
-+
+ // Could not compress throw stackoverflow exception.
+ if (array == NULL) {
+ delete thread->deopt_mark();
@@ -8690,9 +8436,9 @@ diff -r ce2272390558 src/share/vm/runtim
+}
+JRT_END
+
-diff -r ce2272390558 src/share/vm/runtime/deoptimization.hpp
---- a/src/share/vm/runtime/deoptimization.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/deoptimization.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/runtime/deoptimization.hpp
+--- a/src/share/vm/runtime/deoptimization.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/deoptimization.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -78,7 +78,8 @@ class Deoptimization : AllStatic {
Unpack_deopt = 0, // normal deoptimization, use pc computed in unpack_vframe_on_stack
Unpack_exception = 1, // exception is pending
@@ -8758,9 +8504,9 @@ diff -r ce2272390558 src/share/vm/runtim
+
+};
+
-diff -r ce2272390558 src/share/vm/runtime/frame.cpp
---- a/src/share/vm/runtime/frame.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/frame.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/runtime/frame.cpp
+--- a/src/share/vm/runtime/frame.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/frame.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -326,7 +326,10 @@ frame frame::profile_find_Java_sender_fr
// Interpreter frames
@@ -8773,93 +8519,7 @@ diff -r ce2272390558 src/share/vm/runtim
void frame::interpreter_frame_set_locals(intptr_t* locs) {
assert(is_interpreted_frame(), "Not an interpreted frame");
*interpreter_frame_locals_addr() = locs;
-@@ -1084,7 +1087,7 @@ class CompiledArgumentOopFinder: public
- RegisterMap* _reg_map;
- int _arg_size;
- VMRegPair* _regs; // VMReg list of arguments
--
-+ bool _is_tailcall;
- void set(int size, BasicType type) {
- if (type == T_OBJECT || type == T_ARRAY) handle_oop_offset();
- _offset += size;
-@@ -1094,12 +1097,12 @@ class CompiledArgumentOopFinder: public
- // Extract low order register number from register array.
- // In LP64-land, the high-order bits are valid but unhelpful.
- VMReg reg = _regs[_offset].first();
-- oop *loc = _fr.oopmapreg_to_location(reg, _reg_map);
-+ oop *loc = _fr.oopmapreg_to_location(reg, _reg_map, _is_tailcall);
- _f->do_oop(loc);
- }
-
- public:
-- CompiledArgumentOopFinder(symbolHandle signature, bool is_static, OopClosure* f, frame fr, const RegisterMap* reg_map)
-+ CompiledArgumentOopFinder(symbolHandle signature, bool is_static, bool is_tailcall, OopClosure* f, frame fr, const RegisterMap* reg_map)
- : SignatureInfo(signature) {
-
- // initialize CompiledArgumentOopFinder
-@@ -1109,7 +1112,7 @@ class CompiledArgumentOopFinder: public
- _fr = fr;
- _reg_map = (RegisterMap*)reg_map;
- _arg_size = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1);
--
-+ _is_tailcall = is_tailcall;
- int arg_size;
- _regs = SharedRuntime::find_callee_arguments(signature(), is_static, &arg_size);
- assert(arg_size == _arg_size, "wrong arg size");
-@@ -1124,9 +1127,9 @@ class CompiledArgumentOopFinder: public
- }
- };
-
--void frame::oops_compiled_arguments_do(symbolHandle signature, bool is_static, const RegisterMap* reg_map, OopClosure* f) {
-+void frame::oops_compiled_arguments_do(symbolHandle signature, bool is_static, bool is_tailcall, const RegisterMap* reg_map, OopClosure* f) {
- ResourceMark rm;
-- CompiledArgumentOopFinder finder(signature, is_static, f, *this, reg_map);
-+ CompiledArgumentOopFinder finder(signature, is_static, is_tailcall, f, *this, reg_map);
- finder.oops_do();
- }
-
-@@ -1142,20 +1145,35 @@ oop frame::retrieve_receiver(RegisterMap
-
- // First consult the ADLC on where it puts parameter 0 for this signature.
- VMReg reg = SharedRuntime::name_for_receiver();
-- oop r = *caller.oopmapreg_to_location(reg, reg_map);
-+ oop r = *caller.oopmapreg_to_location(reg, reg_map, false);
- assert( Universe::heap()->is_in_or_null(r), "bad receiver" );
- return r;
- }
-
-
--oop* frame::oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const {
-+oop* frame::oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map, bool is_tailcall) const {
- if(reg->is_reg()) {
- // If it is passed in a register, it got spilled in the stub frame.
- return (oop *)reg_map->location(reg);
-- } else {
-- int sp_offset_in_bytes = reg->reg2stack() * VMRegImpl::stack_slot_size;
-- return (oop*)(((address)unextended_sp()) + sp_offset_in_bytes);
-+ } else if (is_tailcall) {
-+ // Sibling tail calls move their arguments eagerly. So we need to look in
-+ // sender frame for arguments.
-+ if (NativeJump::is_jump_before(pc()) &&
-+ is_sibling_tail_call_before(pc())) {
-+ int sp_offset_in_bytes = reg->reg2stack() * VMRegImpl::stack_slot_size;
-+ // Opto's frame.sender_sp() seems to return a wrong value.
-+ //address old_sp = ((address)unextended_sp()) + (frame_size()*VMRegImpl::stack_slot_size);
-+ RegisterMap map(reg_map);
-+ frame sender = this->sender(&map);
-+ int frame_size = sender.sp() - sp();
-+
-+ address old_sp = ((address)unextended_sp()) + (frame_size*VMRegImpl::stack_slot_size);
-+ return (oop*) (((address)old_sp) + sp_offset_in_bytes);
-+ }
- }
-+ // Regular location in outgoing argument area.
-+ int sp_offset_in_bytes = reg->reg2stack() * VMRegImpl::stack_slot_size;
-+ return (oop*)(((address)unextended_sp()) + sp_offset_in_bytes);
- }
-
- BasicLock* frame::compiled_synchronized_native_monitor(nmethod* nm) {
-@@ -1206,6 +1224,7 @@ void frame::oops_do_internal(OopClosure*
+@@ -1206,6 +1209,7 @@ void frame::oops_do_internal(OopClosure*
} else if (is_entry_frame()) { oops_entry_do (f, map);
} else if (CodeCache::contains(pc())) { oops_code_blob_do (f, map);
} else {
@@ -8867,9 +8527,9 @@ diff -r ce2272390558 src/share/vm/runtim
ShouldNotReachHere();
}
}
-diff -r ce2272390558 src/share/vm/runtime/frame.hpp
---- a/src/share/vm/runtime/frame.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/frame.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/runtime/frame.hpp
+--- a/src/share/vm/runtime/frame.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/frame.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -186,6 +186,7 @@ class frame VALUE_OBJ_CLASS_SPEC {
// Interpreter frames:
@@ -8888,23 +8548,10 @@ diff -r ce2272390558 src/share/vm/runtim
// byte code index
jint interpreter_frame_bci() const;
void interpreter_frame_set_bci(jint bci);
-@@ -368,10 +372,10 @@ class frame VALUE_OBJ_CLASS_SPEC {
- void print_on_error(outputStream* st, char* buf, int buflen, bool verbose = false) const;
-
- // Conversion from an VMReg to physical stack location
-- oop* oopmapreg_to_location(VMReg reg, const RegisterMap* regmap) const;
-+ oop* oopmapreg_to_location(VMReg reg, const RegisterMap* regmap, bool is_tailcall) const;
-
- // Oops-do's
-- void oops_compiled_arguments_do(symbolHandle signature, bool is_static, const RegisterMap* reg_map, OopClosure* f);
-+ void oops_compiled_arguments_do(symbolHandle signature, bool is_static, bool is_tailcall, const RegisterMap* reg_map, OopClosure* f);
- void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true);
-
- private:
-diff -r ce2272390558 src/share/vm/runtime/globals.hpp
---- a/src/share/vm/runtime/globals.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/globals.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -3267,6 +3267,15 @@ class CommandLineFlags {
+diff -r aa0c48844632 src/share/vm/runtime/globals.hpp
+--- a/src/share/vm/runtime/globals.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/globals.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -3302,6 +3302,15 @@ class CommandLineFlags {
"Skip assert() and verify() which page-in unwanted shared " \
"objects. ") \
\
@@ -8920,10 +8567,10 @@ diff -r ce2272390558 src/share/vm/runtim
product(bool, AnonymousClasses, false, \
"support sun.misc.Unsafe.defineAnonymousClass") \
\
-diff -r ce2272390558 src/share/vm/runtime/sharedRuntime.cpp
---- a/src/share/vm/runtime/sharedRuntime.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/sharedRuntime.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -463,6 +463,12 @@ address SharedRuntime::compute_compiled_
+diff -r aa0c48844632 src/share/vm/runtime/sharedRuntime.cpp
+--- a/src/share/vm/runtime/sharedRuntime.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/sharedRuntime.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -489,6 +489,12 @@ address SharedRuntime::compute_compiled_
return nm->instructions_begin() + t->pco();
}
@@ -8936,7 +8583,7 @@ diff -r ce2272390558 src/share/vm/runtim
JRT_ENTRY(void, SharedRuntime::throw_AbstractMethodError(JavaThread* thread))
// These errors occur only at call sites
throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_AbstractMethodError());
-@@ -499,6 +505,41 @@ JRT_ENTRY(void, SharedRuntime::throw_Sta
+@@ -525,6 +531,41 @@ JRT_ENTRY(void, SharedRuntime::throw_Sta
throw_and_post_jvmti_exception(thread, exception);
JRT_END
@@ -8978,7 +8625,7 @@ diff -r ce2272390558 src/share/vm/runtim
address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
address pc,
SharedRuntime::ImplicitExceptionKind exception_kind)
-@@ -513,7 +554,12 @@ address SharedRuntime::continuation_for_
+@@ -539,7 +580,12 @@ address SharedRuntime::continuation_for_
switch (exception_kind) {
case IMPLICIT_NULL: return Interpreter::throw_NullPointerException_entry();
case IMPLICIT_DIVIDE_BY_ZERO: return Interpreter::throw_ArithmeticException_entry();
@@ -8992,7 +8639,7 @@ diff -r ce2272390558 src/share/vm/runtim
default: ShouldNotReachHere();
}
#endif // !CC_INTERP
-@@ -527,6 +573,10 @@ address SharedRuntime::continuation_for_
+@@ -553,6 +599,10 @@ address SharedRuntime::continuation_for_
// For stack overflow in deoptimization blob, cleanup thread.
if (thread->deopt_mark() != NULL) {
Deoptimization::cleanup_deopt_info(thread, NULL);
@@ -9003,7 +8650,7 @@ diff -r ce2272390558 src/share/vm/runtim
}
return StubRoutines::throw_StackOverflowError_entry();
}
-@@ -783,9 +833,9 @@ Handle SharedRuntime::find_callee_info_h
+@@ -767,9 +817,9 @@ Handle SharedRuntime::find_callee_info_h
// Find caller and bci from vframe
methodHandle caller (THREAD, vfst.method());
int bci = vfst.bci();
@@ -9014,7 +8661,7 @@ diff -r ce2272390558 src/share/vm/runtim
bc = bytecode->adjusted_invoke_code();
int bytecode_index = bytecode->index();
-@@ -869,9 +919,11 @@ methodHandle SharedRuntime::find_callee_
+@@ -853,9 +903,11 @@ methodHandle SharedRuntime::find_callee_
// Resolves a call.
methodHandle SharedRuntime::resolve_helper(JavaThread *thread,
bool is_virtual,
@@ -9028,7 +8675,7 @@ diff -r ce2272390558 src/share/vm/runtim
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
int retry_count = 0;
while (!HAS_PENDING_EXCEPTION && callee_method->is_old() &&
-@@ -888,17 +940,47 @@ methodHandle SharedRuntime::resolve_help
+@@ -872,17 +924,48 @@ methodHandle SharedRuntime::resolve_help
guarantee((retry_count++ < 100),
"Could not resolve to latest version of redefined method");
// method is redefined in the middle of resolve so re-try.
@@ -9056,6 +8703,7 @@ diff -r ce2272390558 src/share/vm/runtim
+ methodHandle callee_method = call_info.selected_method();
+ KlassHandle callee_klass(callee_method->method_holder());
+ assert(callee_klass->oop_is_instance(), "callee should be instanceoop");
++
+ instanceKlassHandle callee_instance_klass(THREAD, callee_klass());
+ instanceKlassHandle caller_instance_klass(caller_klass_from_frame(thread, THREAD));
+
@@ -9078,7 +8726,7 @@ diff -r ce2272390558 src/share/vm/runtim
ResourceMark rm(thread);
RegisterMap cbl_map(thread, false);
-@@ -941,6 +1023,19 @@ methodHandle SharedRuntime::resolve_sub_
+@@ -925,6 +1008,19 @@ methodHandle SharedRuntime::resolve_sub_
}
#endif
@@ -9098,29 +8746,22 @@ diff -r ce2272390558 src/share/vm/runtim
// Compute entry points. This might require generation of C2I converter
// frames, so we cannot be holding any locks here. Furthermore, the
// computation of the entry points is independent of patching the call. We
-@@ -965,12 +1060,17 @@ methodHandle SharedRuntime::resolve_sub_
- assert(receiver.not_null(), "sanity check");
+@@ -950,11 +1046,11 @@ methodHandle SharedRuntime::resolve_sub_
bool static_bound = call_info.resolved_method()->can_be_statically_bound();
KlassHandle h_klass(THREAD, receiver->klass());
-+ // A call is a tail call iff
-+ // is_sibling_call && is_tail_call (pd_mismatch handled in
-+ // compute_monomorphic_entry) OR
-+ // !is_sibling_call && pd_match && is_tail_call (pd_mismatch ignored,
-+ // we handle mismatch here)
CompiledIC::compute_monomorphic_entry(callee_method, h_klass,
- is_optimized, static_bound, virtual_call_info,
- CHECK_(methodHandle()));
-+ is_optimized, static_bound, is_tail_call && (is_sibling_call || pd_match), is_sibling_call,
-+ pd_match==false, virtual_call_info, CHECK_(methodHandle()));
++ is_optimized, static_bound, is_tail_call && pd_match, is_sibling_call,
++ virtual_call_info, CHECK_(methodHandle()));
} else {
-- // static call
+ // static call
- CompiledStaticCall::compute_entry(callee_method, static_call_info);
-+ // Static call
-+ CompiledStaticCall::compute_entry(callee_method, static_call_info, is_tail_call && (is_sibling_call || pd_match), is_sibling_call, pd_match==false);
++ CompiledStaticCall::compute_entry(callee_method, static_call_info, is_tail_call && pd_match, is_sibling_call);
}
// grab lock, check for deoptimization and potentially patch caller
-@@ -989,13 +1089,23 @@ methodHandle SharedRuntime::resolve_sub_
+@@ -973,13 +1069,23 @@ methodHandle SharedRuntime::resolve_sub_
}
#endif
if (is_virtual) {
@@ -9148,7 +8789,7 @@ diff -r ce2272390558 src/share/vm/runtim
}
}
-@@ -1004,14 +1114,54 @@ methodHandle SharedRuntime::resolve_sub_
+@@ -988,14 +1094,54 @@ methodHandle SharedRuntime::resolve_sub_
return callee_method;
}
@@ -9174,8 +8815,8 @@ diff -r ce2272390558 src/share/vm/runtim
+ break;
+ case relocInfo::sibling_tail_call_type:
+ c2i_entry = callee->get_c2i_verified_tail_call_entry();
-+ verified_entry = callee->verified_tail_call_code_entry();
-+ break;
++ verified_entry = callee->verified_tail_call_code_entry();
++ break;
+ case relocInfo::not_sibling_tail_call_type:
+ c2i_entry = callee->get_c2i_verified_not_sibling_tail_call_entry();
+ verified_entry = callee->verified_not_sibling_tail_call_code_entry();
@@ -9204,7 +8845,7 @@ diff -r ce2272390558 src/share/vm/runtim
assert(!caller_frame.is_interpreted_frame() && !caller_frame.is_entry_frame(), "unexpected frame");
#endif /* ASSERT */
-@@ -1023,7 +1173,8 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
+@@ -1007,7 +1153,8 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
JRT_BLOCK_END
// return compiled code entry point after potential safepoints
assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
@@ -9214,7 +8855,7 @@ diff -r ce2272390558 src/share/vm/runtim
JRT_END
-@@ -1042,12 +1193,15 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
+@@ -1026,12 +1173,15 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
frame stub_frame = thread->last_frame();
assert(stub_frame.is_runtime_frame(), "sanity check");
frame caller_frame = stub_frame.sender(®_map);
@@ -9231,7 +8872,7 @@ diff -r ce2272390558 src/share/vm/runtim
}
// Must be compiled to compiled path which is safe to stackwalk
-@@ -1059,7 +1213,8 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
+@@ -1043,7 +1193,8 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
JRT_BLOCK_END
// return compiled code entry point after potential safepoints
assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
@@ -9241,7 +8882,7 @@ diff -r ce2272390558 src/share/vm/runtim
JRT_END
-@@ -1067,7 +1222,7 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
+@@ -1051,7 +1202,7 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_static_call_C(JavaThread *thread ))
methodHandle callee_method;
JRT_BLOCK
@@ -9250,7 +8891,7 @@ diff -r ce2272390558 src/share/vm/runtim
thread->set_vm_result(callee_method());
JRT_BLOCK_END
// return compiled code entry point after potential safepoints
-@@ -1075,12 +1230,34 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
+@@ -1059,12 +1210,34 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
return callee_method->verified_code_entry();
JRT_END
@@ -9286,7 +8927,7 @@ diff -r ce2272390558 src/share/vm/runtim
thread->set_vm_result(callee_method());
JRT_BLOCK_END
// return compiled code entry point after potential safepoints
-@@ -1088,13 +1265,60 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
+@@ -1072,13 +1245,60 @@ JRT_BLOCK_ENTRY(address, SharedRuntime::
return callee_method->verified_code_entry();
JRT_END
@@ -9348,7 +8989,7 @@ diff -r ce2272390558 src/share/vm/runtim
thread->set_vm_result(callee_method());
JRT_BLOCK_END
// return compiled code entry point after potential safepoints
-@@ -1178,7 +1402,8 @@ methodHandle SharedRuntime::handle_ic_mi
+@@ -1162,7 +1382,8 @@ methodHandle SharedRuntime::handle_ic_mi
CodeBlob* cb = caller_frame.cb();
if (cb->is_nmethod() && ((nmethod*)cb)->is_in_use()) {
// Not a non-entrant nmethod, so find inline_cache
@@ -9358,7 +8999,7 @@ diff -r ce2272390558 src/share/vm/runtim
bool should_be_mono = false;
if (inline_cache->is_optimized()) {
if (TraceCallFixup) {
-@@ -1216,15 +1441,27 @@ methodHandle SharedRuntime::handle_ic_mi
+@@ -1200,15 +1421,26 @@ methodHandle SharedRuntime::handle_ic_mi
// by using a new icBuffer.
CompiledICInfo info;
KlassHandle receiver_klass(THREAD, receiver()->klass());
@@ -9370,7 +9011,6 @@ diff -r ce2272390558 src/share/vm/runtim
false,
+ is_tail_call,
+ is_sibling,
-+ false,
info, CHECK_(methodHandle()));
- inline_cache->set_to_monomorphic(info);
+ inline_cache->set_to_monomorphic(info, is_tail_call);
@@ -9388,7 +9028,7 @@ diff -r ce2272390558 src/share/vm/runtim
} else {
// Either clean or megamorphic
}
-@@ -1283,11 +1520,15 @@ methodHandle SharedRuntime::reresolve_ca
+@@ -1267,11 +1499,15 @@ methodHandle SharedRuntime::reresolve_ca
if (NativeCall::is_call_before(pc)) {
NativeCall *ncall = nativeCall_before(pc);
call_addr = ncall->instruction_address();
@@ -9404,7 +9044,7 @@ diff -r ce2272390558 src/share/vm/runtim
nmethod* caller_nm = CodeCache::find_nmethod(pc);
// Make sure nmethod doesn't get deoptimized and removed until
// this is done with it.
-@@ -1301,10 +1542,12 @@ methodHandle SharedRuntime::reresolve_ca
+@@ -1285,10 +1521,12 @@ methodHandle SharedRuntime::reresolve_ca
assert(iter.addr() == call_addr, "must find call");
if (iter.type() == relocInfo::static_call_type) {
is_static_call = true;
@@ -9417,7 +9057,7 @@ diff -r ce2272390558 src/share/vm/runtim
}
} else {
assert(!UseInlineCaches, "relocation info. must exist for this address");
-@@ -1324,11 +1567,11 @@ methodHandle SharedRuntime::reresolve_ca
+@@ -1308,11 +1546,11 @@ methodHandle SharedRuntime::reresolve_ca
//
if (caller_nm->is_in_use()) {
if (is_static_call) {
@@ -9431,7 +9071,7 @@ diff -r ce2272390558 src/share/vm/runtim
inline_cache->set_to_clean();
}
}
-@@ -1363,6 +1606,8 @@ IRT_LEAF(void, SharedRuntime::fixup_call
+@@ -1347,6 +1585,8 @@ IRT_LEAF(void, SharedRuntime::fixup_call
methodOop moop(method);
address entry_point = moop->from_compiled_entry();
@@ -9440,7 +9080,7 @@ diff -r ce2272390558 src/share/vm/runtim
// It's possible that deoptimization can occur at a call site which hasn't
// been resolved yet, in which case this function will be called from
-@@ -1376,7 +1621,9 @@ IRT_LEAF(void, SharedRuntime::fixup_call
+@@ -1360,7 +1600,9 @@ IRT_LEAF(void, SharedRuntime::fixup_call
//
CodeBlob* cb = CodeCache::find_blob(caller_pc);
@@ -9451,7 +9091,7 @@ diff -r ce2272390558 src/share/vm/runtim
return;
}
-@@ -1392,11 +1639,19 @@ IRT_LEAF(void, SharedRuntime::fixup_call
+@@ -1376,11 +1618,19 @@ IRT_LEAF(void, SharedRuntime::fixup_call
if (moop->code() == NULL) return;
if (((nmethod*)cb)->is_in_use()) {
@@ -9474,7 +9114,7 @@ diff -r ce2272390558 src/share/vm/runtim
//
// bug 6281185. We might get here after resolving a call site to a vanilla
// virtual call. Because the resolvee uses the verified entry it may then
-@@ -1416,8 +1671,38 @@ IRT_LEAF(void, SharedRuntime::fixup_call
+@@ -1400,8 +1650,38 @@ IRT_LEAF(void, SharedRuntime::fixup_call
typ != relocInfo::static_stub_type) {
return;
}
@@ -9514,7 +9154,7 @@ diff -r ce2272390558 src/share/vm/runtim
CodeBlob* callee = CodeCache::find_blob(destination);
// callee == cb seems weird. It means calling interpreter thru stub.
if (callee == cb || callee->is_adapter_blob()) {
-@@ -1425,14 +1710,16 @@ IRT_LEAF(void, SharedRuntime::fixup_call
+@@ -1409,14 +1689,16 @@ IRT_LEAF(void, SharedRuntime::fixup_call
if (TraceCallFixup) {
tty->print("fixup callsite at " INTPTR_FORMAT " to compiled code for", caller_pc);
moop->print_short_name(tty);
@@ -9534,7 +9174,7 @@ diff -r ce2272390558 src/share/vm/runtim
}
// assert is too strong could also be resolve destinations.
// assert(InlineCacheBuffer::contains(destination) || VtableStubs::contains(destination), "must be");
-@@ -1441,7 +1728,7 @@ IRT_LEAF(void, SharedRuntime::fixup_call
+@@ -1425,7 +1707,7 @@ IRT_LEAF(void, SharedRuntime::fixup_call
if (TraceCallFixup) {
tty->print("already patched callsite at " INTPTR_FORMAT " to compiled code for", caller_pc);
moop->print_short_name(tty);
@@ -9543,17 +9183,16 @@ diff -r ce2272390558 src/share/vm/runtim
}
}
}
-@@ -1746,7 +2033,8 @@ void AdapterHandlerLibrary::initialize()
+@@ -1801,7 +2083,7 @@ void AdapterHandlerLibrary::initialize()
_fingerprints->append(0/*the never-allowed 0 fingerprint*/);
assert(_handlers->length() == AbstractMethodHandler, "in wrong slot");
_handlers->append(new AdapterHandlerEntry(StubRoutines::throw_AbstractMethodError_entry(),
- wrong_method, wrong_method));
-+ wrong_method, wrong_method, wrong_method, wrong_method, wrong_method,
-+ wrong_method, wrong_method, wrong_method, wrong_method));
++ wrong_method, wrong_method, wrong_method, wrong_method, wrong_method, wrong_method, wrong_method));
}
int AdapterHandlerLibrary::get_create_adapter_index(methodHandle method) {
-@@ -1903,6 +2191,13 @@ void AdapterHandlerEntry::relocate(addre
+@@ -1963,6 +2245,11 @@ void AdapterHandlerEntry::relocate(addre
_i2c_entry += delta;
_c2i_entry += delta;
_c2i_unverified_entry += delta;
@@ -9562,12 +9201,10 @@ diff -r ce2272390558 src/share/vm/runtim
+ _c2i_entry_skip_fixup += delta;
+ _c2i_verified_not_sibling_tail_call_entry += delta;
+ _c2i_unverified_not_sibling_tail_call_entry += delta;
-+ _c2i_pd_check_failed_unverified_entry += delta;
-+ _c2i_pd_check_failed_entry += delta;
}
// Create a native wrapper for this native method. The wrapper converts the
-@@ -2071,7 +2366,7 @@ VMReg SharedRuntime::name_for_receiver()
+@@ -2135,7 +2422,7 @@ VMReg SharedRuntime::name_for_receiver()
return regs.first();
}
@@ -9576,7 +9213,7 @@ diff -r ce2272390558 src/share/vm/runtim
// This method is returning a data structure allocating as a
// ResourceObject, so do not put any ResourceMarks in here.
char *s = sig->as_C_string();
-@@ -2080,7 +2375,9 @@ VMRegPair *SharedRuntime::find_callee_ar
+@@ -2144,7 +2431,9 @@ VMRegPair *SharedRuntime::find_callee_ar
char *t = s+len;
while( *(--t) != ')' ) ; // Find close paren
@@ -9587,9 +9224,9 @@ diff -r ce2272390558 src/share/vm/runtim
VMRegPair *regs = NEW_RESOURCE_ARRAY( VMRegPair, 256 );
int cnt = 0;
if (!is_static) {
-diff -r ce2272390558 src/share/vm/runtime/sharedRuntime.hpp
---- a/src/share/vm/runtime/sharedRuntime.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/sharedRuntime.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/runtime/sharedRuntime.hpp
+--- a/src/share/vm/runtime/sharedRuntime.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/sharedRuntime.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -33,9 +33,16 @@ class vframeStream;
class SharedRuntime: AllStatic {
@@ -9675,7 +9312,7 @@ diff -r ce2272390558 src/share/vm/runtim
static SafepointBlob* polling_page_return_handler_blob() { return _polling_page_return_handler_blob; }
static SafepointBlob* polling_page_safepoint_handler_blob() { return _polling_page_safepoint_handler_blob; }
-@@ -230,7 +272,10 @@ class SharedRuntime: AllStatic {
+@@ -253,7 +295,10 @@ class SharedRuntime: AllStatic {
// compiled code.
static methodHandle resolve_helper(JavaThread *thread,
bool is_virtual,
@@ -9687,7 +9324,7 @@ diff -r ce2272390558 src/share/vm/runtim
static void generate_stubs(void);
-@@ -334,7 +379,9 @@ class SharedRuntime: AllStatic {
+@@ -357,7 +402,9 @@ class SharedRuntime: AllStatic {
// Convert a sig into a calling convention register layout
// and find interesting things about it.
@@ -9698,7 +9335,7 @@ diff -r ce2272390558 src/share/vm/runtim
static VMReg name_for_receiver();
// "Top of Stack" slots that may be unused by the calling convention but must
-@@ -384,8 +431,14 @@ class SharedRuntime: AllStatic {
+@@ -407,8 +454,14 @@ class SharedRuntime: AllStatic {
// Resolving of calls
static address resolve_static_call_C (JavaThread *thread);
@@ -9713,25 +9350,23 @@ diff -r ce2272390558 src/share/vm/runtim
// arraycopy, the non-leaf version. (See StubRoutines for all the leaf calls.)
static void slow_arraycopy_C(oopDesc* src, jint src_pos,
-@@ -510,21 +563,41 @@ class AdapterHandlerEntry : public CHeap
+@@ -533,21 +586,36 @@ class AdapterHandlerEntry : public CHeap
address _i2c_entry;
address _c2i_entry;
address _c2i_unverified_entry;
--
+ address _c2i_verified_tail_call_entry;
+ address _c2i_unverified_tail_call_entry;
+ address _c2i_entry_skip_fixup;
+ address _c2i_verified_not_sibling_tail_call_entry;
+ address _c2i_unverified_not_sibling_tail_call_entry;
-+ address _c2i_pd_check_failed_entry;
-+ address _c2i_pd_check_failed_unverified_entry;
+
public:
// The name we give all buffer blobs
static const char* name;
- AdapterHandlerEntry(address i2c_entry, address c2i_entry, address c2i_unverified_entry):
-+ AdapterHandlerEntry(address i2c_entry, address c2i_entry, address c2i_unverified_entry, address c2i_verified_tail_call_entry, address c2i_unverified_tail_call_entry, address c2i_entry_skip_fixup, address c2i_verified_not_sibling_tail_call_entry, address c2i_unverified_not_sibling_tail_call_entry, address c2i_pd_check_failed_entry, address c2i_pd_check_failed_unverified_entry):
++ AdapterHandlerEntry(address i2c_entry, address c2i_entry, address c2i_unverified_entry, address c2i_verified_tail_call_entry, address c2i_unverified_tail_call_entry, address c2i_entry_skip_fixup, address c2i_verified_not_sibling_tail_call_entry, address c2i_unverified_not_sibling_tail_call_entry):
_i2c_entry(i2c_entry),
_c2i_entry(c2i_entry),
- _c2i_unverified_entry(c2i_unverified_entry) {
@@ -9740,9 +9375,7 @@ diff -r ce2272390558 src/share/vm/runtim
+ _c2i_unverified_tail_call_entry(c2i_unverified_tail_call_entry),
+ _c2i_entry_skip_fixup(c2i_entry_skip_fixup),
+ _c2i_verified_not_sibling_tail_call_entry(c2i_verified_not_sibling_tail_call_entry),
-+ _c2i_unverified_not_sibling_tail_call_entry(c2i_unverified_not_sibling_tail_call_entry),
-+ _c2i_pd_check_failed_entry(c2i_pd_check_failed_entry),
-+ _c2i_pd_check_failed_unverified_entry(c2i_pd_check_failed_unverified_entry){
++ _c2i_unverified_not_sibling_tail_call_entry(c2i_unverified_not_sibling_tail_call_entry) {
}
address get_i2c_entry() { return _i2c_entry; }
@@ -9752,15 +9385,13 @@ diff -r ce2272390558 src/share/vm/runtim
+ address get_c2i_unverified_tail_call_entry() { return _c2i_unverified_tail_call_entry; }
+ address get_c2i_entry_skip_fixup() { return _c2i_entry_skip_fixup; }
+ address get_c2i_verified_not_sibling_tail_call_entry() { return _c2i_verified_not_sibling_tail_call_entry; }
-+ address get_pd_check_failed_entry() { return _c2i_pd_check_failed_entry; }
-+ address get_pd_check_failed_unverified_entry() { return _c2i_pd_check_failed_unverified_entry; }
+ address get_c2i_unverified_not_sibling_tail_call_entry() { return _c2i_unverified_not_sibling_tail_call_entry; }
void relocate(address new_base);
#ifndef PRODUCT
-diff -r ce2272390558 src/share/vm/runtime/stubRoutines.cpp
---- a/src/share/vm/runtime/stubRoutines.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/stubRoutines.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/runtime/stubRoutines.cpp
+--- a/src/share/vm/runtime/stubRoutines.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/stubRoutines.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -45,7 +45,9 @@ address StubRoutines::_throw_NullPointer
address StubRoutines::_throw_NullPointerException_entry = NULL;
address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
@@ -9771,9 +9402,9 @@ diff -r ce2272390558 src/share/vm/runtim
jint StubRoutines::_verify_oop_count = 0;
address StubRoutines::_verify_oop_subroutine_entry = NULL;
address StubRoutines::_atomic_xchg_entry = NULL;
-diff -r ce2272390558 src/share/vm/runtime/stubRoutines.hpp
---- a/src/share/vm/runtime/stubRoutines.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/stubRoutines.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/runtime/stubRoutines.hpp
+--- a/src/share/vm/runtime/stubRoutines.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/stubRoutines.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -89,7 +89,9 @@ class StubRoutines: AllStatic {
static address _throw_NullPointerException_entry;
static address _throw_NullPointerException_at_call_entry;
@@ -9794,10 +9425,10 @@ diff -r ce2272390558 src/share/vm/runtim
// Exceptions during unsafe access - should throw Java exception rather
// than crash.
static address handler_for_unsafe_access() { return _handler_for_unsafe_access_entry; }
-diff -r ce2272390558 src/share/vm/runtime/thread.cpp
---- a/src/share/vm/runtime/thread.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/thread.cpp Mon Mar 16 11:42:47 2009 +0100
-@@ -1180,6 +1180,7 @@ void JavaThread::initialize() {
+diff -r aa0c48844632 src/share/vm/runtime/thread.cpp
+--- a/src/share/vm/runtime/thread.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/thread.cpp Thu Jun 04 10:20:29 2009 +0200
+@@ -1165,6 +1165,7 @@ void JavaThread::initialize() {
_blocked_on_compilation = false;
_jni_active_critical = 0;
_do_not_unlock_if_synchronized = false;
@@ -9805,10 +9436,10 @@ diff -r ce2272390558 src/share/vm/runtim
_cached_monitor_info = NULL;
_parker = Parker::Allocate(this) ;
-diff -r ce2272390558 src/share/vm/runtime/thread.hpp
---- a/src/share/vm/runtime/thread.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/thread.hpp Mon Mar 16 11:42:47 2009 +0100
-@@ -739,6 +739,9 @@ class JavaThread: public Thread {
+diff -r aa0c48844632 src/share/vm/runtime/thread.hpp
+--- a/src/share/vm/runtime/thread.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/thread.hpp Thu Jun 04 10:20:29 2009 +0200
+@@ -727,6 +727,9 @@ class JavaThread: public Thread {
// is shortly thereafter set false
volatile bool _is_attaching;
@@ -9818,7 +9449,7 @@ diff -r ce2272390558 src/share/vm/runtim
public:
// State of the stack guard pages for this thread.
enum StackGuardState {
-@@ -758,6 +761,9 @@ class JavaThread: public Thread {
+@@ -746,6 +749,9 @@ class JavaThread: public Thread {
volatile address _exception_pc; // PC where exception happened
volatile address _exception_handler_pc; // PC for handler of exception
volatile int _exception_stack_size; // Size of frame where exception happened
@@ -9828,7 +9459,7 @@ diff -r ce2272390558 src/share/vm/runtim
// support for compilation
bool _is_compiling; // is true if a compilation is active inthis thread (one compilation per thread possible)
-@@ -1105,6 +1111,10 @@ class JavaThread: public Thread {
+@@ -1093,6 +1099,10 @@ class JavaThread: public Thread {
void set_exception_handler_pc(address a) { _exception_handler_pc = a; }
void set_exception_stack_size(int size) { _exception_stack_size = size; }
@@ -9839,7 +9470,7 @@ diff -r ce2272390558 src/share/vm/runtim
// Stack overflow support
inline size_t stack_available(address cur_sp);
address stack_yellow_zone_base()
-@@ -1179,8 +1189,11 @@ class JavaThread: public Thread {
+@@ -1167,8 +1177,11 @@ class JavaThread: public Thread {
static ByteSize exception_stack_size_offset() { return byte_offset_of(JavaThread, _exception_stack_size); }
static ByteSize stack_guard_state_offset() { return byte_offset_of(JavaThread, _stack_guard_state ); }
static ByteSize suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags ); }
@@ -9851,9 +9482,9 @@ diff -r ce2272390558 src/share/vm/runtim
#ifndef SERIALGC
static ByteSize satb_mark_queue_offset() { return byte_offset_of(JavaThread, _satb_mark_queue); }
-diff -r ce2272390558 src/share/vm/runtime/vframeArray.cpp
---- a/src/share/vm/runtime/vframeArray.cpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/vframeArray.cpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/runtime/vframeArray.cpp
+--- a/src/share/vm/runtime/vframeArray.cpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/vframeArray.cpp Thu Jun 04 10:20:29 2009 +0200
@@ -181,6 +181,10 @@ void vframeArrayElement::unpack_on_stack
JvmtiThreadState *state = thread->jvmti_thread_state();
if (JvmtiExport::can_pop_frame() &&
@@ -10098,9 +9729,9 @@ diff -r ce2272390558 src/share/vm/runtim
}
void vframeArray::print_value_on(outputStream* st) const {
-diff -r ce2272390558 src/share/vm/runtime/vframeArray.hpp
---- a/src/share/vm/runtime/vframeArray.hpp Mon Mar 09 13:34:00 2009 -0700
-+++ b/src/share/vm/runtime/vframeArray.hpp Mon Mar 16 11:42:47 2009 +0100
+diff -r aa0c48844632 src/share/vm/runtime/vframeArray.hpp
+--- a/src/share/vm/runtime/vframeArray.hpp Thu May 14 10:57:58 2009 -0700
++++ b/src/share/vm/runtime/vframeArray.hpp Thu Jun 04 10:20:29 2009 +0200
@@ -33,6 +33,47 @@ class MonitorStackClosure;
class MonitorStackClosure;
class MonitorArrayElement;
@@ -10168,9 +9799,9 @@ diff -r ce2272390558 src/share/vm/runtim
vframeArrayElement* element(int index) { assert(is_within_bounds(index), "Bad index"); return &_elements[index]; }
-diff -r ce2272390558 test/tailcalltests/CompilerTestDouble.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestDouble.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestDouble.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestDouble.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,56 @@
+ /* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestDouble
@@ -10228,9 +9859,9 @@ diff -r ce2272390558 test/tailcalltests/
+ if (v!=vtailcall) System.exit(1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMegamorphic.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMegamorphic.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMegamorphic.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMegamorphic.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,90 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestMegamorphic
@@ -10322,9 +9953,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMegamorphicC2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMegamorphicC2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMegamorphicC2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMegamorphicC2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,91 @@
+/* @test
+ * @run main/othervm -XX:CompileOnly=.tailCallee -XX:+TailCalls -Xcomp CompilerTestMegamorphicC2I
@@ -10417,9 +10048,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMegamorphicInterface.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMegamorphicInterface.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMegamorphicInterface.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMegamorphicInterface.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,95 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestMegamorphicInterface
@@ -10516,9 +10147,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMegamorphicInterfaceC2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMegamorphicInterfaceC2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMegamorphicInterfaceC2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMegamorphicInterfaceC2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,95 @@
+/* @test
+ * @run main/othervm -XX:CompileOnly=.tailCaller -XX:+TailCalls -Xcomp CompilerTestMegamorphicInterfaceC2I
@@ -10615,9 +10246,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMegamorphicInterfaceNotSib.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMegamorphicInterfaceNotSib.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMegamorphicInterfaceNotSib.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMegamorphicInterfaceNotSib.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,95 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestMegamorphicInterfaceNotSib
@@ -10714,9 +10345,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMegamorphicInterfaceNotSibC2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMegamorphicInterfaceNotSibC2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMegamorphicInterfaceNotSibC2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMegamorphicInterfaceNotSibC2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,95 @@
+/* @test
+ * @run main/othervm -XX:CompileOnly=.tailCaller -XX:+TailCalls -Xcomp CompilerTestMegamorphicInterfaceNotSibC2I
@@ -10813,9 +10444,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMegamorphicNotSib.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMegamorphicNotSib.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMegamorphicNotSib.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMegamorphicNotSib.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,93 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestMegamorphicNotSib
@@ -10910,9 +10541,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMegamorphicNotSibC2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMegamorphicNotSibC2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMegamorphicNotSibC2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMegamorphicNotSibC2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,93 @@
+/* @test
+ * @run main/othervm -XX:CompileOnly=.tailCallee -XX:+TailCalls -Xcomp CompilerTestMegamorphicNotSibC2I
@@ -11007,9 +10638,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMonomorphic1.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMonomorphic1.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMonomorphic1.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMonomorphic1.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,54 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestMonomorphic1
@@ -11065,9 +10696,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMonomorphic2.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMonomorphic2.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMonomorphic2.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMonomorphic2.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,66 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestMonomorphic2
@@ -11135,9 +10766,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMonomorphic2C2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMonomorphic2C2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMonomorphic2C2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMonomorphic2C2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,66 @@
+/* @test
+ * @run main/othervm -XX:CompileOnly=.tailCaller -XX:+TailCalls -Xcomp CompilerTestMonomorphic2C2I
@@ -11205,9 +10836,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMonomorphic2NotSib.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMonomorphic2NotSib.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMonomorphic2NotSib.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMonomorphic2NotSib.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,66 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestMonomorphic2NotSib
@@ -11275,9 +10906,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestMonomorphic2NotSibC2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestMonomorphic2NotSibC2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestMonomorphic2NotSibC2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestMonomorphic2NotSibC2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,66 @@
+/* @test
+ * @run main/othervm -XX:CompileOnly=.tailCallee -XX:+TailCalls -Xcomp CompilerTestMonomorphic2NotSibC2I
@@ -11345,9 +10976,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestStatic.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestStatic.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestStatic.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestStatic.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,43 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestStatic
@@ -11392,9 +11023,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestStaticC2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestStaticC2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestStaticC2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestStaticC2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,44 @@
+
+/* @test
@@ -11440,9 +11071,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestStaticNotSib.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestStaticNotSib.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestStaticNotSib.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestStaticNotSib.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,44 @@
+
+/* @test
@@ -11488,9 +11119,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestStaticNotSibC2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestStaticNotSibC2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestStaticNotSibC2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestStaticNotSibC2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,44 @@
+
+/* @test
@@ -11536,9 +11167,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestVirtualOpt.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestVirtualOpt.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestVirtualOpt.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestVirtualOpt.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,48 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestVirtualOpt
@@ -11588,9 +11219,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestVirtualOptC2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestVirtualOptC2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestVirtualOptC2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestVirtualOptC2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,48 @@
+/* @test
+ * @run main/othervm -XX:CompileOnly=.tailCallee -XX:+TailCalls -Xcomp CompilerTestVirtualOptC2I
@@ -11640,9 +11271,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestVirtualOptNotSib.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestVirtualOptNotSib.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestVirtualOptNotSib.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestVirtualOptNotSib.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,49 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerTestVirtualOptNotSib
@@ -11693,9 +11324,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerTestVirtualOptNotSibC2I.java
+diff -r aa0c48844632 test/tailcalltests/CompilerTestVirtualOptNotSibC2I.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerTestVirtualOptNotSibC2I.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerTestVirtualOptNotSibC2I.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,49 @@
+/* @test
+ * @run main/othervm -XX:CompileOnly=.tailCaller -XX:+TailCalls -Xcomp CompilerTestVirtualOptNotSibC2I
@@ -11746,9 +11377,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/CompilerVoidTest.java
+diff -r aa0c48844632 test/tailcalltests/CompilerVoidTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/CompilerVoidTest.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/CompilerVoidTest.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,25 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp CompilerVoidTest
@@ -11775,9 +11406,9 @@ diff -r ce2272390558 test/tailcalltests/
+ System.out.println("Success");
+ }
+}
-diff -r ce2272390558 test/tailcalltests/ContainsTailcall.java
+diff -r aa0c48844632 test/tailcalltests/ContainsTailcall.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/ContainsTailcall.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/ContainsTailcall.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,15 @@
+/* @test
+ * @run main/othervm/fail -Xint ContainsTailcall
@@ -11794,9 +11425,9 @@ diff -r ce2272390558 test/tailcalltests/
+ int a = tailcall(10);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/ExceptionTest1.java
+diff -r aa0c48844632 test/tailcalltests/ExceptionTest1.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/ExceptionTest1.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/ExceptionTest1.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,23 @@
+/* @test
+ * @run main/othervm/fail -Xint ExceptionTest1
@@ -11821,9 +11452,9 @@ diff -r ce2272390558 test/tailcalltests/
+ System.exit(1); // Should not get here.
+ }
+}
-diff -r ce2272390558 test/tailcalltests/InterpreterTest1.java
+diff -r aa0c48844632 test/tailcalltests/InterpreterTest1.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/InterpreterTest1.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/InterpreterTest1.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,27 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xint InterpreterTest1
@@ -11852,9 +11483,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/InterpreterTest2.java
+diff -r aa0c48844632 test/tailcalltests/InterpreterTest2.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/InterpreterTest2.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/InterpreterTest2.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,26 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xint InterpreterTest2
@@ -11882,9 +11513,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/InterpreterTest3.java
+diff -r aa0c48844632 test/tailcalltests/InterpreterTest3.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/InterpreterTest3.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/InterpreterTest3.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,33 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xint InterpreterTest3
@@ -11919,9 +11550,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/InterpreterTestArgumentMove.java
+diff -r aa0c48844632 test/tailcalltests/InterpreterTestArgumentMove.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/InterpreterTestArgumentMove.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/InterpreterTestArgumentMove.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,39 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xint InterpreterTestArgumentMove
@@ -11962,9 +11593,9 @@ diff -r ce2272390558 test/tailcalltests/
+ assertEqual(a, 1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/InterpreterTestInvokeInterface.java
+diff -r aa0c48844632 test/tailcalltests/InterpreterTestInvokeInterface.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/InterpreterTestInvokeInterface.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/InterpreterTestInvokeInterface.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,32 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xint InterpreterTestInvokeInterface
@@ -11998,9 +11629,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/InterpreterTestInvokeSpecial.java
+diff -r aa0c48844632 test/tailcalltests/InterpreterTestInvokeSpecial.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/InterpreterTestInvokeSpecial.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/InterpreterTestInvokeSpecial.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,35 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xint InterpreterTestInvokeSpecial
@@ -12037,9 +11668,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/InterpreterTestInvokeVirtual.java
+diff -r aa0c48844632 test/tailcalltests/InterpreterTestInvokeVirtual.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/InterpreterTestInvokeVirtual.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/InterpreterTestInvokeVirtual.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,28 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xint InterpreterTestInvokeVirtual
@@ -12069,9 +11700,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/InterpreterTestObjects1.java
+diff -r aa0c48844632 test/tailcalltests/InterpreterTestObjects1.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/InterpreterTestObjects1.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/InterpreterTestObjects1.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,31 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xint InterpreterTestObjects1
@@ -12104,9 +11735,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/InterpreterTestObjects2.java
+diff -r aa0c48844632 test/tailcalltests/InterpreterTestObjects2.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/InterpreterTestObjects2.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/InterpreterTestObjects2.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,33 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xint InterpreterTestObjects2
@@ -12141,9 +11772,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/SynchronizedTest1.java
+diff -r aa0c48844632 test/tailcalltests/SynchronizedTest1.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/SynchronizedTest1.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/SynchronizedTest1.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,16 @@
+/* @test
+ * @run main/othervm/fail -Xint SynchronizedTest1
@@ -12161,9 +11792,9 @@ diff -r ce2272390558 test/tailcalltests/
+ System.exit(1); // Should not get here.
+ }
+}
-diff -r ce2272390558 test/tailcalltests/SynchronizedTest2.java
+diff -r aa0c48844632 test/tailcalltests/SynchronizedTest2.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/SynchronizedTest2.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/SynchronizedTest2.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,20 @@
+/* @test
+ * @run main/othervm/fail -Xint SynchronizedTest2
@@ -12185,9 +11816,9 @@ diff -r ce2272390558 test/tailcalltests/
+ System.exit(1); // Should not get here.
+ }
+}
-diff -r ce2272390558 test/tailcalltests/TEST.ROOT
+diff -r aa0c48844632 test/tailcalltests/TEST.ROOT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/TEST.ROOT Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/TEST.ROOT Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,31 @@
+#
+# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
@@ -12220,9 +11851,9 @@ diff -r ce2272390558 test/tailcalltests/
+
+# The list of keywords supported in this test suite
+keys=cte_test
-diff -r ce2272390558 test/tailcalltests/fold_unfold/AppendLizt.java
+diff -r aa0c48844632 test/tailcalltests/fold_unfold/AppendLizt.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/fold_unfold/AppendLizt.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/fold_unfold/AppendLizt.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,33 @@
+public class AppendLizt<T> extends Lizt<T> {
+ private Lizt<T> front;
@@ -12257,17 +11888,17 @@ diff -r ce2272390558 test/tailcalltests/
+ return goto back.accumulateLength(len);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/fold_unfold/BinaryFunction.java
+diff -r aa0c48844632 test/tailcalltests/fold_unfold/BinaryFunction.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/fold_unfold/BinaryFunction.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/fold_unfold/BinaryFunction.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,3 @@
+interface BinaryFunction <F1,F2,T> {
+ T apply(F1 e1, F2 e2);
+}
\ No newline at end of file
-diff -r ce2272390558 test/tailcalltests/fold_unfold/Conz.java
+diff -r aa0c48844632 test/tailcalltests/fold_unfold/Conz.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/fold_unfold/Conz.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/fold_unfold/Conz.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,27 @@
+public class Conz<T> extends Lizt<T> {
+
@@ -12297,17 +11928,17 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+}
\ No newline at end of file
-diff -r ce2272390558 test/tailcalltests/fold_unfold/Function.java
+diff -r aa0c48844632 test/tailcalltests/fold_unfold/Function.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/fold_unfold/Function.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/fold_unfold/Function.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,3 @@
+interface Function <F,T> {
+ T apply(F e);
+}
\ No newline at end of file
-diff -r ce2272390558 test/tailcalltests/fold_unfold/Lizt.java
+diff -r aa0c48844632 test/tailcalltests/fold_unfold/Lizt.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/fold_unfold/Lizt.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/fold_unfold/Lizt.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,110 @@
+/* @test
+ * @run main/othervm -XX:+TailCalls -Xcomp Lizt
@@ -12419,9 +12050,9 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/fold_unfold/Nil.java
+diff -r aa0c48844632 test/tailcalltests/fold_unfold/Nil.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/fold_unfold/Nil.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/fold_unfold/Nil.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,21 @@
+public class Nil<T> extends Lizt<T> {
+
@@ -12445,17 +12076,17 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+}
\ No newline at end of file
-diff -r ce2272390558 test/tailcalltests/fold_unfold/Predicate.java
+diff -r aa0c48844632 test/tailcalltests/fold_unfold/Predicate.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/fold_unfold/Predicate.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/fold_unfold/Predicate.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,3 @@
+interface Predicate<T> {
+ boolean apply(T e);
+}
\ No newline at end of file
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/InterpreterInterface.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/InterpreterInterface.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/InterpreterInterface.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/InterpreterInterface.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,26 @@
+/* @test
+ * @library Test2.jar
@@ -12483,9 +12114,9 @@ diff -r ce2272390558 test/tailcalltests/
+ System.exit(1); // Failure.
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/InterpreterStatic.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/InterpreterStatic.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/InterpreterStatic.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/InterpreterStatic.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,25 @@
+/* @test
+ * @library Test2.jar
@@ -12512,9 +12143,9 @@ diff -r ce2272390558 test/tailcalltests/
+ System.exit(1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/InterpreterVirtual.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/InterpreterVirtual.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/InterpreterVirtual.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/InterpreterVirtual.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,25 @@
+/* @test
+ * @library Test2.jar
@@ -12541,11 +12172,11 @@ diff -r ce2272390558 test/tailcalltests/
+ System.exit(1); // Failure.
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/Test2.jar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/Test2.jar
Binary file test/tailcalltests/protection_domain_tests/Test2.jar has changed
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/Test2.java.injar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/Test2.java.injar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/Test2.java.injar Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/Test2.java.injar Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,19 @@
+public class Test2 implements TestIFace {
+ public Integer tailcalleeIFace(Integer expect, Integer res) {
@@ -12566,16 +12197,16 @@ diff -r ce2272390558 test/tailcalltests/
+ else return goto InterpreterStatic.tailcaller(expect-1, res+1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/TestIFace.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/TestIFace.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/TestIFace.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/TestIFace.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,3 @@
+public interface TestIFace {
+ Integer tailcalleeIFace(Integer expect, Integer res);
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,46 @@
+/* @test
+ * @library Test2.jar
@@ -12623,11 +12254,11 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test2.jar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test2.jar
Binary file test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test2.jar has changed
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test2.java.injar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test2.java.injar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test2.java.injar Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilermega_compress/Test2.java.injar Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,16 @@
+public class Test2 extends Test{
+
@@ -12645,9 +12276,9 @@ diff -r ce2272390558 test/tailcalltests/
+ else return goto t.tailcaller(a,b,c,d,expect-1, res+1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,46 @@
+/* @test
+ * @library Test2.jar
@@ -12695,11 +12326,11 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test2.jar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test2.jar
Binary file test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test2.jar has changed
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test2.java.injar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test2.java.injar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test2.java.injar Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilermega_compress2/Test2.java.injar Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,16 @@
+public class Test2 extends Test{
+
@@ -12717,9 +12348,9 @@ diff -r ce2272390558 test/tailcalltests/
+ else return goto t.tailcaller(a,b,c,d,expect-1, res+1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,41 @@
+/* @test
+ * @library Test2.jar
@@ -12762,11 +12393,11 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test2.jar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test2.jar
Binary file test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test2.jar has changed
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test2.java.injar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test2.java.injar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test2.java.injar Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilermono_compress/Test2.java.injar Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,7 @@
+public class Test2 extends Test{
+ public Integer tailcallee(Integer a, Integer b, Integer c, Integer d, Integer expect, Integer res) {
@@ -12775,9 +12406,9 @@ diff -r ce2272390558 test/tailcalltests/
+ else return goto tailcaller(a,b,c,d,expect-1, res+1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,41 @@
+/* @test
+ * @library Test2.jar
@@ -12820,11 +12451,11 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test2.jar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test2.jar
Binary file test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test2.jar has changed
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test2.java.injar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test2.java.injar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test2.java.injar Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilermono_compress2/Test2.java.injar Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,7 @@
+public class Test2 extends Test{
+ public Integer tailcallee(Integer a, Integer b, Integer c, Integer d, Integer expect, Integer res) {
@@ -12833,9 +12464,9 @@ diff -r ce2272390558 test/tailcalltests/
+ else return goto tailcaller(a,b,c,d,expect-1, res+1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/CompilerStatic.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/CompilerStatic.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/CompilerStatic.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/CompilerStatic.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,28 @@
+/* @test
+ * @library Test2.jar
@@ -12865,11 +12496,11 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/Test2.jar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/Test2.jar
Binary file test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/Test2.jar has changed
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/Test2.java.injar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/Test2.java.injar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/Test2.java.injar Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/c2i_compilerstatic_compress/Test2.java.injar Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,7 @@
+public class Test2 {
+ public static Integer tailcallee(Integer a, Integer b, Integer c, Integer d, Integer expect, Integer res) {
@@ -12878,9 +12509,9 @@ diff -r ce2272390558 test/tailcalltests/
+ else return goto CompilerStatic.tailcaller(a,b,c,d,expect-1, res+1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/compilermega_compress/Test.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/compilermega_compress/Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/compilermega_compress/Test.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/compilermega_compress/Test.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,46 @@
+/* @test
+ * @library Test2.jar
@@ -12928,11 +12559,11 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/compilermega_compress/Test2.jar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/compilermega_compress/Test2.jar
Binary file test/tailcalltests/protection_domain_tests/compilermega_compress/Test2.jar has changed
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/compilermega_compress/Test2.java.injar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/compilermega_compress/Test2.java.injar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/compilermega_compress/Test2.java.injar Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/compilermega_compress/Test2.java.injar Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,16 @@
+public class Test2 extends Test{
+
@@ -12950,9 +12581,9 @@ diff -r ce2272390558 test/tailcalltests/
+ else return goto t.tailcaller(a,b,c,d,expect-1, res+1);
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/compilermono_compress/Test.java
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/compilermono_compress/Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/compilermono_compress/Test.java Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/compilermono_compress/Test.java Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,41 @@
+/* @test
+ * @library Test2.jar
@@ -12995,11 +12626,11 @@ diff -r ce2272390558 test/tailcalltests/
+ }
+ }
+}
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/compilermono_compress/Test2.jar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/compilermono_compress/Test2.jar
Binary file test/tailcalltests/protection_domain_tests/compilermono_compress/Test2.jar has changed
-diff -r ce2272390558 test/tailcalltests/protection_domain_tests/compilermono_compress/Test2.java.injar
+diff -r aa0c48844632 test/tailcalltests/protection_domain_tests/compilermono_compress/Test2.java.injar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/test/tailcalltests/protection_domain_tests/compilermono_compress/Test2.java.injar Mon Mar 16 11:42:47 2009 +0100
++++ b/test/tailcalltests/protection_domain_tests/compilermono_compress/Test2.java.injar Thu Jun 04 10:20:29 2009 +0200
@@ -0,0 +1,7 @@
+public class Test2 extends Test{
+ public Integer tailcallee(Integer a, Integer b, Integer c, Integer d, Integer expect, Integer res) {
@@ -13008,9 +12639,9 @@ diff -r ce2272390558 test/tailcalltests/
+ else return goto tailcaller(a,b,c,d,expect-1, res+1);
+ }
+}
-diff -r ce22