src/cpu/x86/vm/frame_x86.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/cpu/x86/vm/frame_x86.cpp	Wed Oct 28 19:30:37 2009
--- new/src/cpu/x86/vm/frame_x86.cpp	Wed Oct 28 19:30:37 2009

*** 328,337 **** --- 328,345 ---- intptr_t* sp = (intptr_t*) addr_at(sender_sp_offset); // This is the sp before any possible extension (adapter/locals). intptr_t* unextended_sp = interpreter_frame_sender_sp(); + address sender_pc = this->sender_pc(); + CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); + assert(sender_cb, "sanity"); + nmethod* sender_nm = sender_cb->as_nmethod_or_null(); + if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) { + unextended_sp = (intptr_t*) at(link_offset); + } + // The interpreter and compiler(s) always save EBP/RBP in a known // location on entry. We must record where that location is // so this if EBP/RBP was live on callout from c2 we can find // the saved copy no matter what it called.
*** 350,360 **** --- 358,368 ---- map->set_location(rbp->as_VMReg()->next(), (address)addr_at(link_offset)); } #endif // AMD64 } #endif /* COMPILER2 */ - return frame(sp, unextended_sp, link(), sender_pc()); } //------------------------------sender_for_compiled_frame----------------------- frame frame::sender_for_compiled_frame(RegisterMap* map) const {
*** 373,382 **** --- 381,402 ---- // This is the saved value of ebp which may or may not really be an fp. // it is only an fp if the sender is an interpreter frame (or c1?) intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset); + intptr_t* unextended_sp = sender_sp; + // If we are returning to a compiled method handle call site, + // the saved_fp will in fact be a saved value of the unextended SP. + // The simplest way to tell whether we are returning to such a call + // site is as follows: + CodeBlob* sender_cb = CodeCache::find_blob_unsafe(sender_pc); + assert(sender_cb, "sanity"); + nmethod* sender_nm = sender_cb->as_nmethod_or_null(); + if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) { + unextended_sp = saved_fp; + } + if (map->update_map()) { // Tell GC to use argument oopmaps for some runtime stubs that need it. // For C1, the runtime stub might not have oop maps, so set this flag // outside of update_register_map. map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));
*** 397,407 **** --- 417,427 ---- } #endif // AMD64 } assert(sender_sp != sp(), "must have changed"); ! return frame(sender_sp, unextended_sp, saved_fp, sender_pc); } frame frame::sender(RegisterMap* map) const { // Default is we done have to follow them. The sender_for_xxx will // update it accordingly

src/cpu/x86/vm/frame_x86.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File