rframe.cpp revision 6760:22b98ab2a69f
1241310Sdteske/* 2222417Sjulian * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3222417Sjulian * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4222417Sjulian * 5222417Sjulian * This code is free software; you can redistribute it and/or modify it 6222417Sjulian * under the terms of the GNU General Public License version 2 only, as 7222417Sjulian * published by the Free Software Foundation. 8222417Sjulian * 9222417Sjulian * This code is distributed in the hope that it will be useful, but WITHOUT 10222417Sjulian * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11222417Sjulian * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12222417Sjulian * version 2 for more details (a copy is included in the LICENSE file that 13222417Sjulian * accompanied this code). 14222417Sjulian * 15222417Sjulian * You should have received a copy of the GNU General Public License version 16222417Sjulian * 2 along with this work; if not, write to the Free Software Foundation, 17222417Sjulian * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18222417Sjulian * 19222417Sjulian * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20222417Sjulian * or visit www.oracle.com if you need additional information or have any 21222417Sjulian * questions. 22222417Sjulian * 23222417Sjulian */ 24222417Sjulian 25222417Sjulian#include "precompiled.hpp" 26222417Sjulian#include "code/codeCache.hpp" 27222417Sjulian#include "interpreter/interpreter.hpp" 28222417Sjulian#include "oops/oop.inline.hpp" 29241523Sdteske#include "oops/symbol.hpp" 30241523Sdteske#include "runtime/frame.inline.hpp" 31241523Sdteske#include "runtime/rframe.hpp" 32222417Sjulian#include "runtime/vframe.hpp" 33222417Sjulian#include "runtime/vframe_hp.hpp" 34222417Sjulian 35222417Sjulian 36222417Sjulianstatic RFrame*const noCaller = (RFrame*) 0x1; // no caller (i.e., initial frame) 37222417Sjulianstatic RFrame*const noCallerYet = (RFrame*) 0x0; // caller not yet computed 38222417Sjulian 39222417SjulianRFrame::RFrame(frame fr, JavaThread* thread, RFrame*const callee) : 40222417Sjulian _fr(fr), _thread(thread), _callee(callee), _num(callee ? callee->num() + 1 : 0) { 41222417Sjulian _caller = (RFrame*)noCallerYet; 42222417Sjulian _invocations = 0; 43222417Sjulian _distance = 0; 44222417Sjulian} 45222417Sjulian 46222417Sjulianvoid RFrame::set_distance(int d) { 47222417Sjulian assert(is_compiled() || d >= 0, "should be positive"); 48222417Sjulian _distance = d; 49222417Sjulian} 50222417Sjulian 51222417SjulianInterpretedRFrame::InterpretedRFrame(frame fr, JavaThread* thread, RFrame*const callee) 52222417Sjulian: RFrame(fr, thread, callee) { 53222417Sjulian RegisterMap map(thread, false); 54222417Sjulian _vf = javaVFrame::cast(vframe::new_vframe(&_fr, &map, thread)); 55222417Sjulian _method = methodHandle(thread, _vf->method()); 56222417Sjulian assert( _vf->is_interpreted_frame(), "must be interpreted"); 57222417Sjulian init(); 58222417Sjulian} 59241523Sdteske 60241523SdteskeInterpretedRFrame::InterpretedRFrame(frame fr, JavaThread* thread, methodHandle m) 61241523Sdteske: RFrame(fr, thread, NULL) { 62241523Sdteske RegisterMap map(thread, false); 63241523Sdteske _vf = javaVFrame::cast(vframe::new_vframe(&_fr, &map, thread)); 64241523Sdteske _method = m; 65241523Sdteske 66222417Sjulian assert( _vf->is_interpreted_frame(), "must be interpreted"); 67222417Sjulian init(); 68222417Sjulian} 69222417Sjulian 70222417SjulianCompiledRFrame::CompiledRFrame(frame fr, JavaThread* thread, RFrame*const callee) 71222417Sjulian: RFrame(fr, thread, callee) { 72222417Sjulian init(); 73222417Sjulian} 74222417Sjulian 75233941SavgCompiledRFrame::CompiledRFrame(frame fr, JavaThread* thread) 76222417Sjulian: RFrame(fr, thread, NULL) { 77222417Sjulian init(); 78222417Sjulian} 79222417Sjulian 80233941SavgDeoptimizedRFrame::DeoptimizedRFrame(frame fr, JavaThread* thread, RFrame*const callee) 81233941Savg: InterpretedRFrame(fr, thread, callee) {} 82222417Sjulian 83233941SavgRFrame* RFrame::new_RFrame(frame fr, JavaThread* thread, RFrame*const callee) { 84222417Sjulian RFrame* rf; 85222417Sjulian int dist = callee ? callee->distance() : -1; 86222417Sjulian if (fr.is_interpreted_frame()) { 87222417Sjulian rf = new InterpretedRFrame(fr, thread, callee); 88233941Savg dist++; 89233941Savg } else if (fr.is_compiled_frame()) { 90222417Sjulian // Even deopted frames look compiled because the deopt 91222417Sjulian // is invisible until it happens. 92222417Sjulian rf = new CompiledRFrame(fr, thread, callee); 93222417Sjulian } else { 94222417Sjulian assert(false, "Unhandled frame type"); 95222417Sjulian } 96222417Sjulian rf->set_distance(dist); 97241523Sdteske rf->init(); 98241523Sdteske return rf; 99241523Sdteske} 100241523Sdteske 101241523SdteskeRFrame* RFrame::caller() { 102241523Sdteske if (_caller != noCallerYet) return (_caller == noCaller) ? NULL : _caller; // already computed caller 103241523Sdteske 104222417Sjulian // caller not yet computed; do it now 105222417Sjulian if (_fr.is_first_java_frame()) { 106222417Sjulian _caller = (RFrame*)noCaller; 107222417Sjulian return NULL; 108222417Sjulian } 109222417Sjulian 110222417Sjulian RegisterMap map(_thread, false); 111222417Sjulian frame sender = _fr.real_sender(&map); 112222417Sjulian if (sender.is_java_frame()) { 113222417Sjulian _caller = new_RFrame(sender, thread(), this); 114222417Sjulian return _caller; 115222417Sjulian } 116222417Sjulian 117222417Sjulian // Real caller is not java related 118222417Sjulian _caller = (RFrame*)noCaller; 119222417Sjulian return NULL; 120222417Sjulian} 121222417Sjulian 122241523Sdteskeint InterpretedRFrame::cost() const { 123241523Sdteske return _method->code_size(); // fix this 124241523Sdteske //return _method->estimated_inline_cost(_receiverKlass); 125241523Sdteske} 126241523Sdteske 127241523Sdteskeint CompiledRFrame::cost() const { 128241523Sdteske nmethod* nm = top_method()->code(); 129222417Sjulian if (nm != NULL) { 130222417Sjulian return nm->insts_size(); 131222417Sjulian } else { 132222417Sjulian return top_method()->code_size(); 133222417Sjulian } 134222417Sjulian} 135222417Sjulian 136222417Sjulianvoid CompiledRFrame::init() { 137222417Sjulian RegisterMap map(thread(), false); 138222417Sjulian vframe* vf = vframe::new_vframe(&_fr, &map, thread()); 139222417Sjulian assert(vf->is_compiled_frame(), "must be compiled"); 140222417Sjulian _nm = compiledVFrame::cast(vf)->code(); 141222417Sjulian vf = vf->top(); 142222417Sjulian _vf = javaVFrame::cast(vf); 143222417Sjulian _method = methodHandle(thread(), CodeCache::find_nmethod(_fr.pc())->method()); 144222417Sjulian assert(_method(), "should have found a method"); 145222417Sjulian#ifndef PRODUCT 146222417Sjulian _invocations = _method->compiled_invocation_count(); 147222417Sjulian#endif 148222417Sjulian} 149222417Sjulian 150222417Sjulianvoid InterpretedRFrame::init() { 151222417Sjulian _invocations = _method->invocation_count() + _method->backedge_count(); 152222417Sjulian} 153222417Sjulian 154222417Sjulianvoid RFrame::print(const char* kind) { 155222417Sjulian#ifndef PRODUCT 156222417Sjulian#ifdef COMPILER2 157222417Sjulian int cnt = top_method()->interpreter_invocation_count(); 158222417Sjulian#else 159241523Sdteske int cnt = top_method()->invocation_count(); 160241523Sdteske#endif 161241523Sdteske tty->print("%3d %s ", _num, is_interpreted() ? "I" : "C"); 162241523Sdteske top_method()->print_short_name(tty); 163241523Sdteske tty->print_cr(": inv=%5d(%d) cst=%4d", _invocations, cnt, cost()); 164241523Sdteske#endif 165241523Sdteske} 166241523Sdteske 167241523Sdteskevoid CompiledRFrame::print() { 168241523Sdteske RFrame::print("comp"); 169241523Sdteske} 170241523Sdteske 171241523Sdteskevoid InterpretedRFrame::print() { 172241523Sdteske RFrame::print("int."); 173241523Sdteske} 174241523Sdteske 175241523Sdteskevoid DeoptimizedRFrame::print() { 176241523Sdteske RFrame::print("deopt."); 177241523Sdteske} 178241523Sdteske