1 /* 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "code/codeCache.hpp" 27 #include "code/nmethod.hpp" 28 #include "compiler/compileBroker.hpp" 29 #include "memory/resourceArea.hpp" 30 #include "oops/methodOop.hpp" 31 #include "runtime/atomic.hpp" 32 #include "runtime/compilationPolicy.hpp" 33 #include "runtime/mutexLocker.hpp" 34 #include "runtime/os.hpp" 35 #include "runtime/sweeper.hpp" 36 #include "runtime/vm_operations.hpp" 37 #include "trace/tracing.hpp" 38 #include "utilities/events.hpp" 39 #include "utilities/xmlstream.hpp" 40 41 #ifdef ASSERT 42 43 #define SWEEP(nm) record_sweep(nm, __LINE__) 44 // Sweeper logging code 45 class SweeperRecord { 46 public: 47 int traversal; 48 int invocation; 49 int compile_id; 50 long traversal_mark; 51 int state; 52 const char* kind; 53 address vep; 54 address uep; 55 int line; 56 57 void print() { 58 tty->print_cr("traversal = %d invocation = %d compile_id = %d %s uep = " PTR_FORMAT " vep = " 59 PTR_FORMAT " state = %d traversal_mark %d line = %d", 60 traversal, 61 invocation, 62 compile_id, 63 kind == NULL ? "" : kind, 64 uep, 65 vep, 66 state, 67 traversal_mark, 68 line); 69 } 70 }; 71 72 static int _sweep_index = 0; 73 static SweeperRecord* _records = NULL; 74 75 void NMethodSweeper::report_events(int id, address entry) { 76 if (_records != NULL) { 77 for (int i = _sweep_index; i < SweeperLogEntries; i++) { 78 if (_records[i].uep == entry || 79 _records[i].vep == entry || 80 _records[i].compile_id == id) { 81 _records[i].print(); 82 } 83 } 84 for (int i = 0; i < _sweep_index; i++) { 85 if (_records[i].uep == entry || 86 _records[i].vep == entry || 87 _records[i].compile_id == id) { 88 _records[i].print(); 89 } 90 } 91 } 92 } 93 94 void NMethodSweeper::report_events() { 95 if (_records != NULL) { 96 for (int i = _sweep_index; i < SweeperLogEntries; i++) { 97 // skip empty records 98 if (_records[i].vep == NULL) continue; 99 _records[i].print(); 100 } 101 for (int i = 0; i < _sweep_index; i++) { 102 // skip empty records 103 if (_records[i].vep == NULL) continue; 104 _records[i].print(); 105 } 106 } 107 } 108 109 void NMethodSweeper::record_sweep(nmethod* nm, int line) { 110 if (_records != NULL) { 111 _records[_sweep_index].traversal = _traversals; 112 _records[_sweep_index].traversal_mark = nm->_stack_traversal_mark; 113 _records[_sweep_index].invocation = _invocations; 114 _records[_sweep_index].compile_id = nm->compile_id(); 115 _records[_sweep_index].kind = nm->compile_kind(); 116 _records[_sweep_index].state = nm->_state; 117 _records[_sweep_index].vep = nm->verified_entry_point(); 118 _records[_sweep_index].uep = nm->entry_point(); 119 _records[_sweep_index].line = line; 120 121 _sweep_index = (_sweep_index + 1) % SweeperLogEntries; 122 } 123 } 124 #else 125 #define SWEEP(nm) 126 #endif 127 128 129 long NMethodSweeper::_traversals = 0; // No. of stack traversals performed 130 nmethod* NMethodSweeper::_current = NULL; // Current nmethod 131 int NMethodSweeper::_seen = 0 ; // No. of nmethods we have currently processed in current pass of CodeCache 132 int NMethodSweeper::_flushed_count = 0; // Nof. nmethods flushed in current sweep 133 int NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep 134 int NMethodSweeper::_marked_count = 0; // Nof. nmethods marked for reclaim in current sweep 135 136 volatile int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass 137 volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress. 138 139 jint NMethodSweeper::_locked_seen = 0; 140 jint NMethodSweeper::_not_entrant_seen_on_stack = 0; 141 bool NMethodSweeper::_rescan = false; 142 bool NMethodSweeper::_do_sweep = false; 143 bool NMethodSweeper::_was_full = false; 144 jint NMethodSweeper::_advise_to_sweep = 0; 145 jlong NMethodSweeper::_last_was_full = 0; 146 uint NMethodSweeper::_highest_marked = 0; 147 long NMethodSweeper::_was_full_traversal = 0; 148 149 int NMethodSweeper::_number_of_flushes = 0; // Total of full traversals caused by full cache 150 int NMethodSweeper::_total_nof_methods_reclaimed = 0; 151 long NMethodSweeper::_total_time_sweeping = 0; 152 long NMethodSweeper::_total_time_this_sweep = 0; 153 long NMethodSweeper::_peak_sweep_time = 0; 154 long NMethodSweeper::_peak_sweep_fraction_time = 0; 155 long NMethodSweeper::_total_disconnect_time = 0; 156 long NMethodSweeper::_peak_disconnect_time = 0; 157 158 class MarkActivationClosure: public CodeBlobClosure { 159 public: 160 virtual void do_code_blob(CodeBlob* cb) { 161 // If we see an activation belonging to a non_entrant nmethod, we mark it. 162 if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) { 163 ((nmethod*)cb)->mark_as_seen_on_stack(); 164 } 165 } 166 }; 167 static MarkActivationClosure mark_activation_closure; 168 169 void NMethodSweeper::scan_stacks() { 170 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint"); 171 if (!MethodFlushing) return; 172 _do_sweep = true; 173 174 // No need to synchronize access, since this is always executed at a 175 // safepoint. If we aren't in the middle of scan and a rescan 176 // hasn't been requested then just return. If UseCodeCacheFlushing is on and 177 // code cache flushing is in progress, don't skip sweeping to help make progress 178 // clearing space in the code cache. 179 if ((_current == NULL && !_rescan) && !(UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs())) { 180 _do_sweep = false; 181 return; 182 } 183 184 // Make sure CompiledIC_lock in unlocked, since we might update some 185 // inline caches. If it is, we just bail-out and try later. 186 if (CompiledIC_lock->is_locked() || Patching_lock->is_locked()) return; 187 188 // Check for restart 189 assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid"); 190 if (_current == NULL) { 191 _seen = 0; 192 _invocations = NmethodSweepFraction; 193 _current = CodeCache::first_nmethod(); 194 _traversals += 1; 195 _total_time_this_sweep = 0; 196 197 if (PrintMethodFlushing) { 198 tty->print_cr("### Sweep: stack traversal %d", _traversals); 199 } 200 Threads::nmethods_do(&mark_activation_closure); 201 202 // reset the flags since we started a scan from the beginning. 203 _rescan = false; 204 _locked_seen = 0; 205 _not_entrant_seen_on_stack = 0; 206 } 207 208 if (UseCodeCacheFlushing) { 209 if (!CodeCache::needs_flushing()) { 210 // scan_stacks() runs during a safepoint, no race with setters 211 _advise_to_sweep = 0; 212 } 213 214 if (was_full()) { 215 // There was some progress so attempt to restart the compiler 216 jlong now = os::javaTimeMillis(); 217 jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; 218 jlong curr_interval = now - _last_was_full; 219 if ((!CodeCache::needs_flushing()) && (curr_interval > max_interval)) { 220 CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); 221 set_was_full(false); 222 223 // Update the _last_was_full time so we can tell how fast the 224 // code cache is filling up 225 _last_was_full = os::javaTimeMillis(); 226 227 log_sweep("restart_compiler"); 228 } 229 } 230 } 231 } 232 233 void NMethodSweeper::possibly_sweep() { 234 assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); 235 if ((!MethodFlushing) || (!_do_sweep)) return; 236 237 if (_invocations > 0) { 238 // Only one thread at a time will sweep 239 jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 ); 240 if (old != 0) { 241 return; 242 } 243 #ifdef ASSERT 244 if (LogSweeper && _records == NULL) { 245 // Create the ring buffer for the logging code 246 _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC); 247 memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries); 248 } 249 #endif 250 if (_invocations > 0) { 251 sweep_code_cache(); 252 _invocations--; 253 } 254 _sweep_started = 0; 255 } 256 } 257 258 void NMethodSweeper::sweep_code_cache() { 259 260 long sweep_start_counter, sweep_end_counter; 261 long sweep_time; 262 sweep_start_counter = os::elapsed_counter(); 263 264 _flushed_count = 0; 265 _zombified_count = 0; 266 _marked_count = 0; 267 268 if (PrintMethodFlushing && Verbose) { 269 tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations); 270 } 271 272 // We want to visit all nmethods after NmethodSweepFraction 273 // invocations so divide the remaining number of nmethods by the 274 // remaining number of invocations. This is only an estimate since 275 // the number of nmethods changes during the sweep so the final 276 // stage must iterate until it there are no more nmethods. 277 int todo = (CodeCache::nof_nmethods() - _seen) / _invocations; 278 279 assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); 280 assert(!CodeCache_lock->owned_by_self(), "just checking"); 281 282 { 283 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 284 285 // The last invocation iterates until there are no more nmethods 286 for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) { 287 if (SafepointSynchronize::is_synchronizing()) { // Safepoint request 288 if (PrintMethodFlushing && Verbose) { 289 tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _invocations); 290 } 291 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 292 293 assert(Thread::current()->is_Java_thread(), "should be java thread"); 294 JavaThread* thread = (JavaThread*)Thread::current(); 295 ThreadBlockInVM tbivm(thread); 296 thread->java_suspend_self(); 297 } 298 // Since we will give up the CodeCache_lock, always skip ahead 299 // to the next nmethod. Other blobs can be deleted by other 300 // threads but nmethods are only reclaimed by the sweeper. 301 nmethod* next = CodeCache::next_nmethod(_current); 302 303 // Now ready to process nmethod and give up CodeCache_lock 304 { 305 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 306 process_nmethod(_current); 307 } 308 _seen++; 309 _current = next; 310 } 311 } 312 313 assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache"); 314 315 if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) { 316 // we've completed a scan without making progress but there were 317 // nmethods we were unable to process either because they were 318 // locked or were still on stack. We don't have to aggresively 319 // clean them up so just stop scanning. We could scan once more 320 // but that complicates the control logic and it's unlikely to 321 // matter much. 322 if (PrintMethodFlushing) { 323 tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep"); 324 } 325 } 326 327 sweep_end_counter = os::elapsed_counter(); 328 sweep_time = sweep_end_counter - sweep_start_counter; 329 _total_time_sweeping += sweep_time; 330 _total_time_this_sweep += sweep_time; 331 _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time); 332 _total_nof_methods_reclaimed += _flushed_count; 333 334 EventSweepCodeCache event(UNTIMED); 335 if (event.should_commit()) { 336 event.set_starttime(sweep_start_counter); 337 event.set_endtime(sweep_end_counter); 338 event.set_sweepIndex(_traversals); 339 event.set_sweepFractionIndex(NmethodSweepFraction - _invocations + 1); 340 event.set_sweptCount(todo); 341 event.set_flushedCount(_flushed_count); 342 event.set_markedCount(_marked_count); 343 event.set_zombifiedCount(_zombified_count); 344 event.commit(); 345 } 346 347 #ifdef ASSERT 348 if(PrintMethodFlushing) { 349 tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _invocations, (jlong)sweep_time); 350 } 351 #endif 352 353 if (_invocations == 1) { 354 _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep); 355 log_sweep("finished"); 356 } 357 } 358 359 class NMethodMarker: public StackObj { 360 private: 361 CompilerThread* _thread; 362 public: 363 NMethodMarker(nmethod* nm) { 364 _thread = CompilerThread::current(); 365 _thread->set_scanned_nmethod(nm); 366 } 367 ~NMethodMarker() { 368 _thread->set_scanned_nmethod(NULL); 369 } 370 }; 371 372 373 void NMethodSweeper::process_nmethod(nmethod *nm) { 374 assert(!CodeCache_lock->owned_by_self(), "just checking"); 375 376 // Make sure this nmethod doesn't get unloaded during the scan, 377 // since the locks acquired below might safepoint. 378 NMethodMarker nmm(nm); 379 380 SWEEP(nm); 381 382 // Skip methods that are currently referenced by the VM 383 if (nm->is_locked_by_vm()) { 384 // But still remember to clean-up inline caches for alive nmethods 385 if (nm->is_alive()) { 386 // Clean-up all inline caches that points to zombie/non-reentrant methods 387 MutexLocker cl(CompiledIC_lock); 388 nm->cleanup_inline_caches(); 389 SWEEP(nm); 390 } else { 391 _locked_seen++; 392 SWEEP(nm); 393 } 394 return; 395 } 396 397 if (nm->is_zombie()) { 398 // If it is first time, we see nmethod then we mark it. Otherwise, 399 // we reclame it. When we have seen a zombie method twice, we know that 400 // there are no inline caches that refer to it. 401 if (nm->is_marked_for_reclamation()) { 402 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); 403 if (PrintMethodFlushing && Verbose) { 404 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); 405 } 406 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 407 nm->flush(); 408 _flushed_count++; 409 } else { 410 if (PrintMethodFlushing && Verbose) { 411 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); 412 } 413 nm->mark_for_reclamation(); 414 _marked_count++; 415 _rescan = true; 416 SWEEP(nm); 417 } 418 } else if (nm->is_not_entrant()) { 419 // If there is no current activations of this method on the 420 // stack we can safely convert it to a zombie method 421 if (nm->can_not_entrant_be_converted()) { 422 if (PrintMethodFlushing && Verbose) { 423 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm); 424 } 425 nm->make_zombie(); 426 _zombified_count++; 427 _rescan = true; 428 SWEEP(nm); 429 } else { 430 // Still alive, clean up its inline caches 431 MutexLocker cl(CompiledIC_lock); 432 nm->cleanup_inline_caches(); 433 // we coudn't transition this nmethod so don't immediately 434 // request a rescan. If this method stays on the stack for a 435 // long time we don't want to keep rescanning the code cache. 436 _not_entrant_seen_on_stack++; 437 SWEEP(nm); 438 } 439 } else if (nm->is_unloaded()) { 440 // Unloaded code, just make it a zombie 441 if (PrintMethodFlushing && Verbose) 442 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); 443 444 if (nm->is_osr_method()) { 445 // No inline caches will ever point to osr methods, so we can just remove it 446 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 447 SWEEP(nm); 448 nm->flush(); 449 _flushed_count++; 450 } else { 451 nm->make_zombie(); 452 _zombified_count++; 453 _rescan = true; 454 SWEEP(nm); 455 } 456 } else { 457 assert(nm->is_alive(), "should be alive"); 458 459 if (UseCodeCacheFlushing) { 460 if ((nm->method()->code() != nm) && !(nm->is_locked_by_vm()) && !(nm->is_osr_method()) && 461 (_traversals > _was_full_traversal+2) && (((uint)nm->compile_id()) < _highest_marked) && 462 CodeCache::needs_flushing()) { 463 // This method has not been called since the forced cleanup happened 464 nm->make_not_entrant(); 465 } 466 } 467 468 // Clean-up all inline caches that points to zombie/non-reentrant methods 469 MutexLocker cl(CompiledIC_lock); 470 nm->cleanup_inline_caches(); 471 SWEEP(nm); 472 } 473 } 474 475 // Code cache unloading: when compilers notice the code cache is getting full, 476 // they will call a vm op that comes here. This code attempts to speculatively 477 // unload the oldest half of the nmethods (based on the compile job id) by 478 // saving the old code in a list in the CodeCache. Then 479 // execution resumes. If a method so marked is not called by the second sweeper 480 // stack traversal after the current one, the nmethod will be marked non-entrant and 481 // got rid of by normal sweeping. If the method is called, the methodOop's 482 // _code field is restored and the methodOop/nmethod 483 // go back to their normal state. 484 void NMethodSweeper::handle_full_code_cache(bool is_full) { 485 // Only the first one to notice can advise us to start early cleaning 486 if (!is_full){ 487 jint old = Atomic::cmpxchg( 1, &_advise_to_sweep, 0 ); 488 if (old != 0) { 489 return; 490 } 491 } 492 493 if (is_full) { 494 // Since code cache is full, immediately stop new compiles 495 bool did_set = CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); 496 if (!did_set){ 497 // only the first to notice can start the cleaning, 498 // others will go back and block 499 return; 500 } 501 set_was_full(true); 502 503 // If we run out within MinCodeCacheFlushingInterval of the last unload time, give up 504 jlong now = os::javaTimeMillis(); 505 jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; 506 jlong curr_interval = now - _last_was_full; 507 if (curr_interval < max_interval) { 508 _rescan = true; 509 log_sweep("disable_compiler", "flushing_interval='" UINT64_FORMAT "'", 510 curr_interval/1000); 511 return; 512 } 513 } 514 515 VM_HandleFullCodeCache op(is_full); 516 VMThread::execute(&op); 517 518 // rescan again as soon as possible 519 _rescan = true; 520 } 521 522 void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) { 523 // If there was a race in detecting full code cache, only run 524 // one vm op for it or keep the compiler shut off 525 526 long disconnect_start_counter; 527 long disconnect_end_counter; 528 long disconnect_time; 529 530 if ((!was_full()) && (is_full)) { 531 if (!CodeCache::needs_flushing()) { 532 log_sweep("restart_compiler"); 533 CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); 534 return; 535 } 536 } 537 538 disconnect_start_counter = os::elapsed_counter(); 539 540 // Traverse the code cache trying to dump the oldest nmethods 541 uint curr_max_comp_id = CompileBroker::get_compilation_id(); 542 uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked; 543 log_sweep("start_cleaning"); 544 545 nmethod* nm = CodeCache::alive_nmethod(CodeCache::first()); 546 jint disconnected = 0; 547 jint made_not_entrant = 0; 548 while ((nm != NULL)){ 549 uint curr_comp_id = nm->compile_id(); 550 551 // OSR methods cannot be flushed like this. Also, don't flush native methods 552 // since they are part of the JDK in most cases 553 if (nm->is_in_use() && (!nm->is_osr_method()) && (!nm->is_locked_by_vm()) && 554 (!nm->is_native_method()) && ((curr_comp_id < flush_target))) { 555 556 if ((nm->method()->code() == nm)) { 557 // This method has not been previously considered for 558 // unloading or it was restored already 559 CodeCache::speculatively_disconnect(nm); 560 disconnected++; 561 } else if (nm->is_speculatively_disconnected()) { 562 // This method was previously considered for preemptive unloading and was not called since then 563 CompilationPolicy::policy()->delay_compilation(nm->method()); 564 nm->make_not_entrant(); 565 made_not_entrant++; 566 } 567 568 if (curr_comp_id > _highest_marked) { 569 _highest_marked = curr_comp_id; 570 } 571 } 572 nm = CodeCache::alive_nmethod(CodeCache::next(nm)); 573 } 574 575 log_sweep("stop_cleaning", 576 "disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'", 577 disconnected, made_not_entrant); 578 579 // Shut off compiler. Sweeper will start over with a new stack scan and 580 // traversal cycle and turn it back on if it clears enough space. 581 if (was_full()) { 582 _last_was_full = os::javaTimeMillis(); 583 CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); 584 } 585 586 disconnect_end_counter = os::elapsed_counter(); 587 disconnect_time = disconnect_end_counter - disconnect_start_counter; 588 _total_disconnect_time += disconnect_time; 589 _peak_disconnect_time = MAX2(disconnect_time, _peak_disconnect_time); 590 591 EventCleanCodeCache event(UNTIMED); 592 if (event.should_commit()) { 593 event.set_starttime(disconnect_start_counter); 594 event.set_endtime(disconnect_end_counter); 595 event.set_disconnectedCount(disconnected); 596 event.set_madeNonEntrantCount(made_not_entrant); 597 event.commit(); 598 } 599 _number_of_flushes++; 600 601 // After two more traversals the sweeper will get rid of unrestored nmethods 602 _was_full_traversal = _traversals; 603 #ifdef ASSERT 604 605 if(PrintMethodFlushing && Verbose) { 606 tty->print_cr("### sweeper: unload time: " INT64_FORMAT, (jlong)disconnect_time); 607 } 608 #endif 609 } 610 611 612 // Print out some state information about the current sweep and the 613 // state of the code cache if it's requested. 614 void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { 615 if (PrintMethodFlushing) { 616 stringStream s; 617 // Dump code cache state into a buffer before locking the tty, 618 // because log_state() will use locks causing lock conflicts. 619 CodeCache::log_state(&s); 620 621 ttyLocker ttyl; 622 tty->print("### sweeper: %s ", msg); 623 if (format != NULL) { 624 va_list ap; 625 va_start(ap, format); 626 tty->vprint(format, ap); 627 va_end(ap); 628 } 629 tty->print_cr(s.as_string()); 630 } 631 632 if (LogCompilation && (xtty != NULL)) { 633 stringStream s; 634 // Dump code cache state into a buffer before locking the tty, 635 // because log_state() will use locks causing lock conflicts. 636 CodeCache::log_state(&s); 637 638 ttyLocker ttyl; 639 xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count()); 640 if (format != NULL) { 641 va_list ap; 642 va_start(ap, format); 643 xtty->vprint(format, ap); 644 va_end(ap); 645 } 646 xtty->print(s.as_string()); 647 xtty->stamp(); 648 xtty->end_elem(); 649 } 650 }