00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 # include "incls/_precompiled.incl"
00026
00027 #ifdef DELTA_COMPILER
00028
00029 #include "incls/_rframe.cpp.incl"
00030
00031 const RFrame* noCaller = (RFrame*) 0x1;
00032 const RFrame* noCallerYet = (RFrame*) 0x0;
00033
00034 RFrame::RFrame(frame fr, const RFrame* callee) : _fr(fr) {
00035 _caller = (RFrame*)noCallerYet;
00036 _callee = (RFrame*)callee;
00037 _invocations = _sends = _cumulSends = _loopDepth = 0;
00038 _num = callee ? callee->num() + 1 : 0;
00039 _distance = -1;
00040 }
00041
00042 void RFrame::set_distance(int d) {
00043 _distance = d;
00044 }
00045
00046 InterpretedRFrame::InterpretedRFrame(frame fr, const RFrame* callee) : RFrame(fr, callee) {
00047 vframe* vf1 = vframe::new_vframe(&_fr);
00048 assert(vf1->is_interpreted_frame(), "must be interpreted");
00049 interpretedVFrame* vf = (interpretedVFrame*)vf1;
00050 _method = vf->method();
00051 assert(_method->codes() <= _fr.hp() && _fr.hp() < _method->codes_end(),
00052 "frame doesn't match method");
00053 _bci = vf->bci();
00054 _receiverKlass = theRecompilation->receiverOf(vf)->klass();
00055 _vf = vf;
00056 }
00057
00058 InterpretedRFrame::InterpretedRFrame(frame fr, methodOop m, klassOop rcvrKlass) : RFrame(fr, NULL) {
00059 _method = m;
00060 assert(_method->codes() <= _fr.hp() && _fr.hp() < _method->codes_end(),
00061 "frame doesn't match method");
00062 _bci = PrologueBCI;
00063 _receiverKlass = rcvrKlass;
00064 vframe* vf1 = vframe::new_vframe(&_fr);
00065 assert(vf1->is_interpreted_frame(), "must be interpreted");
00066 interpretedVFrame* vf = (interpretedVFrame*)vf1;
00067 _vf = vf;
00068 init();
00069 }
00070
00071 CompiledRFrame::CompiledRFrame(frame fr, const RFrame* callee) : RFrame(fr, callee) {
00072 }
00073
00074 CompiledRFrame::CompiledRFrame(frame fr) : RFrame(fr, NULL) { init(); }
00075
00076
00077 RFrame* RFrame::new_RFrame(frame fr, const RFrame* callee) {
00078 RFrame* rf;
00079 int dist = callee ? callee->distance() : -1;
00080 if (fr.is_interpreted_frame()) {
00081 rf = new InterpretedRFrame(fr, callee);
00082 dist++;
00083 } else if (fr.is_compiled_frame()) {
00084 rf = new CompiledRFrame(fr, callee);
00085 } else {
00086 fatal("not a Delta frame");
00087 }
00088 rf->init();
00089 rf->set_distance(dist);
00090 return rf;
00091 }
00092
00093 bool RFrame::is_blockMethod() const { return top_method()->is_blockMethod(); }
00094
00095 RFrame* RFrame::caller() {
00096 if (_caller != noCallerYet) return (_caller == noCaller) ? NULL : _caller;
00097
00098
00099 if (_fr.is_first_delta_frame()) {
00100 _caller = (RFrame*)noCaller;
00101 return NULL;
00102 } else {
00103 _caller = new_RFrame(_fr.delta_sender(), this);
00104 return _caller;
00105 }
00106 }
00107
00108 methodOop CompiledRFrame::top_method() const {
00109 return _nm->method();
00110 }
00111
00112 bool RFrame::is_super() const {
00113 if (is_blockMethod()) return false;
00114 IC_Iterator* it = _fr.sender_ic_iterator();
00115 return it ? it->is_super_send() : false;
00116 }
00117
00118 bool RFrame::hasBlockArgs() const {
00119 deltaVFrame* vf = top_vframe();
00120 if (!vf) return false;
00121 int nargs = vf->method()->number_of_arguments();
00122 for (int i = 0; i < nargs; i++) {
00123 oop b = vf->argument_at(i);
00124 if (b->is_block()) return true;
00125 }
00126 return false;
00127 }
00128
00129 GrowableArray<blockClosureOop>* RFrame::blockArgs() const {
00130 deltaVFrame* vf = top_vframe();
00131 int nargs = top_method()->number_of_arguments();
00132 GrowableArray<blockClosureOop>* blocks = new GrowableArray<blockClosureOop>(nargs);
00133 if (!vf) return blocks;
00134 for (int i = 0; i < nargs; i++) {
00135 oop b = vf->argument_at(i);
00136 if (b->is_block()) blocks->append(blockClosureOop(b));
00137 }
00138 return blocks;
00139 }
00140
00141 LookupKey* CompiledRFrame::key() const {
00142 return &_nm->key;
00143 }
00144
00145 LookupKey* InterpretedRFrame::key() const {
00146 if (_key) return _key;
00147 if (_method->is_blockMethod()) return NULL;
00148 symbolOop sel = _method->selector();
00149 ((InterpretedRFrame*)this)->_key = LookupKey::allocate(_receiverKlass, sel);
00150
00151 if (is_super()) {
00152 deltaVFrame* senderVF = _vf ? _vf->sender_delta_frame() : DeltaProcess::active()->last_delta_vframe();
00153 methodOop sendingMethod = senderVF->method()->home();
00154 klassOop sendingMethodHolder =_receiverKlass->klass_part()->lookup_method_holder_for(sendingMethod);
00155 if (sendingMethodHolder) {
00156 klassOop superKlass = sendingMethodHolder->klass_part()->superKlass();
00157 assert(_method == lookupCache::method_lookup(superKlass, sel),
00158 "inconsistent lookup result");
00159 _key->initialize(superKlass, sel);
00160 } else {
00161 if (WizardMode) warning("sending method holder not found??");
00162 ((InterpretedRFrame*)this)->_key = NULL;
00163 }
00164 } else {
00165 assert(_method == lookupCache::compile_time_normal_lookup(_receiverKlass, sel),
00166 "inconsistent lookup result");
00167 }
00168 return _key;
00169 }
00170
00171 int InterpretedRFrame::cost() const {
00172 return _method->estimated_inline_cost(_receiverKlass);
00173 }
00174
00175 int CompiledRFrame::cost() const {
00176 return _nm->instsLen();
00177 }
00178
00179 void CompiledRFrame::cleanupStaleInlineCaches() { _nm->cleanup_inline_caches(); }
00180 void InterpretedRFrame::cleanupStaleInlineCaches() { _method->cleanup_inline_caches(); }
00181
00182 int RFrame::computeSends(methodOop m) {
00183
00184
00185 int sends = 0;
00186 CodeIterator iter(m);
00187 do {
00188 switch (iter.send()) {
00189 case Bytecodes::interpreted_send:
00190 case Bytecodes::compiled_send :
00191 case Bytecodes::polymorphic_send:
00192 case Bytecodes::predicted_send :
00193 case Bytecodes::accessor_send :
00194 { InterpretedIC* ic = iter.ic();
00195 InterpretedIC_Iterator it(ic);
00196 while (!it.at_end()) {
00197 int count;
00198 if (it.is_compiled()) {
00199 sends += (count = it.compiled_method()->invocation_count());
00200 } else {
00201 sends += (count = it.interpreted_method()->invocation_count());
00202 }
00203 assert(count >= 0 && count <= 100 * 1000 * 1000, "bad invocation count");
00204 it.advance();
00205 }
00206 }
00207 break;
00208 case Bytecodes::megamorphic_send:
00209
00210
00211 break;
00212 case Bytecodes::primitive_send :
00213 case Bytecodes::no_send :
00214 break;
00215 default:
00216 fatal1("unexpected send type %d", iter.send());
00217 }
00218 } while (iter.advance());
00219 return sends;
00220 }
00221
00222 static CompiledRFrame* this_rframe = NULL;
00223 static int sum_ics_result = 0;
00224 static void sum_ics(CompiledIC* ic) {
00225
00226
00227
00228 if (ic->is_empty()) return;
00229 CompiledIC_Iterator it(ic);
00230 while (!it.at_end()) {
00231 if (it.is_compiled()) {
00232 sum_ics_result += it.compiled_method()->invocation_count();
00233 } else {
00234 sum_ics_result += it.interpreted_method()->invocation_count();
00235 }
00236 it.advance();
00237 }
00238 }
00239
00240 void CompiledRFrame::init() {
00241 vframe* vf = vframe::new_vframe(&_fr);
00242 assert(vf->is_compiled_frame(), "must be compiled");
00243 _nm = ((compiledVFrame*)vf)->code();
00244 vf = vf->top();
00245 assert(vf->is_compiled_frame(), "must be compiled");
00246 _vf = (deltaVFrame*)vf;
00247 _invocations = _nm->invocation_count();
00248 _ncallers = _nm->number_of_links();
00249 this_rframe = this;
00250 sum_ics_result = 0;
00251 _nm->CompiledICs_do(sum_ics);
00252 _sends += sum_ics_result;
00253 }
00254
00255 void InterpretedRFrame::init() {
00256
00257 if (_bci != PrologueBCI) {
00258 CodeIterator iter(_method);
00259 while (bciLT(iter.bci(), _bci)) {
00260 switch (iter.loopType()) {
00261 case Bytecodes::loop_start: _loopDepth++; break;
00262 case Bytecodes::loop_end : _loopDepth--; break;
00263 case Bytecodes::no_loop : break;
00264 default: fatal1("unexpected loop type %d", iter.loopType());
00265 }
00266 if (!iter.advance()) break;
00267 }
00268 assert(iter.bci() == _bci, "should have found exact bci");
00269 }
00270 _invocations = _method->invocation_count();
00271 _ncallers = _method->sharing_count();
00272 _sends = computeSends(_method);
00273 _cumulSends = computeCumulSends(_method) + _sends;
00274 _key = NULL;
00275 }
00276
00277
00278
00279 class CumulCounter: public SpecializedMethodClosure {
00280 public:
00281 methodOop method;
00282 int cumulSends;
00283 bool top;
00284
00285 CumulCounter(methodOop m) { cumulSends = 0; method = m; top = true;}
00286
00287 void count() {
00288 if (!top) cumulSends += RFrame::computeSends(method);
00289 top = false;
00290 MethodIterator iter(method, this);
00291 }
00292
00293 void allocate_closure(AllocationType type, int nofArgs, methodOop meth) {
00294 methodOop savedMethod = method;
00295 method = meth;
00296 count();
00297 method = savedMethod;
00298 }
00299 };
00300
00301
00302 int RFrame::computeCumulSends(methodOop m) {
00303 CumulCounter c(m);
00304 c.count();
00305 return c.cumulSends;
00306 }
00307
00308 void RFrame::print(const char* kind) {
00309 lprintf("%3d %s %-15.15s: inv=%5d/%3d snd=%6d cum=%6d loop=%2d cst=%4d\n",
00310 _num, is_interpreted() ? "I" : "C", top_method()->selector()->as_string(),
00311 _invocations, _ncallers, _sends, _cumulSends, _loopDepth, cost());
00312 }
00313
00314 void CompiledRFrame::print() {
00315 RFrame::print("comp");
00316 }
00317
00318 void InterpretedRFrame::print() {
00319 RFrame::print("int.");
00320 }
00321
00322 #endif