recompiler.cpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.39 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 
00025 # include "incls/_precompiled.incl"
00026 #ifdef DELTA_COMPILER
00027 
00028 #include "incls/_recompiler.cpp.incl"
00029 
00030 RecompilationPolicy::RecompilationPolicy(RFrame* first) {
00031   stack = new GrowableArray<RFrame*>(50);
00032   stack->push(first);
00033 }
00034 
00035 
00036 Recompilee* RecompilationPolicy::findRecompilee() {
00037   RFrame* rf = stack->at(0);
00038   if (PrintRecompilation2) {
00039     for (int i = 0; i < 10 && rf; i++, rf = senderOf(rf)) ;   // create 10 frames
00040     printStack();
00041   }
00042   RFrame* r = findTopInlinableFrame();
00043   if (r) {
00044     if (PrintRecompilation) r->print();
00045     return Recompilee::new_Recompilee(r);
00046   } else {
00047     return NULL;
00048   }
00049 }
00050 
00051 void RecompilationPolicy::cleanupStaleInlineCaches() {
00052   int len = min(20, stack->length());
00053   for (int i = 0; i < len; i++) stack->at(i)->cleanupStaleInlineCaches();
00054 }
00055 
00056 RFrame* RecompilationPolicy::findTopInlinableFrame() {
00057   // go up the stack until finding a frame that (probably) won't be inlined into its caller
00058   RecompilerInliningPolicy p;
00059   RFrame* current = stack->at(0);       // current choice for stopping
00060   RFrame* prev = NULL;                  // prev. value of current
00061   RFrame* prevMethod = NULL;            // same as prev, except always holds method frames (not blocks)
00062   msg = NULL; 
00063   
00064   while (1) {
00065     if (current == NULL) {
00066       // reached end of stack without finding a candidate
00067       current = prev; 
00068       break;
00069     }
00070 
00071     if ((msg = p.shouldInline(current)) != NULL) {
00072       // current won't be inlined into caller, so stop here
00073       break;
00074     }
00075 
00076     // before going up the stack further, check if doing so would get us into compiled code
00077     RFrame* next = senderOrParentOf(current);
00078 
00079     if (next) {
00080       if (next->num() > MaxRecompilationSearchLength) {
00081         // don't go up too high when searching for recompilees
00082         msg = "(don't go up any further: next > MaxRecompilationSearchLength)";
00083         break;
00084       }
00085       if (next->distance() > MaxInterpretedSearchLength) {
00086         // don't go up too high when searching for recompilees
00087         msg = "(don't go up any further: next > MaxInterpretedSearchLength)";
00088         break;
00089       }
00090       if (current->is_interpreted()) {
00091         // Before recompiling any compiled code (next or its callers), first compile the interpreted
00092         // method; later, if that gets executed often, it will trigger another recompile that 
00093         // will lead to next (or its caller) to be reoptimized.  At that point, optimization can take
00094         // advantage of the better type information in the compiled version of current
00095         LookupKey* k = next->key();
00096         if (next->is_compiled()) {
00097           msg = "(not going up into optimized code)";
00098           break;
00099         } else if (k != NULL && Universe::code->lookup(k) != NULL) {
00100           msg = "(already compiled this method)";
00101           break;
00102         } 
00103       }
00104       if (next->is_compiled() && (msg = shouldNotRecompileNMethod(next->nm())) != NULL) {
00105         msg = "nmethod should not be recompiled; don't go up";
00106         break;
00107       }
00108       if (next->is_compiled() && next->sends() < MinSendsBeforeRecompile) {
00109         msg = "don't recompile -- hasn't sent MinSendsBeforeRecompile messages yet";
00110         if (PrintRecompilation && msg) current->print();
00111         break;
00112       }
00113     }
00114     prev = current;
00115     
00116     if (!current->is_blockMethod()) prevMethod = current;
00117     current = next;
00118   }
00119 
00120   if (current) checkCurrent(current, prev, prevMethod);
00121 
00122   if (PrintRecompilation && msg) lprintf("%s\n", msg);
00123 
00124   return current;
00125 }
00126 
00127 void RecompilationPolicy::checkCurrent(RFrame*& current, RFrame*& prev, RFrame*& prevMethod) {
00128   // current is the provisional recompilation candidate; perform a few sanity checks on it
00129   if (current->is_blockMethod() && current->is_interpreted()) {
00130     // can't recompile blocks in isolation, and this block is too big to inline
00131     // thus, optimize method called by block
00132     if (PrintRecompilation && msg) lprintf("%s\n", msg);
00133     fixBlockParent(current);
00134     if (prev && !prev->is_blockMethod()) {
00135       current = prev; prev = prevMethod = NULL;
00136       if (current) checkCurrent(current, prev, prevMethod);
00137       msg = "(can't recompile block in isolation)";
00138     } else {
00139       current = NULL;
00140       msg = "(can't recompile block in isolation, and no callee method found)";
00141     }
00142   } else if (current->is_super()) {
00143     current = prev; prev = prevMethod = NULL;
00144     if (current) checkCurrent(current, prev, prevMethod);
00145     msg = "(can't recompile super nmethods yet)";
00146   } else if (current->is_compiled()) {
00147     char* msg2;
00148     if ((msg2 = shouldNotRecompileNMethod(current->nm())) != NULL) {
00149       current = NULL;
00150       msg = msg2;
00151     } else {
00152       // should recompile nmethod
00153       msg = NULL;
00154     }
00155   }
00156   if (current == NULL) return;      
00157 
00158   // check if we already recompiled this method (but old one is still on the stack)
00159   // Inserted after several hours of debugging by Lars
00160   if (current->is_compiled()) {
00161     if (EnableOptimizedCodeRecompilation) {
00162       LookupKey* k          = current->key();
00163       nmethod*   running_nm = current->nm();
00164       nmethod*   newest_nm  = k ? Universe::code->lookup(k) : NULL;
00165       // NB: newest_nm is always NULL for block nmethods
00166       if (k && running_nm && running_nm->is_method() && running_nm != newest_nm) {
00167         // ideally, should determine how many stack frames nm covers, then recompile
00168         // the next frame
00169         // for now, try previous method frame
00170         current = prevMethod; prev = prevMethod = NULL;
00171         if (current) checkCurrent(current, prev, prevMethod);
00172       }
00173     } else {
00174       current = NULL;
00175     }
00176   }
00177 }
00178 
00179 char* RecompilationPolicy::shouldNotRecompileNMethod(nmethod* nm) {
00180   // if nm should not be recompiled, return a string with the reason; otherwise, return NULL
00181   if (nm->isUncommonRecompiled()) {
00182     if (RecompilationPolicy::shouldRecompileUncommonNMethod(nm)) {
00183       nm->makeOld();
00184       return NULL;        // ok
00185     } else {
00186       return "uncommon nmethod too young";
00187     }
00188   } else if (nm->version() >= MaxVersions) {
00189     return "max. version reached";
00190   } else if (nm->level() == MaxRecompilationLevels - 1) {
00191     return "maximally optimized";
00192   } else if (nm->isYoung()) {
00193     return "nmethod too young";
00194   }
00195   return NULL;
00196 }
00197 
00198 RFrame* RecompilationPolicy::senderOf(RFrame* rf) {
00199   RFrame* sender = rf->caller();
00200   if (sender && sender->num() == stack->length()) stack->push(sender);
00201   return sender;
00202 }
00203 
00204 void RecompilationPolicy::fixBlockParent(RFrame* rf) {
00205   // find the parent method and increase its counter so it will be recompiled next time
00206   methodOop blk = rf->top_method();
00207   assert(blk->is_blockMethod(), "must be a block");
00208   methodOop home = blk->home();
00209   int count = home->invocation_count();
00210   count += Interpreter::get_invocation_counter_limit();
00211   count = min(count, methodOopDesc::_invocation_count_max - 1);
00212   home->set_invocation_count(count);
00213   assert(home->invocation_count() >= Interpreter::get_invocation_counter_limit(),
00214          "counter increment didn't work");
00215 }
00216 
00217 RFrame* RecompilationPolicy::senderOrParentOf(RFrame* rf) {
00218   // "go up" on the stack to find a better recompilee;
00219   // for normal methods, that's the sender; for block methods, it's the home method
00220   // (*not* enclosing scope) unless that method is already optimized
00221   if (rf->is_blockMethod()) {
00222     RFrame* parent = parentOf(rf);
00223     if (parent == NULL) {
00224       // can't find the parent (e.g. because it's a non-LIFO block)
00225       fixBlockParent(rf);
00226       return senderOf(rf);      // is this a good idea???
00227       // It may be; this way, a parent-less block doesn't prevent its callers from being
00228       // optimized; on the other hand, it may lead to too much compilation since what we
00229       // really want to do is recompile the parent.  On the third hand, if a block is non-lifo
00230       // = (has no parent) it may not make sense to optimize its enclosing method anyway.
00231       // But on the fourth hand, to optimize any block its enclosing method must be optimized.
00232     } else {
00233       if (parent->is_compiled() == rf->is_compiled()) {
00234         // try to optimize the parent
00235         if (CountParentLinksAsOne) parent->set_distance(rf->distance() + 1);
00236         return parent;
00237       } else {
00238         return senderOf(rf);    // try sender
00239       }
00240     }
00241   } else if (rf->hasBlockArgs()) {
00242     // go up to highest home of any block arg
00243     // bug: should check how often block is created / invoked
00244     GrowableArray<blockClosureOop>* blockArgs = rf->blockArgs();
00245     RFrame* max = NULL;
00246     for (int i = 0; i < blockArgs->length(); i++) {
00247       blockClosureOop blk = blockArgs->at(i);
00248       //jumpTableEntry* e = blk->jump_table_entry();
00249       RFrame* home = parentOfBlock(blk);
00250       if (home == NULL) continue;
00251       if (max == NULL || home->num() > max->num()) max = home;
00252     }
00253     if (max) return max;
00254   }
00255   // default: return sender
00256   return senderOf(rf);
00257 }
00258 
00259 RFrame* RecompilationPolicy::parentOf(RFrame* rf) {
00260   assert(rf->is_blockMethod(), "shouldn't call");
00261   // use caller vframe's receiver instead of rf's receiver because vframe may not be set up correctly
00262   // for most recent frame [this may not be true anymore -- Urs 10/96]
00263   // caller vframe must have block as the receiver because it invokes primitiveValue
00264 
00265   // Urs - please put in more comments here (gri):
00266   // b) why do you look at the receiver of the sender instead of the receiver of the send
00267   //    (it only happens right now that they are the same, but what if we change what we
00268   //    can use as first argument for primitives (primitiveValue) ?). Seems to be a lot of
00269   //    implicit assumptions & no checks.
00270   // Yes this assumes that the caller invokes primitiveValue on self; if we change that the
00271   // code here breaks.
00272 
00273   deltaVFrame* sender = rf->top_vframe()->sender_delta_frame();  
00274   if (sender == NULL) return NULL;
00275 
00276   oop blk = sender->receiver();
00277   guarantee(blk->is_block(), "should be a block");
00278   return parentOfBlock(blockClosureOop(blk));
00279 }
00280 
00281 RFrame* RecompilationPolicy::parentOfBlock(blockClosureOop blk) {
00282   if (blk->is_pure()) return NULL;
00283   
00284   contextOop ctx = blk->lexical_scope();
00285   assert(ctx->is_context(), "make sure we have a context");
00286 
00287   int* fp = ctx->parent_fp();
00288   if (fp == NULL) {
00289     return NULL;        // non-LIFO block
00290   } 
00291   // try to find context's RFrame
00292   RFrame* parent = stack->first();
00293   for (int i = 0; i < MaxRecompilationSearchLength; i++ ) {
00294     parent = senderOf(parent);
00295     if (!parent) break;
00296     frame fr = parent->fr();
00297     if (fr.fp() == fp) return parent;   // found it!
00298   }
00299   return NULL;    // parent not found
00300 }
00301 
00302 
00303 void RecompilationPolicy::printStack() {        // for debugging
00304   for (int i = 0; i < stack->length(); i++ ) stack->at(i)->print();
00305 }
00306 
00307 bool RecompilationPolicy::needRecompileCounter(Compiler* c) {
00308   if (!UseRecompilation) return false;
00309   if (c->version() == MaxVersions) return false;    // to prevent endless recompilation
00310   // also stop counting for "perfect" nmethods where nothing more can be optimized
00311   // NB: it is tempting to leave counters in very small methods (so that e.g. accessor functions 
00312   // still trigger counters), but that won't work if they're invoked from megamorphic
00313   // call sites --> put the counters in the caller, not the callee.
00314   return c->level() < MaxRecompilationLevels - 1;
00315 }
00316 
00317 bool RecompilationPolicy::shouldRecompileAfterUncommonTrap(nmethod* nm) {
00318   // called after nm encountered an uncommon trap; should it be recompiled into
00319   // less optimized form (without uncommon branches)?
00320   return nm->uncommon_trap_counter() >= UncommonRecompileLimit;
00321 }
00322 
00323 bool RecompilationPolicy::shouldRecompileUncommonNMethod(nmethod* nm) {
00324   assert(nm->isUncommonRecompiled(), "expected an uncommon nmethod");
00325   // nm looks like a recompilation candidate; can it really be optimized?
00326   // isUncommonRecompiled nmethods were created after the original nmethod encountered
00327   // too many "uncommon" cases.  Thus, the assumptions the compiler originally took
00328   // proved to be too aggressive.  In the uncommon-recompiled nmethod, there are
00329   // no uncommon branches, so it's slower.  But we don't want to reoptimize it too eagerly
00330   // because it needs to run long enough to accumulate type information that's truly
00331   // representative of its usage.  This method determines how to make that tradeoff.
00332   // The main idea is to back off exponentially each time we go through the cycle
00333   // of optimize -- uncommon recompile -- reoptimize.
00334   const int v = nm->version();
00335   const int c = nm->invocation_count();
00336   return  c >= uncommonNMethodInvocationLimit(v) ||
00337          (c >= UncommonInvocationLimit && nm->age() > uncommonNMethodAgeLimit(v));
00338 }
00339 
00340 int RecompilationPolicy::uncommonNMethodInvocationLimit(int version) {
00341   int n = UncommonInvocationLimit;
00342   for (int i = 0; i < version; i++) n *= UncommonAgeBackoffFactor;
00343   return n;
00344 }
00345 
00346 int RecompilationPolicy::uncommonNMethodAgeLimit(int version) {
00347   int n = NMethodAgeLimit;
00348   for (int i = 0; i < version; i++) n *= UncommonAgeBackoffFactor;
00349   return n;
00350 }
00351 
00352 #endif

Generated on Mon Oct 9 13:37:25 2006 for Strongtalk VM by  doxygen 1.4.7