Mon, 01 Feb 2010 19:29:46 +0100
6921352: JSR 292 needs its own deopt handler
Summary: We need to introduce a new MH deopt handler so we can easily determine if the deopt happened at a MH call site or not.
Reviewed-by: never, jrose
1.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Jan 29 22:51:41 2010 -0800 1.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Mon Feb 01 19:29:46 2010 +0100 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -357,7 +357,7 @@ 1.11 } 1.12 1.13 1.14 -void LIR_Assembler::emit_exception_handler() { 1.15 +int LIR_Assembler::emit_exception_handler() { 1.16 // if the last instruction is a call (typically to do a throw which 1.17 // is coming at the end after block reordering) the return address 1.18 // must still point into the code area in order to avoid assertion 1.19 @@ -373,13 +373,10 @@ 1.20 if (handler_base == NULL) { 1.21 // not enough space left for the handler 1.22 bailout("exception handler overflow"); 1.23 - return; 1.24 + return -1; 1.25 } 1.26 -#ifdef ASSERT 1.27 + 1.28 int offset = code_offset(); 1.29 -#endif // ASSERT 1.30 - compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset()); 1.31 - 1.32 1.33 if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) { 1.34 __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type); 1.35 @@ -390,11 +387,13 @@ 1.36 __ delayed()->nop(); 1.37 debug_only(__ stop("should have gone to the caller");) 1.38 assert(code_offset() - offset <= exception_handler_size, "overflow"); 1.39 - 1.40 __ end_a_stub(); 1.41 + 1.42 + return offset; 1.43 } 1.44 1.45 -void LIR_Assembler::emit_deopt_handler() { 1.46 + 1.47 +int LIR_Assembler::emit_deopt_handler() { 1.48 // if the last instruction is a call (typically to do a throw which 1.49 // is coming at the end after block reordering) the return address 1.50 // must still point into the code area in order to avoid assertion 1.51 @@ -408,23 +407,18 @@ 1.52 if (handler_base == NULL) { 1.53 // not enough space left for the handler 1.54 bailout("deopt handler overflow"); 1.55 - return; 1.56 + return -1; 1.57 } 1.58 -#ifdef ASSERT 1.59 + 1.60 int offset = code_offset(); 1.61 -#endif // ASSERT 1.62 - compilation()->offsets()->set_value(CodeOffsets::Deopt, code_offset()); 1.63 - 1.64 AddressLiteral deopt_blob(SharedRuntime::deopt_blob()->unpack()); 1.65 - 1.66 __ JUMP(deopt_blob, G3_scratch, 0); // sethi;jmp 1.67 __ delayed()->nop(); 1.68 - 1.69 assert(code_offset() - offset <= deopt_handler_size, "overflow"); 1.70 - 1.71 debug_only(__ stop("should have gone to the caller");) 1.72 - 1.73 __ end_a_stub(); 1.74 + 1.75 + return offset; 1.76 } 1.77 1.78
2.1 --- a/src/cpu/sparc/vm/frame_sparc.cpp Fri Jan 29 22:51:41 2010 -0800 2.2 +++ b/src/cpu/sparc/vm/frame_sparc.cpp Mon Feb 01 19:29:46 2010 +0100 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 2.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -366,8 +366,9 @@ 2.11 // as get_original_pc() needs correct value for unextended_sp() 2.12 if (_pc != NULL) { 2.13 _cb = CodeCache::find_blob(_pc); 2.14 - if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 2.15 - _pc = ((nmethod*)_cb)->get_original_pc(this); 2.16 + address original_pc = nmethod::get_deopt_original_pc(this); 2.17 + if (original_pc != NULL) { 2.18 + _pc = original_pc; 2.19 _deopt_state = is_deoptimized; 2.20 } else { 2.21 _deopt_state = not_deoptimized; 2.22 @@ -519,9 +520,9 @@ 2.23 _cb = CodeCache::find_blob(pc); 2.24 *O7_addr() = pc - pc_return_offset; 2.25 _cb = CodeCache::find_blob(_pc); 2.26 - if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 2.27 - address orig = ((nmethod*)_cb)->get_original_pc(this); 2.28 - assert(orig == _pc, "expected original to be stored before patching"); 2.29 + address original_pc = nmethod::get_deopt_original_pc(this); 2.30 + if (original_pc != NULL) { 2.31 + assert(original_pc == _pc, "expected original to be stored before patching"); 2.32 _deopt_state = is_deoptimized; 2.33 } else { 2.34 _deopt_state = not_deoptimized;
3.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Jan 29 22:51:41 2010 -0800 3.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Mon Feb 01 19:29:46 2010 +0100 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. 3.6 + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -418,13 +418,12 @@ 3.11 } 3.12 3.13 3.14 -void LIR_Assembler::emit_exception_handler() { 3.15 +int LIR_Assembler::emit_exception_handler() { 3.16 // if the last instruction is a call (typically to do a throw which 3.17 // is coming at the end after block reordering) the return address 3.18 // must still point into the code area in order to avoid assertion 3.19 // failures when searching for the corresponding bci => add a nop 3.20 // (was bug 5/14/1999 - gri) 3.21 - 3.22 __ nop(); 3.23 3.24 // generate code for exception handler 3.25 @@ -432,13 +431,10 @@ 3.26 if (handler_base == NULL) { 3.27 // not enough space left for the handler 3.28 bailout("exception handler overflow"); 3.29 - return; 3.30 + return -1; 3.31 } 3.32 -#ifdef ASSERT 3.33 + 3.34 int offset = code_offset(); 3.35 -#endif // ASSERT 3.36 - 3.37 - compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset()); 3.38 3.39 // if the method does not have an exception handler, then there is 3.40 // no reason to search for one 3.41 @@ -474,19 +470,19 @@ 3.42 // unwind activation and forward exception to caller 3.43 // rax,: exception 3.44 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); 3.45 - 3.46 assert(code_offset() - offset <= exception_handler_size, "overflow"); 3.47 - 3.48 __ end_a_stub(); 3.49 + 3.50 + return offset; 3.51 } 3.52 3.53 -void LIR_Assembler::emit_deopt_handler() { 3.54 + 3.55 +int LIR_Assembler::emit_deopt_handler() { 3.56 // if the last instruction is a call (typically to do a throw which 3.57 // is coming at the end after block reordering) the return address 3.58 // must still point into the code area in order to avoid assertion 3.59 // failures when searching for the corresponding bci => add a nop 3.60 // (was bug 5/14/1999 - gri) 3.61 - 3.62 __ nop(); 3.63 3.64 // generate code for exception handler 3.65 @@ -494,23 +490,17 @@ 3.66 if (handler_base == NULL) { 3.67 // not enough space left for the handler 3.68 bailout("deopt handler overflow"); 3.69 - return; 3.70 + return -1; 3.71 } 3.72 -#ifdef ASSERT 3.73 + 3.74 int offset = code_offset(); 3.75 -#endif // ASSERT 3.76 - 3.77 - compilation()->offsets()->set_value(CodeOffsets::Deopt, code_offset()); 3.78 - 3.79 InternalAddress here(__ pc()); 3.80 __ pushptr(here.addr()); 3.81 - 3.82 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 3.83 - 3.84 assert(code_offset() - offset <= deopt_handler_size, "overflow"); 3.85 - 3.86 __ end_a_stub(); 3.87 3.88 + return offset; 3.89 } 3.90 3.91
4.1 --- a/src/cpu/x86/vm/frame_x86.cpp Fri Jan 29 22:51:41 2010 -0800 4.2 +++ b/src/cpu/x86/vm/frame_x86.cpp Mon Feb 01 19:29:46 2010 +0100 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 4.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -222,9 +222,9 @@ 4.11 } 4.12 ((address *)sp())[-1] = pc; 4.13 _cb = CodeCache::find_blob(pc); 4.14 - if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 4.15 - address orig = (((nmethod*)_cb)->get_original_pc(this)); 4.16 - assert(orig == _pc, "expected original to be stored before patching"); 4.17 + address original_pc = nmethod::get_deopt_original_pc(this); 4.18 + if (original_pc != NULL) { 4.19 + assert(original_pc == _pc, "expected original PC to be stored before patching"); 4.20 _deopt_state = is_deoptimized; 4.21 // leave _pc as is 4.22 } else { 4.23 @@ -323,19 +323,61 @@ 4.24 return fr; 4.25 } 4.26 4.27 + 4.28 +//------------------------------------------------------------------------------ 4.29 +// frame::verify_deopt_original_pc 4.30 +// 4.31 +// Verifies the calculated original PC of a deoptimization PC for the 4.32 +// given unextended SP. The unextended SP might also be the saved SP 4.33 +// for MethodHandle call sites. 4.34 +#if ASSERT 4.35 +void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) { 4.36 + frame fr; 4.37 + 4.38 + // This is ugly but it's better than to change {get,set}_original_pc 4.39 + // to take an SP value as argument. And it's only a debugging 4.40 + // method anyway. 4.41 + fr._unextended_sp = unextended_sp; 4.42 + 4.43 + address original_pc = nm->get_original_pc(&fr); 4.44 + assert(nm->code_contains(original_pc), "original PC must be in nmethod"); 4.45 + assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be"); 4.46 +} 4.47 +#endif 4.48 + 4.49 + 4.50 +//------------------------------------------------------------------------------ 4.51 +// frame::sender_for_interpreter_frame 4.52 frame frame::sender_for_interpreter_frame(RegisterMap* map) const { 4.53 - // sp is the raw sp from the sender after adapter or interpreter extension 4.54 - intptr_t* sp = (intptr_t*) addr_at(sender_sp_offset); 4.55 + // SP is the raw SP from the sender after adapter or interpreter 4.56 + // extension. 4.57 + intptr_t* sender_sp = this->sender_sp(); 4.58 4.59 // This is the sp before any possible extension (adapter/locals). 4.60 intptr_t* unextended_sp = interpreter_frame_sender_sp(); 4.61 4.62 + // Stored FP. 4.63 + intptr_t* saved_fp = link(); 4.64 + 4.65 address sender_pc = this->sender_pc(); 4.66 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); 4.67 assert(sender_cb, "sanity"); 4.68 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); 4.69 - if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) { 4.70 - unextended_sp = (intptr_t*) at(link_offset); 4.71 + 4.72 + if (sender_nm != NULL) { 4.73 + // If the sender PC is a deoptimization point, get the original 4.74 + // PC. For MethodHandle call site the unextended_sp is stored in 4.75 + // saved_fp. 4.76 + if (sender_nm->is_deopt_mh_entry(sender_pc)) { 4.77 + DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); 4.78 + unextended_sp = saved_fp; 4.79 + } 4.80 + else if (sender_nm->is_deopt_entry(sender_pc)) { 4.81 + DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); 4.82 + } 4.83 + else if (sender_nm->is_method_handle_return(sender_pc)) { 4.84 + unextended_sp = saved_fp; 4.85 + } 4.86 } 4.87 4.88 // The interpreter and compiler(s) always save EBP/RBP in a known 4.89 @@ -359,40 +401,51 @@ 4.90 } 4.91 #endif // AMD64 4.92 } 4.93 -#endif /* COMPILER2 */ 4.94 - return frame(sp, unextended_sp, link(), sender_pc); 4.95 +#endif // COMPILER2 4.96 + 4.97 + return frame(sender_sp, unextended_sp, saved_fp, sender_pc); 4.98 } 4.99 4.100 4.101 -//------------------------------sender_for_compiled_frame----------------------- 4.102 +//------------------------------------------------------------------------------ 4.103 +// frame::sender_for_compiled_frame 4.104 frame frame::sender_for_compiled_frame(RegisterMap* map) const { 4.105 assert(map != NULL, "map must be set"); 4.106 - const bool c1_compiled = _cb->is_compiled_by_c1(); 4.107 4.108 // frame owned by optimizing compiler 4.109 - intptr_t* sender_sp = NULL; 4.110 - 4.111 assert(_cb->frame_size() >= 0, "must have non-zero frame size"); 4.112 - sender_sp = unextended_sp() + _cb->frame_size(); 4.113 + intptr_t* sender_sp = unextended_sp() + _cb->frame_size(); 4.114 + intptr_t* unextended_sp = sender_sp; 4.115 4.116 // On Intel the return_address is always the word on the stack 4.117 address sender_pc = (address) *(sender_sp-1); 4.118 4.119 - // This is the saved value of ebp which may or may not really be an fp. 4.120 - // it is only an fp if the sender is an interpreter frame (or c1?) 4.121 + // This is the saved value of EBP which may or may not really be an FP. 4.122 + // It is only an FP if the sender is an interpreter frame (or C1?). 4.123 + intptr_t* saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset); 4.124 4.125 - intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset); 4.126 - 4.127 - intptr_t* unextended_sp = sender_sp; 4.128 - // If we are returning to a compiled method handle call site, 4.129 - // the saved_fp will in fact be a saved value of the unextended SP. 4.130 - // The simplest way to tell whether we are returning to such a call 4.131 - // site is as follows: 4.132 + // If we are returning to a compiled MethodHandle call site, the 4.133 + // saved_fp will in fact be a saved value of the unextended SP. The 4.134 + // simplest way to tell whether we are returning to such a call site 4.135 + // is as follows: 4.136 CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); 4.137 assert(sender_cb, "sanity"); 4.138 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); 4.139 - if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) { 4.140 - unextended_sp = saved_fp; 4.141 + 4.142 + if (sender_nm != NULL) { 4.143 + // If the sender PC is a deoptimization point, get the original 4.144 + // PC. For MethodHandle call site the unextended_sp is stored in 4.145 + // saved_fp. 4.146 + if (sender_nm->is_deopt_mh_entry(sender_pc)) { 4.147 + DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, saved_fp)); 4.148 + unextended_sp = saved_fp; 4.149 + } 4.150 + else if (sender_nm->is_deopt_entry(sender_pc)) { 4.151 + DEBUG_ONLY(verify_deopt_original_pc(sender_nm, unextended_sp)); 4.152 + } 4.153 + else if (sender_nm->is_method_handle_return(sender_pc)) { 4.154 + unextended_sp = saved_fp; 4.155 + } 4.156 } 4.157 4.158 if (map->update_map()) { 4.159 @@ -403,7 +456,7 @@ 4.160 if (_cb->oop_maps() != NULL) { 4.161 OopMapSet::update_register_map(this, map); 4.162 } 4.163 - // Since the prolog does the save and restore of epb there is no oopmap 4.164 + // Since the prolog does the save and restore of EBP there is no oopmap 4.165 // for it so we must fill in its location as if there was an oopmap entry 4.166 // since if our caller was compiled code there could be live jvm state in it. 4.167 map->set_location(rbp->as_VMReg(), (address) (sender_sp - frame::sender_sp_offset)); 4.168 @@ -422,6 +475,9 @@ 4.169 return frame(sender_sp, unextended_sp, saved_fp, sender_pc); 4.170 } 4.171 4.172 + 4.173 +//------------------------------------------------------------------------------ 4.174 +// frame::sender 4.175 frame frame::sender(RegisterMap* map) const { 4.176 // Default is we done have to follow them. The sender_for_xxx will 4.177 // update it accordingly
5.1 --- a/src/cpu/x86/vm/frame_x86.hpp Fri Jan 29 22:51:41 2010 -0800 5.2 +++ b/src/cpu/x86/vm/frame_x86.hpp Mon Feb 01 19:29:46 2010 +0100 5.3 @@ -163,6 +163,14 @@ 5.4 return (intptr_t*) addr_at(offset); 5.5 } 5.6 5.7 +#if ASSERT 5.8 + // Used in frame::sender_for_{interpreter,compiled}_frame 5.9 + static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false); 5.10 + static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) { 5.11 + verify_deopt_original_pc(nm, unextended_sp, true); 5.12 + } 5.13 +#endif 5.14 + 5.15 public: 5.16 // Constructors 5.17
6.1 --- a/src/cpu/x86/vm/frame_x86.inline.hpp Fri Jan 29 22:51:41 2010 -0800 6.2 +++ b/src/cpu/x86/vm/frame_x86.inline.hpp Mon Feb 01 19:29:46 2010 +0100 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 6.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -35,32 +35,35 @@ 6.11 _deopt_state = unknown; 6.12 } 6.13 6.14 -inline frame:: frame(intptr_t* sp, intptr_t* fp, address pc) { 6.15 +inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) { 6.16 _sp = sp; 6.17 _unextended_sp = sp; 6.18 _fp = fp; 6.19 _pc = pc; 6.20 assert(pc != NULL, "no pc?"); 6.21 _cb = CodeCache::find_blob(pc); 6.22 - _deopt_state = not_deoptimized; 6.23 - if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 6.24 - _pc = (((nmethod*)_cb)->get_original_pc(this)); 6.25 + 6.26 + address original_pc = nmethod::get_deopt_original_pc(this); 6.27 + if (original_pc != NULL) { 6.28 + _pc = original_pc; 6.29 _deopt_state = is_deoptimized; 6.30 } else { 6.31 _deopt_state = not_deoptimized; 6.32 } 6.33 } 6.34 6.35 -inline frame:: frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) { 6.36 +inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) { 6.37 _sp = sp; 6.38 _unextended_sp = unextended_sp; 6.39 _fp = fp; 6.40 _pc = pc; 6.41 assert(pc != NULL, "no pc?"); 6.42 _cb = CodeCache::find_blob(pc); 6.43 - _deopt_state = not_deoptimized; 6.44 - if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 6.45 - _pc = (((nmethod*)_cb)->get_original_pc(this)); 6.46 + 6.47 + address original_pc = nmethod::get_deopt_original_pc(this); 6.48 + if (original_pc != NULL) { 6.49 + _pc = original_pc; 6.50 + assert(((nmethod*)_cb)->code_contains(_pc), "original PC must be in nmethod"); 6.51 _deopt_state = is_deoptimized; 6.52 } else { 6.53 _deopt_state = not_deoptimized; 6.54 @@ -86,9 +89,9 @@ 6.55 6.56 _cb = CodeCache::find_blob(_pc); 6.57 6.58 - _deopt_state = not_deoptimized; 6.59 - if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 6.60 - _pc = (((nmethod*)_cb)->get_original_pc(this)); 6.61 + address original_pc = nmethod::get_deopt_original_pc(this); 6.62 + if (original_pc != NULL) { 6.63 + _pc = original_pc; 6.64 _deopt_state = is_deoptimized; 6.65 } else { 6.66 _deopt_state = not_deoptimized;
7.1 --- a/src/share/vm/asm/codeBuffer.hpp Fri Jan 29 22:51:41 2010 -0800 7.2 +++ b/src/share/vm/asm/codeBuffer.hpp Mon Feb 01 19:29:46 2010 +0100 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 7.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -39,6 +39,7 @@ 7.11 Dtrace_trap = OSR_Entry, // dtrace probes can never have an OSR entry so reuse it 7.12 Exceptions, // Offset where exception handler lives 7.13 Deopt, // Offset where deopt handler lives 7.14 + DeoptMH, // Offset where MethodHandle deopt handler lives 7.15 max_Entries }; 7.16 7.17 // special value to note codeBlobs where profile (forte) stack walking is 7.18 @@ -51,12 +52,13 @@ 7.19 7.20 public: 7.21 CodeOffsets() { 7.22 - _values[Entry] = 0; 7.23 + _values[Entry ] = 0; 7.24 _values[Verified_Entry] = 0; 7.25 _values[Frame_Complete] = frame_never_safe; 7.26 - _values[OSR_Entry] = 0; 7.27 - _values[Exceptions] = -1; 7.28 - _values[Deopt] = -1; 7.29 + _values[OSR_Entry ] = 0; 7.30 + _values[Exceptions ] = -1; 7.31 + _values[Deopt ] = -1; 7.32 + _values[DeoptMH ] = -1; 7.33 } 7.34 7.35 int value(Entries e) { return _values[e]; }
8.1 --- a/src/share/vm/c1/c1_Compilation.cpp Fri Jan 29 22:51:41 2010 -0800 8.2 +++ b/src/share/vm/c1/c1_Compilation.cpp Mon Feb 01 19:29:46 2010 +0100 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 8.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -205,6 +205,8 @@ 8.11 void Compilation::emit_code_epilog(LIR_Assembler* assembler) { 8.12 CHECK_BAILOUT(); 8.13 8.14 + CodeOffsets* code_offsets = assembler->offsets(); 8.15 + 8.16 // generate code or slow cases 8.17 assembler->emit_slow_case_stubs(); 8.18 CHECK_BAILOUT(); 8.19 @@ -213,10 +215,18 @@ 8.20 assembler->emit_exception_entries(exception_info_list()); 8.21 CHECK_BAILOUT(); 8.22 8.23 - // generate code for exception handler 8.24 - assembler->emit_exception_handler(); 8.25 + // Generate code for exception handler. 8.26 + code_offsets->set_value(CodeOffsets::Exceptions, assembler->emit_exception_handler()); 8.27 CHECK_BAILOUT(); 8.28 - assembler->emit_deopt_handler(); 8.29 + 8.30 + // Generate code for deopt handler. 8.31 + code_offsets->set_value(CodeOffsets::Deopt, assembler->emit_deopt_handler()); 8.32 + CHECK_BAILOUT(); 8.33 + 8.34 + // Generate code for MethodHandle deopt handler. We can use the 8.35 + // same code as for the normal deopt handler, we just need a 8.36 + // different entry point address. 8.37 + code_offsets->set_value(CodeOffsets::DeoptMH, assembler->emit_deopt_handler()); 8.38 CHECK_BAILOUT(); 8.39 8.40 // done
9.1 --- a/src/share/vm/c1/c1_LIRAssembler.hpp Fri Jan 29 22:51:41 2010 -0800 9.2 +++ b/src/share/vm/c1/c1_LIRAssembler.hpp Mon Feb 01 19:29:46 2010 +0100 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. 9.6 + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -133,9 +133,9 @@ 9.11 void add_call_info_here(CodeEmitInfo* info) { add_call_info(code_offset(), info); } 9.12 9.13 // code patterns 9.14 - void emit_exception_handler(); 9.15 + int emit_exception_handler(); 9.16 void emit_exception_entries(ExceptionInfoList* info_list); 9.17 - void emit_deopt_handler(); 9.18 + int emit_deopt_handler(); 9.19 9.20 void emit_code(BlockList* hir); 9.21 void emit_block(BlockBegin* block);
10.1 --- a/src/share/vm/code/nmethod.cpp Fri Jan 29 22:51:41 2010 -0800 10.2 +++ b/src/share/vm/code/nmethod.cpp Mon Feb 01 19:29:46 2010 +0100 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 10.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -593,6 +593,7 @@ 10.11 // values something that will never match a pc like the nmethod vtable entry 10.12 _exception_offset = 0; 10.13 _deoptimize_offset = 0; 10.14 + _deoptimize_mh_offset = 0; 10.15 _orig_pc_offset = 0; 10.16 #ifdef HAVE_DTRACE_H 10.17 _trap_offset = 0; 10.18 @@ -683,6 +684,7 @@ 10.19 // values something that will never match a pc like the nmethod vtable entry 10.20 _exception_offset = 0; 10.21 _deoptimize_offset = 0; 10.22 + _deoptimize_mh_offset = 0; 10.23 _trap_offset = offsets->value(CodeOffsets::Dtrace_trap); 10.24 _orig_pc_offset = 0; 10.25 _stub_offset = data_offset(); 10.26 @@ -795,6 +797,7 @@ 10.27 // Exception handler and deopt handler are in the stub section 10.28 _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); 10.29 _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt); 10.30 + _deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH); 10.31 _consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start()); 10.32 _scopes_data_offset = data_offset(); 10.33 _scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize); 10.34 @@ -2037,9 +2040,21 @@ 10.35 guarantee(nm->_lock_count >= 0, "unmatched nmethod lock/unlock"); 10.36 } 10.37 10.38 -bool nmethod::is_deopt_pc(address pc) { 10.39 - bool ret = pc == deopt_handler_begin(); 10.40 - return ret; 10.41 + 10.42 +// ----------------------------------------------------------------------------- 10.43 +// nmethod::get_deopt_original_pc 10.44 +// 10.45 +// Return the original PC for the given PC if: 10.46 +// (a) the given PC belongs to a nmethod and 10.47 +// (b) it is a deopt PC 10.48 +address nmethod::get_deopt_original_pc(const frame* fr) { 10.49 + if (fr->cb() == NULL) return NULL; 10.50 + 10.51 + nmethod* nm = fr->cb()->as_nmethod_or_null(); 10.52 + if (nm != NULL && nm->is_deopt_pc(fr->pc())) 10.53 + return nm->get_original_pc(fr); 10.54 + 10.55 + return NULL; 10.56 } 10.57 10.58 10.59 @@ -2410,6 +2425,8 @@ 10.60 if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); 10.61 if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); 10.62 if (block_begin == stub_begin()) stream->print_cr("[Stub Code]"); 10.63 + if (block_begin == deopt_handler_begin()) stream->print_cr("[Deopt Handler Code]"); 10.64 + if (block_begin == deopt_mh_handler_begin()) stream->print_cr("[Deopt MH Handler Code]"); 10.65 if (block_begin == consts_begin()) stream->print_cr("[Constants]"); 10.66 if (block_begin == entry_point()) { 10.67 methodHandle m = method();
11.1 --- a/src/share/vm/code/nmethod.hpp Fri Jan 29 22:51:41 2010 -0800 11.2 +++ b/src/share/vm/code/nmethod.hpp Mon Feb 01 19:29:46 2010 +0100 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 11.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -148,8 +148,12 @@ 11.11 11.12 // Offsets for different nmethod parts 11.13 int _exception_offset; 11.14 - // All deoptee's will resume execution at this location described by this offset 11.15 + // All deoptee's will resume execution at this location described by 11.16 + // this offset. 11.17 int _deoptimize_offset; 11.18 + // All deoptee's at a MethodHandle call site will resume execution 11.19 + // at this location described by this offset. 11.20 + int _deoptimize_mh_offset; 11.21 #ifdef HAVE_DTRACE_H 11.22 int _trap_offset; 11.23 #endif // def HAVE_DTRACE_H 11.24 @@ -332,24 +336,25 @@ 11.25 bool is_compiled_by_c2() const; 11.26 11.27 // boundaries for different parts 11.28 - address code_begin () const { return _entry_point; } 11.29 - address code_end () const { return header_begin() + _stub_offset ; } 11.30 - address exception_begin () const { return header_begin() + _exception_offset ; } 11.31 - address deopt_handler_begin() const { return header_begin() + _deoptimize_offset ; } 11.32 - address stub_begin () const { return header_begin() + _stub_offset ; } 11.33 - address stub_end () const { return header_begin() + _consts_offset ; } 11.34 - address consts_begin () const { return header_begin() + _consts_offset ; } 11.35 - address consts_end () const { return header_begin() + _scopes_data_offset ; } 11.36 - address scopes_data_begin () const { return header_begin() + _scopes_data_offset ; } 11.37 - address scopes_data_end () const { return header_begin() + _scopes_pcs_offset ; } 11.38 - PcDesc* scopes_pcs_begin () const { return (PcDesc*)(header_begin() + _scopes_pcs_offset ); } 11.39 - PcDesc* scopes_pcs_end () const { return (PcDesc*)(header_begin() + _dependencies_offset); } 11.40 - address dependencies_begin () const { return header_begin() + _dependencies_offset ; } 11.41 - address dependencies_end () const { return header_begin() + _handler_table_offset ; } 11.42 - address handler_table_begin() const { return header_begin() + _handler_table_offset ; } 11.43 - address handler_table_end () const { return header_begin() + _nul_chk_table_offset ; } 11.44 - address nul_chk_table_begin() const { return header_begin() + _nul_chk_table_offset ; } 11.45 - address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; } 11.46 + address code_begin () const { return _entry_point; } 11.47 + address code_end () const { return header_begin() + _stub_offset ; } 11.48 + address exception_begin () const { return header_begin() + _exception_offset ; } 11.49 + address deopt_handler_begin () const { return header_begin() + _deoptimize_offset ; } 11.50 + address deopt_mh_handler_begin() const { return header_begin() + _deoptimize_mh_offset ; } 11.51 + address stub_begin () const { return header_begin() + _stub_offset ; } 11.52 + address stub_end () const { return header_begin() + _consts_offset ; } 11.53 + address consts_begin () const { return header_begin() + _consts_offset ; } 11.54 + address consts_end () const { return header_begin() + _scopes_data_offset ; } 11.55 + address scopes_data_begin () const { return header_begin() + _scopes_data_offset ; } 11.56 + address scopes_data_end () const { return header_begin() + _scopes_pcs_offset ; } 11.57 + PcDesc* scopes_pcs_begin () const { return (PcDesc*)(header_begin() + _scopes_pcs_offset ); } 11.58 + PcDesc* scopes_pcs_end () const { return (PcDesc*)(header_begin() + _dependencies_offset) ; } 11.59 + address dependencies_begin () const { return header_begin() + _dependencies_offset ; } 11.60 + address dependencies_end () const { return header_begin() + _handler_table_offset ; } 11.61 + address handler_table_begin () const { return header_begin() + _handler_table_offset ; } 11.62 + address handler_table_end () const { return header_begin() + _nul_chk_table_offset ; } 11.63 + address nul_chk_table_begin () const { return header_begin() + _nul_chk_table_offset ; } 11.64 + address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; } 11.65 11.66 int code_size () const { return code_end () - code_begin (); } 11.67 int stub_size () const { return stub_end () - stub_begin (); } 11.68 @@ -524,7 +529,7 @@ 11.69 private: 11.70 ScopeDesc* scope_desc_in(address begin, address end); 11.71 11.72 - address* orig_pc_addr(const frame* fr ) { return (address*) ((address)fr->unextended_sp() + _orig_pc_offset); } 11.73 + address* orig_pc_addr(const frame* fr) { return (address*) ((address)fr->unextended_sp() + _orig_pc_offset); } 11.74 11.75 PcDesc* find_pc_desc_internal(address pc, bool approximate); 11.76 11.77 @@ -547,13 +552,17 @@ 11.78 void copy_scopes_pcs(PcDesc* pcs, int count); 11.79 void copy_scopes_data(address buffer, int size); 11.80 11.81 - // deopt 11.82 - // return true is the pc is one would expect if the frame is being deopted. 11.83 - bool is_deopt_pc(address pc); 11.84 + // Deopt 11.85 + // Return true is the PC is one would expect if the frame is being deopted. 11.86 + bool is_deopt_pc (address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); } 11.87 + bool is_deopt_entry (address pc) { return pc == deopt_handler_begin(); } 11.88 + bool is_deopt_mh_entry(address pc) { return pc == deopt_mh_handler_begin(); } 11.89 // Accessor/mutator for the original pc of a frame before a frame was deopted. 11.90 address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); } 11.91 void set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; } 11.92 11.93 + static address get_deopt_original_pc(const frame* fr); 11.94 + 11.95 // MethodHandle 11.96 bool is_method_handle_return(address return_pc); 11.97
12.1 --- a/src/share/vm/opto/output.cpp Fri Jan 29 22:51:41 2010 -0800 12.2 +++ b/src/share/vm/opto/output.cpp Mon Feb 01 19:29:46 2010 +0100 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved. 12.6 + * Copyright 1998-2010 Sun Microsystems, Inc. All Rights Reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -1430,6 +1430,10 @@ 12.11 _code_offsets.set_value(CodeOffsets::Exceptions, emit_exception_handler(*cb)); 12.12 // Emit the deopt handler code. 12.13 _code_offsets.set_value(CodeOffsets::Deopt, emit_deopt_handler(*cb)); 12.14 + // Emit the MethodHandle deopt handler code. We can use the same 12.15 + // code as for the normal deopt handler, we just need a different 12.16 + // entry point address. 12.17 + _code_offsets.set_value(CodeOffsets::DeoptMH, emit_deopt_handler(*cb)); 12.18 } 12.19 12.20 // One last check for failed CodeBuffer::expand:
13.1 --- a/src/share/vm/runtime/deoptimization.cpp Fri Jan 29 22:51:41 2010 -0800 13.2 +++ b/src/share/vm/runtime/deoptimization.cpp Mon Feb 01 19:29:46 2010 +0100 13.3 @@ -1,5 +1,5 @@ 13.4 /* 13.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 13.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.8 * 13.9 * This code is free software; you can redistribute it and/or modify it 13.10 @@ -235,6 +235,12 @@ 13.11 assert(cb->frame_size() >= 0, "Unexpected frame size"); 13.12 intptr_t* unpack_sp = stub_frame.sp() + cb->frame_size(); 13.13 13.14 + // If the deopt call site is a MethodHandle invoke call site we have 13.15 + // to adjust the unpack_sp. 13.16 + nmethod* deoptee_nm = deoptee.cb()->as_nmethod_or_null(); 13.17 + if (deoptee_nm != NULL && deoptee_nm->is_method_handle_return(deoptee.pc())) 13.18 + unpack_sp = deoptee.unextended_sp(); 13.19 + 13.20 #ifdef ASSERT 13.21 assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking"); 13.22 Events::log("fetch unroll sp " INTPTR_FORMAT, unpack_sp);
14.1 --- a/src/share/vm/runtime/frame.cpp Fri Jan 29 22:51:41 2010 -0800 14.2 +++ b/src/share/vm/runtime/frame.cpp Mon Feb 01 19:29:46 2010 +0100 14.3 @@ -1,5 +1,5 @@ 14.4 /* 14.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 14.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 14.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.8 * 14.9 * This code is free software; you can redistribute it and/or modify it 14.10 @@ -107,7 +107,11 @@ 14.11 14.12 address frame::raw_pc() const { 14.13 if (is_deoptimized_frame()) { 14.14 - return ((nmethod*) cb())->deopt_handler_begin() - pc_return_offset; 14.15 + nmethod* nm = cb()->as_nmethod_or_null(); 14.16 + if (nm->is_method_handle_return(pc())) 14.17 + return nm->deopt_mh_handler_begin() - pc_return_offset; 14.18 + else 14.19 + return nm->deopt_handler_begin() - pc_return_offset; 14.20 } else { 14.21 return (pc() - pc_return_offset); 14.22 } 14.23 @@ -269,10 +273,16 @@ 14.24 } // NeedsDeoptSuspend 14.25 14.26 14.27 - address deopt = nm->deopt_handler_begin(); 14.28 + // If the call site is a MethodHandle call site use the MH deopt 14.29 + // handler. 14.30 + address deopt = nm->is_method_handle_return(pc()) ? 14.31 + nm->deopt_mh_handler_begin() : 14.32 + nm->deopt_handler_begin(); 14.33 + 14.34 // Save the original pc before we patch in the new one 14.35 nm->set_original_pc(this, pc()); 14.36 patch_pc(thread, deopt); 14.37 + 14.38 #ifdef ASSERT 14.39 { 14.40 RegisterMap map(thread, false);
15.1 --- a/src/share/vm/runtime/sharedRuntime.cpp Fri Jan 29 22:51:41 2010 -0800 15.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp Mon Feb 01 19:29:46 2010 +0100 15.3 @@ -1033,10 +1033,20 @@ 15.4 address sender_pc = caller_frame.pc(); 15.5 CodeBlob* sender_cb = caller_frame.cb(); 15.6 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); 15.7 + bool is_mh_invoke_via_adapter = false; // Direct c2c call or via adapter? 15.8 + if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) { 15.9 + // If the callee_target is set, then we have come here via an i2c 15.10 + // adapter. 15.11 + methodOop callee = thread->callee_target(); 15.12 + if (callee != NULL) { 15.13 + assert(callee->is_method(), "sanity"); 15.14 + is_mh_invoke_via_adapter = true; 15.15 + } 15.16 + } 15.17 15.18 if (caller_frame.is_interpreted_frame() || 15.19 - caller_frame.is_entry_frame() || 15.20 - (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc))) { 15.21 + caller_frame.is_entry_frame() || 15.22 + is_mh_invoke_via_adapter) { 15.23 methodOop callee = thread->callee_target(); 15.24 guarantee(callee != NULL && callee->is_method(), "bad handshake"); 15.25 thread->set_vm_result(callee); 15.26 @@ -1417,7 +1427,7 @@ 15.27 if (callee == cb || callee->is_adapter_blob()) { 15.28 // static call or optimized virtual 15.29 if (TraceCallFixup) { 15.30 - tty->print("fixup callsite at " INTPTR_FORMAT " to compiled code for", caller_pc); 15.31 + tty->print("fixup callsite at " INTPTR_FORMAT " to compiled code for", caller_pc); 15.32 moop->print_short_name(tty); 15.33 tty->print_cr(" to " INTPTR_FORMAT, entry_point); 15.34 } 15.35 @@ -1433,7 +1443,7 @@ 15.36 } 15.37 } else { 15.38 if (TraceCallFixup) { 15.39 - tty->print("already patched callsite at " INTPTR_FORMAT " to compiled code for", caller_pc); 15.40 + tty->print("already patched callsite at " INTPTR_FORMAT " to compiled code for", caller_pc); 15.41 moop->print_short_name(tty); 15.42 tty->print_cr(" to " INTPTR_FORMAT, entry_point); 15.43 }