rframe.cpp revision 0:a61af66fc99e
1/* 2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25# include "incls/_precompiled.incl" 26 27#include "incls/_rframe.cpp.incl" 28 29static RFrame*const noCaller = (RFrame*) 0x1; // no caller (i.e., initial frame) 30static RFrame*const noCallerYet = (RFrame*) 0x0; // caller not yet computed 31 32RFrame::RFrame(frame fr, JavaThread* thread, RFrame*const callee) : 33 _fr(fr), _thread(thread), _callee(callee), _num(callee ? callee->num() + 1 : 0) { 34 _caller = (RFrame*)noCallerYet; 35 _invocations = 0; 36 _distance = 0; 37} 38 39void RFrame::set_distance(int d) { 40 assert(is_compiled() || d >= 0, "should be positive"); 41 _distance = d; 42} 43 44InterpretedRFrame::InterpretedRFrame(frame fr, JavaThread* thread, RFrame*const callee) 45: RFrame(fr, thread, callee) { 46 RegisterMap map(thread, false); 47 _vf = javaVFrame::cast(vframe::new_vframe(&_fr, &map, thread)); 48 _method = methodHandle(thread, _vf->method()); 49 assert( _vf->is_interpreted_frame(), "must be interpreted"); 50 init(); 51} 52 53InterpretedRFrame::InterpretedRFrame(frame fr, JavaThread* thread, methodHandle m) 54: RFrame(fr, thread, NULL) { 55 RegisterMap map(thread, false); 56 _vf = javaVFrame::cast(vframe::new_vframe(&_fr, &map, thread)); 57 _method = m; 58 59 assert( _vf->is_interpreted_frame(), "must be interpreted"); 60 init(); 61} 62 63CompiledRFrame::CompiledRFrame(frame fr, JavaThread* thread, RFrame*const callee) 64: RFrame(fr, thread, callee) { 65 init(); 66} 67 68CompiledRFrame::CompiledRFrame(frame fr, JavaThread* thread) 69: RFrame(fr, thread, NULL) { 70 init(); 71} 72 73DeoptimizedRFrame::DeoptimizedRFrame(frame fr, JavaThread* thread, RFrame*const callee) 74: InterpretedRFrame(fr, thread, callee) {} 75 76RFrame* RFrame::new_RFrame(frame fr, JavaThread* thread, RFrame*const callee) { 77 RFrame* rf; 78 int dist = callee ? callee->distance() : -1; 79 if (fr.is_interpreted_frame()) { 80 rf = new InterpretedRFrame(fr, thread, callee); 81 dist++; 82 } else if (fr.is_compiled_frame()) { 83 // Even deopted frames look compiled because the deopt 84 // is invisible until it happens. 85 rf = new CompiledRFrame(fr, thread, callee); 86 } else { 87 assert(false, "Unhandled frame type"); 88 } 89 rf->set_distance(dist); 90 rf->init(); 91 return rf; 92} 93 94RFrame* RFrame::caller() { 95 if (_caller != noCallerYet) return (_caller == noCaller) ? NULL : _caller; // already computed caller 96 97 // caller not yet computed; do it now 98 if (_fr.is_first_java_frame()) { 99 _caller = (RFrame*)noCaller; 100 return NULL; 101 } 102 103 RegisterMap map(_thread, false); 104 frame sender = _fr.real_sender(&map); 105 if (sender.is_java_frame()) { 106 _caller = new_RFrame(sender, thread(), this); 107 return _caller; 108 } 109 110 // Real caller is not java related 111 _caller = (RFrame*)noCaller; 112 return NULL; 113} 114 115int InterpretedRFrame::cost() const { 116 return _method->code_size(); // fix this 117 //return _method->estimated_inline_cost(_receiverKlass); 118} 119 120int CompiledRFrame::cost() const { 121 nmethod* nm = top_method()->code(); 122 if (nm != NULL) { 123 return nm->code_size(); 124 } else { 125 return top_method()->code_size(); 126 } 127} 128 129void CompiledRFrame::init() { 130 RegisterMap map(thread(), false); 131 vframe* vf = vframe::new_vframe(&_fr, &map, thread()); 132 assert(vf->is_compiled_frame(), "must be compiled"); 133 _nm = compiledVFrame::cast(vf)->code(); 134 vf = vf->top(); 135 _vf = javaVFrame::cast(vf); 136 _method = methodHandle(thread(), CodeCache::find_nmethod(_fr.pc())->method()); 137 assert(_method(), "should have found a method"); 138#ifndef PRODUCT 139 _invocations = _method->compiled_invocation_count(); 140#endif 141} 142 143void InterpretedRFrame::init() { 144 _invocations = _method->invocation_count() + _method->backedge_count(); 145} 146 147void RFrame::print(const char* kind) { 148#ifndef PRODUCT 149#ifdef COMPILER2 150 int cnt = top_method()->interpreter_invocation_count(); 151#else 152 int cnt = top_method()->invocation_count(); 153#endif 154 tty->print("%3d %s ", _num, is_interpreted() ? "I" : "C"); 155 top_method()->print_short_name(tty); 156 tty->print_cr(": inv=%5d(%d) cst=%4d", _invocations, cnt, cost()); 157#endif 158} 159 160void CompiledRFrame::print() { 161 RFrame::print("comp"); 162} 163 164void InterpretedRFrame::print() { 165 RFrame::print("int."); 166} 167 168void DeoptimizedRFrame::print() { 169 RFrame::print("deopt."); 170} 171