00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025
00026 #ifdef DELTA_COMPILER
00027
00028 # include "incls/_zone.cpp.incl"
00029
00030 # define LRU_RESOLUTION 16
00031
00032 # define LRU_RETIREMENT_AGE 10
00033 # define LRU_MAX_VISITED min(numberOfNMethods(), LRUMaxVisited)
00034
00035 # define LRU_MAX_RECLAIMED 250000
00036
00037 # define LRU_CUTOFF 32
00038 # define LRU_SMALL_BOOST 3
00039
00040
00041 # define COMPACT_OVERHEAD 0.05
00042
00043
00044
00045
00046
00047
00048
00049 # define CODE_BLOCK 64
00050 # define PIC_BLOCK 32
00051 # define FREE 20
00052
00053 # define StubBlock 16
00054 # define StubFree 20
00055
00056 # define MaxExtFrag 0.05
00057
00058 # define FOR_ALL_NMETHODS(var) \
00059 for (nmethod *var = first_nm(); var; var = next_nm(var))
00060
00061
00062 # define FOR_ALL_PICS(var) \
00063 for (PIC *var = first_pic(); var; var = next_pic(var))
00064
00065 inline int roundSize(int s, int blockSize) {
00066 return (s + blockSize - 1) / blockSize * blockSize;
00067 }
00068
00069 LRUcount* LRUtable;
00070 int* LRUflag;
00071
00072 static int LRUtime;
00073
00074
00075
00076 void sweepTrigger() {
00077 if (UseLRUInterrupts) {
00078 Universe::code->_needsSweep = true;
00079
00080
00081 };
00082 }
00083
00084 static void idOverflowError(int delta) {
00085 Unused(delta);
00086
00087 fatal("zone: nmethod ID table overflowed");
00088 }
00089
00090 zone::zone(int& size) {
00091 methodHeap = new Heap(Universe::current_sizes.code_size, CODE_BLOCK);
00092 picHeap = new Heap(Universe::current_sizes.pic_heap_size, PIC_BLOCK);
00093
00094 methodTable = new codeTable(codeTableSize);
00095
00096
00097 LRUtable = (LRUcount*)LRUflag;
00098 clear();
00099
00100
00101
00102 }
00103
00104 void zone::clear() {
00105 methodHeap->clear();
00106 picHeap->clear();
00107 methodTable->clear();
00108
00109 LRUhand = NULL;
00110 LRUtime = 0;
00111 jump_table()->init();
00112 _needsCompaction = _needsSweep = false;
00113 compactTime = 0; compactDuration = 1; minFreeFrac = 0.05;
00114 }
00115
00116 int zone::nextNMethodID() { return jump_table()->peekID(); }
00117
00118 nmethod* zone::allocate(int size) {
00119
00120
00121
00122 if (needsSweep()) doSweep();
00123
00124 nmethod* n = (nmethod*) methodHeap->allocate(size);
00125
00126 if (n == NULL) {
00127
00128 flushZombies();
00129 n = (nmethod*) methodHeap->allocate(size);
00130 if (n == NULL) {
00131 print();
00132 fatal("cannot allocate enough space for nmethod");
00133 }
00134 }
00135
00136 verify_if_often();
00137 return n;
00138 }
00139
00140 int zone::used() {
00141 return methodHeap->usedBytes();
00142 }
00143
00144 void zone::verify_if_often() {
00145 if (VerifyZoneOften) {
00146 methodHeap->verify();
00147 }
00148 }
00149
00150 void zone::flush() {
00151 ResourceMark rm;
00152 TraceTime t("Flushing method cache...", PrintCodeReclamation);
00153 EventMarker em("flushing method cache");
00154
00155
00156 Processes::deoptimize_all();
00157
00158 FOR_ALL_NMETHODS(p) { p->makeZombie(true); }
00159 flushZombies();
00160
00161 verify_if_often();
00162 }
00163
00164
00165 int zone::findReplCandidates(int needed) {
00166
00167
00168 # ifdef NOT_IMPLEMENTED
00169 int reclaimed = 0, iter = 0;
00170 while (iter++ < LRU_RETIREMENT_AGE && reclaimed < needed) {
00171 int vis, recl;
00172 int limit = numberOfNMethods();
00173 int newTime = sweeper(limit, needed, &vis, &recl);
00174 reclaimed += recl;
00175 if (recl < needed && newTime > LRUtime + 1) {
00176
00177 assert(vis == limit, "should have visited them all");
00178 LRUtime = newTime - 1;
00179 if (PrintLRUSweep) lprintf("\n*forced new LRU time: %ld", LRUtime);
00180 }
00181 }
00182 return reclaimed;
00183 #endif
00184 return 0;
00185 }
00186
00187
00188 int zone::flushNextMethod(int needed) {
00189 int freed = 0;
00190 Unimplemented();
00191 return freed;
00192 }
00193
00194 void moveInsts(char* from, char* to, int size) {
00195 Unused(size);
00196 nmethod* n = (nmethod*) from;
00197 nmethod* nTo = (nmethod*)to;
00198
00199 char* n1 = n->insts();
00200 char* n2 = n->instsEnd();
00201 n->moveTo(to, (char*)n->locsEnd() - (char*)n);
00202 if (Universe::code->LRUhand == n) Universe::code->LRUhand = nTo;
00203 }
00204
00205 class ConvertBlockClosure : public ObjectClosure {
00206 public:
00207 void do_object(memOop obj) {
00208 if (obj->is_block() && blockClosureOop(obj)->isCompiledBlock()) {
00209 blockClosureOop(obj)->deoptimize();
00210 }
00211 }
00212 };
00213
00214 void zone::flushZombies() {
00215
00216
00217
00218
00219
00220 lookupCache::flush();
00221
00222
00223 Universe::flush_inline_caches_in_methods();
00224 clear_inline_caches();
00225
00226
00227 ConvertBlockClosure bl;
00228 Universe::object_iterate(&bl);
00229
00230 FOR_ALL_NMETHODS(p) {
00231 if (p->isZombie()) {
00232 p->flush();
00233 }
00234 }
00235 }
00236
00237 void zone::flushUnused() {
00238
00239
00240
00241 FOR_ALL_NMETHODS(p) {
00242
00243
00244 p->makeZombie(true);
00245 }
00246 flushZombies();
00247 flushICache();
00248
00249 }
00250
00251 void zone::adjustPolicy() {
00252
00253
00254
00255
00256
00257 # ifdef NOT_IMPLEMENTED
00258 if (DontUseAnyTimer) return;
00259 float timeSinceLast = cpuTimer->tickNo - compactTime;
00260 float overhead = compactDuration / timeSinceLast;
00261 if (overhead > COMPACT_OVERHEAD) {
00262 float currentFreeFrac = 1 - float(iZone->usedBytes()) / iZone->capacity();
00263 minFreeFrac = min(float(minFreeFrac * 1.5), float(minFreeFrac + 0.05));
00264 if (PrintCodeReclamation) {
00265 printf("(compact overhead %3.1f%%: increasing minFreeFrac to %3.1f%%) ",
00266 overhead *100, minFreeFrac * 100);
00267 }
00268 } else if (overhead < COMPACT_OVERHEAD / 2) {
00269 minFreeFrac = max(float(minFreeFrac / 1.5), float(minFreeFrac - 0.05));
00270 if (PrintCodeReclamation) {
00271 printf("(compact overhead %3.1f%%: decreasing minFreeFrac to %3.1f%%) ",
00272 overhead *100, minFreeFrac * 100);
00273 }
00274 }
00275 int minFree = int(iZone->capacity() * minFreeFrac);
00276 while (1) {
00277 int toFlush = minFree - (iZone->capacity() - iZone->usedBytes());
00278 if (toFlush <= 0) break;
00279 flushNextMethod(LRU_MAX_RECLAIMED);
00280 }
00281 compactTime = cpuTimer->tickNo;
00282 # endif
00283 }
00284
00285 # define LRU_MAX_RECLAIMED 250000
00286 # define LRUMaxVisited 150
00287 void zone::doSweep() { sweeper(LRUMaxVisited, LRU_MAX_RECLAIMED); }
00288
00289 void zone::doWork() {
00290 if (needsSweep()) doSweep();
00291 if (needsCompaction()) compact();
00292 }
00293
00294 void zone::compact(bool forced) {
00295
00296
00297
00298 TraceTime t("*compacting nmethod cache...", PrintCodeReclamation);
00299 EventMarker em("compacting zone");
00300
00301
00302 flushZombies();
00303 char* firstFree = NULL;
00304 if (!forced) adjustPolicy();
00305 if (needsCompaction()) {
00306 if (PrintCodeReclamation) std->print("I");
00307 firstFree = methodHeap->compact(moveInsts);
00308 }
00309
00310 flushICache();
00311
00312 verify_if_often();
00313 _needsCompaction = false;
00314
00315 }
00316
00317 void zone::free(nmethod* nm) {
00318 verify_if_often();
00319 if (LRUhand == nm) LRUhand = next_nm(nm);
00320 methodHeap->deallocate(nm, nm->size());
00321 verify_if_often();
00322 }
00323
00324 void zone::addToCodeTable(nmethod* nm) {
00325 methodTable->add(nm);
00326 }
00327
00328 void zone::clear_inline_caches() {
00329 TraceTime t("*flushing inline caches...", PrintInlineCacheInvalidation);
00330 EventMarker em("flushing inline caches");
00331
00332 FOR_ALL_NMETHODS(p) {
00333 p->clear_inline_caches();
00334 }
00335
00336 flushICache();
00337 }
00338
00339 void zone::cleanup_inline_caches() {
00340 TraceTime t("*cleaning inline caches...", PrintInlineCacheInvalidation);
00341 EventMarker em("cleaning inline caches");
00342
00343 FOR_ALL_NMETHODS(p) {
00344 p->cleanup_inline_caches();
00345 }
00346
00347 flushICache();
00348 }
00349
00350 inline int retirementAge(nmethod* n) {
00351 int delta = LRU_RETIREMENT_AGE;
00352 if (n->instsLen() <= LRU_CUTOFF)
00353 delta = max(delta, LRU_RETIREMENT_AGE * LRU_SMALL_BOOST);
00354 return n->lastUsed() + delta;
00355 }
00356
00357 void zone::verify() {
00358 methodTable->verify();
00359 int n = 0;
00360 FOR_ALL_NMETHODS(p) {
00361 n++;
00362 p->verify();
00363 }
00364 if (n != numberOfNMethods())
00365 error("zone: inconsistent usedIDs value - should be %ld, is %ld",
00366 n, numberOfNMethods());
00367 methodHeap->verify();
00368 jump_table()->verify();
00369 }
00370
00371
00372 void zone::switch_pointers(oop from, oop to) {
00373 Unimplemented();
00374 }
00375
00376 void zone::oops_do(void f(oop*)) {
00377 FOR_ALL_NMETHODS(nm) {
00378 nm->oops_do(f);
00379 }
00380
00381 FOR_ALL_PICS(pic) {
00382 pic->oops_do(f);
00383 }
00384 }
00385
00386 void zone::nmethods_do(void f(nmethod* nm)) {
00387 FOR_ALL_NMETHODS(p) {
00388 f(p);
00389 }
00390 }
00391
00392 void zone::PICs_do(void f(PIC* pic)) {
00393 FOR_ALL_PICS(p) {
00394 f(p);
00395 }
00396 }
00397
00398 # define NMLINE(format, n, ntot, ntot2) \
00399 std->print(format, (n), 100.0 * (n) / (ntot), 100.0 * (n) / (ntot2))
00400
00401 class nmsizes {
00402 int n, insts, locs, scopes;
00403 public:
00404 nmsizes() {
00405 n = insts = locs = scopes = 0; }
00406
00407 int total() {
00408 return n * sizeof(nmethod)+ insts + locs + scopes; }
00409
00410 bool isEmpty() { return n == 0; }
00411
00412 void print(char* name, nmsizes& tot) {
00413 int bigTotal = tot.total();
00414 int myTotal = total();
00415 if (! isEmpty()) {
00416 std->print("%-13s (%ld methods): ", name, n);
00417 NMLINE("headers = %ld (%2.0f%%/%2.0f%%); ", n*sizeof(nmethod),
00418 myTotal, bigTotal);
00419 NMLINE("insts = %ld (%2.0f%%/%2.0f%%);\n", insts, myTotal, bigTotal);
00420 NMLINE("\tlocs = %ld (%2.0f%%/%2.0f%%); ", locs, myTotal, bigTotal);
00421 NMLINE("scopes = %ld (%2.0f%%/%2.0f%%);\n", scopes, myTotal, bigTotal);
00422 NMLINE("\ttotal = %ld (%2.0f%%/%2.0f%%)\n", myTotal, myTotal, bigTotal);
00423 }
00424 }
00425
00426 void print(char* title, int t) {
00427 std->print_cr(" %3d %s nmethods %2d%% = %4dK (hdr %2d%%, inst %2d%%, locs %2d%%, debug %2d%%)",
00428 n,
00429 title,
00430 total() * 100 / t,
00431 total() / K,
00432 n * sizeof(nmethod) * 100 / total(),
00433 insts * 100 / total(),
00434 locs * 100 / total(),
00435 scopes * 100 / total());
00436 }
00437
00438 void add(nmethod* nm) {
00439 n++;
00440 insts += nm->instsLen();
00441 locs += nm->locsLen();
00442 scopes += nm->scopes()->length();
00443 }
00444 };
00445
00446 void zone::print() {
00447 nmsizes nms;
00448 nmsizes zombies;
00449 int uncommon = 0;
00450
00451 FOR_ALL_NMETHODS(p) {
00452 if (p->isZombie()) {
00453 zombies.add(p);
00454 } else {
00455 nms.add(p);
00456 if (p->isUncommonRecompiled()) uncommon++;
00457 }
00458 }
00459
00460 std->print_cr("Zone:");
00461
00462 if (!nms.isEmpty()) {
00463 std->print_cr(" Code (%dK, %d%% used)", methodHeap->capacity() / K, (methodHeap->usedBytes() * 100) / methodHeap->capacity());
00464 nms.print("live", methodHeap->capacity());
00465 }
00466 if (uncommon) {
00467 std->print_cr("(%d live uncommon nmethods)", uncommon);
00468 }
00469 if (!zombies.isEmpty()) {
00470 zombies.print("dead", methodHeap->capacity());
00471 std->print_cr(" PICs (%dK, %d%% used)", picHeap->capacity() / K, (picHeap->usedBytes() * 100) / picHeap->capacity());
00472 }
00473
00474 int n = 0;
00475 int insts = 0;
00476 FOR_ALL_PICS(pic) {
00477 n++;
00478 insts += pic->code_size();
00479 }
00480 int total = insts + n * sizeof(PIC);
00481
00482 if (n > 0) {
00483 std->print_cr(" %3d entries = %dK (hdr %2d%%, inst %2d%%)",
00484 n,
00485 total / K,
00486 n * sizeof(PIC) * 100 / total,
00487 insts * 100 / total);
00488 }
00489 }
00490
00491 struct nm_hist_elem{
00492 nmethod* nm;
00493 int count;
00494 int size;
00495 int sic_count;
00496 int sic_size;
00497 };
00498
00499 static int compareOop(const void *m1, const void *m2) {
00500 ResourceMark rm;
00501 struct nm_hist_elem *nmethod1 = (struct nm_hist_elem *) m1;
00502 struct nm_hist_elem *nmethod2 = (struct nm_hist_elem *) m2;
00503 return nmethod2->nm->method() - nmethod1->nm->method();
00504 }
00505
00506 static int compareCount(const void *m1, const void *m2) {
00507 struct nm_hist_elem *nmethod1 = (struct nm_hist_elem *) m1;
00508 struct nm_hist_elem *nmethod2 = (struct nm_hist_elem *) m2;
00509 return nmethod2->count - nmethod1->count;
00510 }
00511
00512 void zone::print_nmethod_histogram(int size) {
00513 # ifdef NOT_IMPLEMENTED
00514 ResourceMark rm;
00515 nm_hist_elem* hist_array = NEW_RESOURCE_ARRAY(nm_hist_elem, numberOfNMethods());
00516
00517 int* compiled_nmethods = NEW_RESOURCE_ARRAY(int, numberOfNMethods());
00518
00519 int n = 0;
00520 FOR_ALL_NMETHODS(p) {
00521 if (!p->isAccess() && !p->isZombie()) {
00522 hist_array[n].nm = p;
00523 hist_array[n].size = p->instsLen() +
00524 p->locsLen() +
00525 p->depsLen +
00526 p->scopes->length();
00527 n++;
00528 }
00529 }
00530
00531 qsort(hist_array, n, sizeof(nm_hist_elem), compareOop);
00532
00533 int i = 0;
00534 for (i = 0; i < n; i++) compiled_nmethods[i] = 0;
00535
00536 i = 0;
00537 int out = 0;
00538 while (i < n) {
00539 int counter = 1;
00540 int all_size = 0;
00541 int sic_counter = 0;
00542 int sic_size = 0;
00543
00544 oop method = hist_array[i].nm->method();
00545 if (hist_array[i].nm->flags.compiler == nm_new) {
00546 sic_counter++;
00547 sic_size += hist_array[i].size;
00548 }
00549 all_size = hist_array[i].size;
00550
00551 i++;
00552
00553 while (i < n && method == hist_array[i].nm->method()) {
00554 if (hist_array[i].nm->flags.compiler == nm_sic) {
00555 sic_counter++;
00556 sic_size += hist_array[i].size;
00557 }
00558 all_size += hist_array[i].size;
00559 counter++; i++;
00560 }
00561 compiled_nmethods[counter]++;
00562 if (counter > size) {
00563 hist_array[out] = hist_array[i-1];
00564 hist_array[out].count = counter;
00565 hist_array[out].size = all_size;
00566 hist_array[out].sic_count = sic_counter;
00567 hist_array[out].sic_size = sic_size;
00568 out++;
00569 }
00570 }
00571
00572 qsort(hist_array, out, sizeof(nm_hist_elem), compareCount);
00573
00574 printf("\n# nm \t # methods \t%% acc.\n");
00575 int nm_count = 0;
00576 for (i = 0; i < n; i++) {
00577 if (compiled_nmethods[i] > 0) {
00578 nm_count += i * compiled_nmethods[i];
00579 printf("%5ld \t%5ld \t\t%3ld %%\n", i, compiled_nmethods[i],
00580 (nm_count*100)/n);
00581
00582 }
00583 }
00584
00585 printf( "\nList of methods with more than %d nmethods compiled.\n", size);
00586 printf( " ALL(#,Kb) Compiler(#,Kb) Method:\n");
00587 for (i = 0; i < out; i++) {
00588 printf("%4d,%-4d %4d,%-4d ",
00589 hist_array[i].count, hist_array[i].size / 1024,
00590 hist_array[i].sic_count, hist_array[i].sic_size / 1024);
00591 printName((methodKlass*) hist_array[i].nm->method()->klass(),
00592 hist_array[i].nm->key.selector);
00593 printf("\n");
00594 }
00595
00596 fflush(stdout);
00597 # endif
00598 }
00599
00600 bool zone::isDeltaPC(void* p) const {
00601 return methodHeap->contains(p)
00602 || picHeap->contains(p);
00603 }
00604
00605 nmethod* zone::findNMethod(void* start) const {
00606 nmethod* n;
00607 if (methodHeap->contains(start)) {
00608 n = (nmethod*)methodHeap->findStartOfBlock(start);
00609 assert((char*)start < (char*)n->locsEnd(), "found wrong nmethod");
00610 }
00611 assert(methodHeap->contains(n), "not in zone");
00612 assert(n->isNMethod(), "findNMethod didn't find nmethod");
00613 assert(n->encompasses(start), "doesn't encompass start");
00614 return n;
00615 }
00616
00617
00618 nmethod* zone::findNMethod_maybe(void* start) const {
00619
00620 if (!methodHeap->contains(start)) return NULL;
00621
00622 FOR_ALL_NMETHODS(p) {
00623 if (p->insts() > (char*)start) return NULL;
00624 if (p->instsEnd() > (char*)start) return p;
00625 }
00626 return NULL;
00627 }
00628
00629 void zone::mark_dependents_for_deoptimization() {
00630 ResourceMark rm;
00631 FOR_ALL_NMETHODS(nm) {
00632 if (nm->depends_on_invalid_klass()) {
00633 GrowableArray<nmethod*>* nms = nm->invalidation_family();
00634 for (int index = 0; index < nms->length(); index++) {
00635 nmethod* elem = nms->at(index);
00636 if (TraceApplyChange) {
00637 std->print("invalidating ");
00638 elem->print_value_on(std);
00639 std->cr();
00640 }
00641 elem->mark_for_deoptimization();
00642 }
00643 }
00644 }
00645 }
00646
00647 void zone::mark_all_for_deoptimization() {
00648 FOR_ALL_NMETHODS(nm) {
00649 nm->mark_for_deoptimization();
00650 }
00651 }
00652
00653 void zone::unmark_all_for_deoptimization() {
00654 FOR_ALL_NMETHODS(nm) nm->unmark_for_deoptimization();
00655 }
00656
00657 void zone::make_marked_nmethods_zombies() {
00658 FOR_ALL_NMETHODS(nm) {
00659 if (nm->is_marked_for_deoptimization()) {
00660 nm->makeZombie(true);
00661 }
00662 }
00663 }
00664
00665 char* zone::instsStart() { return methodHeap->startAddr(); };
00666 int zone::instsSize() { return methodHeap->capacity(); }
00667
00668 inline nmethod* zone::next_circular_nm(nmethod* nm) {
00669 nm = next_nm(nm);
00670 if (nm == NULL) nm = first_nm();
00671 return nm;
00672 }
00673
00674
00675
00676 int zone::sweeper(int maxVisit, int maxReclaim,
00677 int* nvisited, int* nbytesReclaimed) {
00678 # ifdef NOT_IMPLEMENTED
00679 EventMarker em("LRU sweep");
00680 ResourceMark rm;
00681
00682 timer tmr;
00683 int visited = 0;
00684 int nused = 0;
00685 int nbytes = 0;
00686 int nextTime = LRUtime + LRU_RETIREMENT_AGE;
00687 nmethod* first = first_nm();
00688 if (! first) return -1;
00689
00690 nmethod* p = LRUhand ? LRUhand : first;
00691 if (PrintLRUSweep || PrintLRUSweep2) {
00692 printf("*starting LRU sweep...");
00693 fflush(stdout);
00694 tmr.start();
00695 }
00696
00697 do {
00698 if (PrintLRUSweep2) printf("\n*inspecting %#lx (id %ld): ", p, p->id);
00699
00700 if ((p->isZombie() ||
00701 p->isDebug() ||
00702 p->codeTableLink.isEmpty() && !p->isUncommon()) &&
00703 p->frame_chain == NULL) {
00704
00705 if (PrintLRUSweep2) printf(" %s; flushed",
00706 p->isZombie() ? "zombie" :
00707 (p->isDebug() ? "debug" : "unreachable"));
00708 nbytes += iZone->sizeOfBlock(p);
00709 p->flush();
00710 } else if (p->isUsed()) {
00711
00712 nused++;
00713 if (PrintLRUSweep2) {
00714 printf("used");
00715 int diff = useCount[p->id] - p->oldCount;
00716 if (diff) printf(" %ld times", diff);
00717 }
00718 if (LRUDecayFactor > 1) {
00719 useCount[p->id] = int(useCount[p->id] / LRUDecayFactor);
00720 }
00721 p->oldCount = useCount[p->id];
00722 LRUtable[p->id].unused = true;
00723 LRUtable[p->id].lastUsed = LRUtime;
00724 if (p->zoneLink.notEmpty()) {
00725 if (PrintLRUSweep2) printf("; removed from replCandidates");
00726 p->zoneLink.remove();
00727 nbytes -= iZone->sizeOfBlock(p);
00728 }
00729 } else if (retirementAge(p) < LRUtime && p->zoneLink.isEmpty()) {
00730 if (PrintLRUSweep2) printf("added to replCandidates");
00731 replCandidates.add(&p->zoneLink);
00732 nbytes += iZone->sizeOfBlock(p);
00733 } else {
00734 int age = retirementAge(p);
00735 if (age < nextTime) {
00736 nextTime = age;
00737 }
00738 if (PrintLRUSweep2) {
00739 printf("unused (age %ld)", LRUtime - p->lastUsed());
00740 if (p->zoneLink.notEmpty())
00741 printf(" already scheduled for replacement");
00742 }
00743 }
00744
00745 nmethod* oldp = p;
00746 p = next_circular_nm(p);
00747 if (p < oldp) {
00748 LRUtime++;
00749
00750
00751 if (PrintLRUSweep2) printf("\n*new LRU time: %ld", LRUtime);
00752 }
00753 } while (++visited < maxVisit && nbytes < maxReclaim && p);
00754
00755 if (needsSweep() && LRUDecayFactor > 1) {
00756
00757 stubs->decay(LRUDecayFactor);
00758 }
00759
00760 LRUhand = p;
00761 _needsSweep = false;
00762 if (PrintLRUSweep || PrintLRUSweep2) {
00763 printf(" done: %ld/%ld visits, %ld bytes, %ld ms.\n",
00764 nused, visited, nbytes, tmr.time());
00765 fflush(stdout);
00766 }
00767 if (nvisited) *nvisited = visited;
00768 if (nbytesReclaimed) *nbytesReclaimed = nbytes;
00769 return nextTime;
00770 # endif
00771 return 0;
00772 }
00773
00774 int zone::LRU_time() { return LRUtime; }
00775
00776 void printAllNMethods() {
00777 for(nmethod* m = Universe::code->first_nm(); m != NULL; m = Universe::code->next_nm(m)) {
00778 if (!m->isZombie()) {
00779 m->scopes()->print_partition();
00780 }
00781 }
00782 }
00783
00784 #endif