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 #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)) ;
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
00058 RecompilerInliningPolicy p;
00059 RFrame* current = stack->at(0);
00060 RFrame* prev = NULL;
00061 RFrame* prevMethod = NULL;
00062 msg = NULL;
00063
00064 while (1) {
00065 if (current == NULL) {
00066
00067 current = prev;
00068 break;
00069 }
00070
00071 if ((msg = p.shouldInline(current)) != NULL) {
00072
00073 break;
00074 }
00075
00076
00077 RFrame* next = senderOrParentOf(current);
00078
00079 if (next) {
00080 if (next->num() > MaxRecompilationSearchLength) {
00081
00082 msg = "(don't go up any further: next > MaxRecompilationSearchLength)";
00083 break;
00084 }
00085 if (next->distance() > MaxInterpretedSearchLength) {
00086
00087 msg = "(don't go up any further: next > MaxInterpretedSearchLength)";
00088 break;
00089 }
00090 if (current->is_interpreted()) {
00091
00092
00093
00094
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
00129 if (current->is_blockMethod() && current->is_interpreted()) {
00130
00131
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
00153 msg = NULL;
00154 }
00155 }
00156 if (current == NULL) return;
00157
00158
00159
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
00166 if (k && running_nm && running_nm->is_method() && running_nm != newest_nm) {
00167
00168
00169
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
00181 if (nm->isUncommonRecompiled()) {
00182 if (RecompilationPolicy::shouldRecompileUncommonNMethod(nm)) {
00183 nm->makeOld();
00184 return NULL;
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
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
00219
00220
00221 if (rf->is_blockMethod()) {
00222 RFrame* parent = parentOf(rf);
00223 if (parent == NULL) {
00224
00225 fixBlockParent(rf);
00226 return senderOf(rf);
00227
00228
00229
00230
00231
00232 } else {
00233 if (parent->is_compiled() == rf->is_compiled()) {
00234
00235 if (CountParentLinksAsOne) parent->set_distance(rf->distance() + 1);
00236 return parent;
00237 } else {
00238 return senderOf(rf);
00239 }
00240 }
00241 } else if (rf->hasBlockArgs()) {
00242
00243
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
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
00256 return senderOf(rf);
00257 }
00258
00259 RFrame* RecompilationPolicy::parentOf(RFrame* rf) {
00260 assert(rf->is_blockMethod(), "shouldn't call");
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
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;
00290 }
00291
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;
00298 }
00299 return NULL;
00300 }
00301
00302
00303 void RecompilationPolicy::printStack() {
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;
00310
00311
00312
00313
00314 return c->level() < MaxRecompilationLevels - 1;
00315 }
00316
00317 bool RecompilationPolicy::shouldRecompileAfterUncommonTrap(nmethod* nm) {
00318
00319
00320 return nm->uncommon_trap_counter() >= UncommonRecompileLimit;
00321 }
00322
00323 bool RecompilationPolicy::shouldRecompileUncommonNMethod(nmethod* nm) {
00324 assert(nm->isUncommonRecompiled(), "expected an uncommon nmethod");
00325
00326
00327
00328
00329
00330
00331
00332
00333
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