1.1 --- a/src/share/vm/compiler/compileBroker.cpp Wed Oct 16 10:52:41 2013 +0200 1.2 +++ b/src/share/vm/compiler/compileBroker.cpp Tue Nov 05 17:38:04 2013 -0800 1.3 @@ -186,7 +186,7 @@ 1.4 CompileQueue* CompileBroker::_c1_method_queue = NULL; 1.5 CompileTask* CompileBroker::_task_free_list = NULL; 1.6 1.7 -GrowableArray<CompilerThread*>* CompileBroker::_method_threads = NULL; 1.8 +GrowableArray<CompilerThread*>* CompileBroker::_compiler_threads = NULL; 1.9 1.10 1.11 class CompilationLog : public StringEventLog { 1.12 @@ -587,9 +587,6 @@ 1.13 1.14 1.15 1.16 -// ------------------------------------------------------------------ 1.17 -// CompileQueue::add 1.18 -// 1.19 // Add a CompileTask to a CompileQueue 1.20 void CompileQueue::add(CompileTask* task) { 1.21 assert(lock()->owned_by_self(), "must own lock"); 1.22 @@ -626,6 +623,16 @@ 1.23 lock()->notify_all(); 1.24 } 1.25 1.26 +void CompileQueue::delete_all() { 1.27 + assert(lock()->owned_by_self(), "must own lock"); 1.28 + if (_first != NULL) { 1.29 + for (CompileTask* task = _first; task != NULL; task = task->next()) { 1.30 + delete task; 1.31 + } 1.32 + _first = NULL; 1.33 + } 1.34 +} 1.35 + 1.36 // ------------------------------------------------------------------ 1.37 // CompileQueue::get 1.38 // 1.39 @@ -634,22 +641,52 @@ 1.40 NMethodSweeper::possibly_sweep(); 1.41 1.42 MutexLocker locker(lock()); 1.43 - // Wait for an available CompileTask. 1.44 + // If _first is NULL we have no more compile jobs. There are two reasons for 1.45 + // having no compile jobs: First, we compiled everything we wanted. Second, 1.46 + // we ran out of code cache so compilation has been disabled. In the latter 1.47 + // case we perform code cache sweeps to free memory such that we can re-enable 1.48 + // compilation. 1.49 while (_first == NULL) { 1.50 - // There is no work to be done right now. Wait. 1.51 - if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() || CodeCache::needs_flushing())) { 1.52 - // During the emergency sweeping periods, wake up and sweep occasionally 1.53 - bool timedout = lock()->wait(!Mutex::_no_safepoint_check_flag, NmethodSweepCheckInterval*1000); 1.54 - if (timedout) { 1.55 + // Exit loop if compilation is disabled forever 1.56 + if (CompileBroker::is_compilation_disabled_forever()) { 1.57 + return NULL; 1.58 + } 1.59 + 1.60 + if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) { 1.61 + // Wait a certain amount of time to possibly do another sweep. 1.62 + // We must wait until stack scanning has happened so that we can 1.63 + // transition a method's state from 'not_entrant' to 'zombie'. 1.64 + long wait_time = NmethodSweepCheckInterval * 1000; 1.65 + if (FLAG_IS_DEFAULT(NmethodSweepCheckInterval)) { 1.66 + // Only one thread at a time can do sweeping. Scale the 1.67 + // wait time according to the number of compiler threads. 1.68 + // As a result, the next sweep is likely to happen every 100ms 1.69 + // with an arbitrary number of threads that do sweeping. 1.70 + wait_time = 100 * CICompilerCount; 1.71 + } 1.72 + bool timeout = lock()->wait(!Mutex::_no_safepoint_check_flag, wait_time); 1.73 + if (timeout) { 1.74 MutexUnlocker ul(lock()); 1.75 - // When otherwise not busy, run nmethod sweeping 1.76 NMethodSweeper::possibly_sweep(); 1.77 } 1.78 } else { 1.79 - // During normal operation no need to wake up on timer 1.80 - lock()->wait(); 1.81 + // If there are no compilation tasks and we can compile new jobs 1.82 + // (i.e., there is enough free space in the code cache) there is 1.83 + // no need to invoke the sweeper. As a result, the hotness of methods 1.84 + // remains unchanged. This behavior is desired, since we want to keep 1.85 + // the stable state, i.e., we do not want to evict methods from the 1.86 + // code cache if it is unnecessary. 1.87 + // We need a timed wait here, since compiler threads can exit if compilation 1.88 + // is disabled forever. We use 5 seconds wait time; the exiting of compiler threads 1.89 + // is not critical and we do not want idle compiler threads to wake up too often. 1.90 + lock()->wait(!Mutex::_no_safepoint_check_flag, 5*1000); 1.91 } 1.92 } 1.93 + 1.94 + if (CompileBroker::is_compilation_disabled_forever()) { 1.95 + return NULL; 1.96 + } 1.97 + 1.98 CompileTask* task = CompilationPolicy::policy()->select_task(this); 1.99 remove(task); 1.100 return task; 1.101 @@ -743,6 +780,10 @@ 1.102 void CompileBroker::compilation_init() { 1.103 _last_method_compiled[0] = '\0'; 1.104 1.105 + // No need to initialize compilation system if we do not use it. 1.106 + if (!UseCompiler) { 1.107 + return; 1.108 + } 1.109 #ifndef SHARK 1.110 // Set the interface to the current compiler(s). 1.111 int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple); 1.112 @@ -874,10 +915,8 @@ 1.113 } 1.114 1.115 1.116 - 1.117 -// ------------------------------------------------------------------ 1.118 -// CompileBroker::make_compiler_thread 1.119 -CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS) { 1.120 +CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, 1.121 + AbstractCompiler* comp, TRAPS) { 1.122 CompilerThread* compiler_thread = NULL; 1.123 1.124 Klass* k = 1.125 @@ -944,6 +983,7 @@ 1.126 java_lang_Thread::set_daemon(thread_oop()); 1.127 1.128 compiler_thread->set_threadObj(thread_oop()); 1.129 + compiler_thread->set_compiler(comp); 1.130 Threads::add(compiler_thread); 1.131 Thread::start(compiler_thread); 1.132 } 1.133 @@ -955,25 +995,24 @@ 1.134 } 1.135 1.136 1.137 -// ------------------------------------------------------------------ 1.138 -// CompileBroker::init_compiler_threads 1.139 -// 1.140 -// Initialize the compilation queue 1.141 void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) { 1.142 EXCEPTION_MARK; 1.143 #if !defined(ZERO) && !defined(SHARK) && !defined(PPC64) 1.144 assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?"); 1.145 #endif // !ZERO && !SHARK 1.146 + // Initialize the compilation queue 1.147 if (c2_compiler_count > 0) { 1.148 _c2_method_queue = new CompileQueue("C2MethodQueue", MethodCompileQueue_lock); 1.149 + _compilers[1]->set_num_compiler_threads(c2_compiler_count); 1.150 } 1.151 if (c1_compiler_count > 0) { 1.152 _c1_method_queue = new CompileQueue("C1MethodQueue", MethodCompileQueue_lock); 1.153 + _compilers[0]->set_num_compiler_threads(c1_compiler_count); 1.154 } 1.155 1.156 int compiler_count = c1_compiler_count + c2_compiler_count; 1.157 1.158 - _method_threads = 1.159 + _compiler_threads = 1.160 new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<CompilerThread*>(compiler_count, true); 1.161 1.162 char name_buffer[256]; 1.163 @@ -981,21 +1020,22 @@ 1.164 // Create a name for our thread. 1.165 sprintf(name_buffer, "C2 CompilerThread%d", i); 1.166 CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK); 1.167 - CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, CHECK); 1.168 - _method_threads->append(new_thread); 1.169 + // Shark and C2 1.170 + CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, _compilers[1], CHECK); 1.171 + _compiler_threads->append(new_thread); 1.172 } 1.173 1.174 for (int i = c2_compiler_count; i < compiler_count; i++) { 1.175 // Create a name for our thread. 1.176 sprintf(name_buffer, "C1 CompilerThread%d", i); 1.177 CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK); 1.178 - CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, CHECK); 1.179 - _method_threads->append(new_thread); 1.180 + // C1 1.181 + CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, _compilers[0], CHECK); 1.182 + _compiler_threads->append(new_thread); 1.183 } 1.184 1.185 if (UsePerfData) { 1.186 - PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, 1.187 - compiler_count, CHECK); 1.188 + PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, compiler_count, CHECK); 1.189 } 1.190 } 1.191 1.192 @@ -1012,27 +1052,6 @@ 1.193 } 1.194 1.195 // ------------------------------------------------------------------ 1.196 -// CompileBroker::is_idle 1.197 -bool CompileBroker::is_idle() { 1.198 - if (_c2_method_queue != NULL && !_c2_method_queue->is_empty()) { 1.199 - return false; 1.200 - } else if (_c1_method_queue != NULL && !_c1_method_queue->is_empty()) { 1.201 - return false; 1.202 - } else { 1.203 - int num_threads = _method_threads->length(); 1.204 - for (int i=0; i<num_threads; i++) { 1.205 - if (_method_threads->at(i)->task() != NULL) { 1.206 - return false; 1.207 - } 1.208 - } 1.209 - 1.210 - // No pending or active compilations. 1.211 - return true; 1.212 - } 1.213 -} 1.214 - 1.215 - 1.216 -// ------------------------------------------------------------------ 1.217 // CompileBroker::compile_method 1.218 // 1.219 // Request compilation of a method. 1.220 @@ -1227,16 +1246,9 @@ 1.221 return method_code; 1.222 } 1.223 } 1.224 - if (method->is_not_compilable(comp_level)) return NULL; 1.225 - 1.226 - if (UseCodeCacheFlushing) { 1.227 - nmethod* saved = CodeCache::reanimate_saved_code(method()); 1.228 - if (saved != NULL) { 1.229 - method->set_code(method, saved); 1.230 - return saved; 1.231 - } 1.232 + if (method->is_not_compilable(comp_level)) { 1.233 + return NULL; 1.234 } 1.235 - 1.236 } else { 1.237 // osr compilation 1.238 #ifndef TIERED 1.239 @@ -1289,13 +1301,6 @@ 1.240 method->jmethod_id(); 1.241 } 1.242 1.243 - // If the compiler is shut off due to code cache getting full 1.244 - // fail out now so blocking compiles dont hang the java thread 1.245 - if (!should_compile_new_jobs()) { 1.246 - CompilationPolicy::policy()->delay_compilation(method()); 1.247 - return NULL; 1.248 - } 1.249 - 1.250 // do the compilation 1.251 if (method->is_native()) { 1.252 if (!PreferInterpreterNativeStubs || method->is_method_handle_intrinsic()) { 1.253 @@ -1305,11 +1310,22 @@ 1.254 MutexLocker locker(MethodCompileQueue_lock, THREAD); 1.255 compile_id = assign_compile_id(method, standard_entry_bci); 1.256 } 1.257 + // To properly handle the appendix argument for out-of-line calls we are using a small trampoline that 1.258 + // pops off the appendix argument and jumps to the target (see gen_special_dispatch in SharedRuntime). 1.259 + // 1.260 + // Since normal compiled-to-compiled calls are not able to handle such a thing we MUST generate an adapter 1.261 + // in this case. If we can't generate one and use it we can not execute the out-of-line method handle calls. 1.262 (void) AdapterHandlerLibrary::create_native_wrapper(method, compile_id); 1.263 } else { 1.264 return NULL; 1.265 } 1.266 } else { 1.267 + // If the compiler is shut off due to code cache getting full 1.268 + // fail out now so blocking compiles dont hang the java thread 1.269 + if (!should_compile_new_jobs()) { 1.270 + CompilationPolicy::policy()->delay_compilation(method()); 1.271 + return NULL; 1.272 + } 1.273 compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, THREAD); 1.274 } 1.275 1.276 @@ -1541,6 +1557,101 @@ 1.277 free_task(task); 1.278 } 1.279 1.280 +// Initialize compiler thread(s) + compiler object(s). The postcondition 1.281 +// of this function is that the compiler runtimes are initialized and that 1.282 +//compiler threads can start compiling. 1.283 +bool CompileBroker::init_compiler_runtime() { 1.284 + CompilerThread* thread = CompilerThread::current(); 1.285 + AbstractCompiler* comp = thread->compiler(); 1.286 + // Final sanity check - the compiler object must exist 1.287 + guarantee(comp != NULL, "Compiler object must exist"); 1.288 + 1.289 + int system_dictionary_modification_counter; 1.290 + { 1.291 + MutexLocker locker(Compile_lock, thread); 1.292 + system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); 1.293 + } 1.294 + 1.295 + { 1.296 + // Must switch to native to allocate ci_env 1.297 + ThreadToNativeFromVM ttn(thread); 1.298 + ciEnv ci_env(NULL, system_dictionary_modification_counter); 1.299 + // Cache Jvmti state 1.300 + ci_env.cache_jvmti_state(); 1.301 + // Cache DTrace flags 1.302 + ci_env.cache_dtrace_flags(); 1.303 + 1.304 + // Switch back to VM state to do compiler initialization 1.305 + ThreadInVMfromNative tv(thread); 1.306 + ResetNoHandleMark rnhm; 1.307 + 1.308 + 1.309 + if (!comp->is_shark()) { 1.310 + // Perform per-thread and global initializations 1.311 + comp->initialize(); 1.312 + } 1.313 + } 1.314 + 1.315 + if (comp->is_failed()) { 1.316 + disable_compilation_forever(); 1.317 + // If compiler initialization failed, no compiler thread that is specific to a 1.318 + // particular compiler runtime will ever start to compile methods. 1.319 + 1.320 + shutdown_compiler_runtime(comp, thread); 1.321 + return false; 1.322 + } 1.323 + 1.324 + // C1 specific check 1.325 + if (comp->is_c1() && (thread->get_buffer_blob() == NULL)) { 1.326 + warning("Initialization of %s thread failed (no space to run compilers)", thread->name()); 1.327 + return false; 1.328 + } 1.329 + 1.330 + return true; 1.331 +} 1.332 + 1.333 +// If C1 and/or C2 initialization failed, we shut down all compilation. 1.334 +// We do this to keep things simple. This can be changed if it ever turns out to be 1.335 +// a problem. 1.336 +void CompileBroker::shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread) { 1.337 + // Free buffer blob, if allocated 1.338 + if (thread->get_buffer_blob() != NULL) { 1.339 + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 1.340 + CodeCache::free(thread->get_buffer_blob()); 1.341 + } 1.342 + 1.343 + if (comp->should_perform_shutdown()) { 1.344 + // There are two reasons for shutting down the compiler 1.345 + // 1) compiler runtime initialization failed 1.346 + // 2) The code cache is full and the following flag is set: -XX:-UseCodeCacheFlushing 1.347 + warning("Shutting down compiler %s (no space to run compilers)", comp->name()); 1.348 + 1.349 + // Only one thread per compiler runtime object enters here 1.350 + // Set state to shut down 1.351 + comp->set_shut_down(); 1.352 + 1.353 + MutexLocker mu(MethodCompileQueue_lock, thread); 1.354 + CompileQueue* queue; 1.355 + if (_c1_method_queue != NULL) { 1.356 + _c1_method_queue->delete_all(); 1.357 + queue = _c1_method_queue; 1.358 + _c1_method_queue = NULL; 1.359 + delete _c1_method_queue; 1.360 + } 1.361 + 1.362 + if (_c2_method_queue != NULL) { 1.363 + _c2_method_queue->delete_all(); 1.364 + queue = _c2_method_queue; 1.365 + _c2_method_queue = NULL; 1.366 + delete _c2_method_queue; 1.367 + } 1.368 + 1.369 + // We could delete compiler runtimes also. However, there are references to 1.370 + // the compiler runtime(s) (e.g., nmethod::is_compiled_by_c1()) which then 1.371 + // fail. This can be done later if necessary. 1.372 + } 1.373 +} 1.374 + 1.375 // ------------------------------------------------------------------ 1.376 // CompileBroker::compiler_thread_loop 1.377 // 1.378 @@ -1548,7 +1659,6 @@ 1.379 void CompileBroker::compiler_thread_loop() { 1.380 CompilerThread* thread = CompilerThread::current(); 1.381 CompileQueue* queue = thread->queue(); 1.382 - 1.383 // For the thread that initializes the ciObjectFactory 1.384 // this resource mark holds all the shared objects 1.385 ResourceMark rm; 1.386 @@ -1577,68 +1687,78 @@ 1.387 log->end_elem(); 1.388 } 1.389 1.390 - while (true) { 1.391 - { 1.392 - // We need this HandleMark to avoid leaking VM handles. 1.393 - HandleMark hm(thread); 1.394 + // If compiler thread/runtime initialization fails, exit the compiler thread 1.395 + if (!init_compiler_runtime()) { 1.396 + return; 1.397 + } 1.398 1.399 - if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) { 1.400 - // the code cache is really full 1.401 - handle_full_code_cache(); 1.402 - } else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) { 1.403 - // Attempt to start cleaning the code cache while there is still a little headroom 1.404 - NMethodSweeper::handle_full_code_cache(false); 1.405 - } 1.406 + // Poll for new compilation tasks as long as the JVM runs. Compilation 1.407 + // should only be disabled if something went wrong while initializing the 1.408 + // compiler runtimes. This, in turn, should not happen. The only known case 1.409 + // when compiler runtime initialization fails is if there is not enough free 1.410 + // space in the code cache to generate the necessary stubs, etc. 1.411 + while (!is_compilation_disabled_forever()) { 1.412 + // We need this HandleMark to avoid leaking VM handles. 1.413 + HandleMark hm(thread); 1.414 1.415 - CompileTask* task = queue->get(); 1.416 + if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) { 1.417 + // the code cache is really full 1.418 + handle_full_code_cache(); 1.419 + } 1.420 1.421 - // Give compiler threads an extra quanta. They tend to be bursty and 1.422 - // this helps the compiler to finish up the job. 1.423 - if( CompilerThreadHintNoPreempt ) 1.424 - os::hint_no_preempt(); 1.425 + CompileTask* task = queue->get(); 1.426 + if (task == NULL) { 1.427 + continue; 1.428 + } 1.429 1.430 - // trace per thread time and compile statistics 1.431 - CompilerCounters* counters = ((CompilerThread*)thread)->counters(); 1.432 - PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter()); 1.433 + // Give compiler threads an extra quanta. They tend to be bursty and 1.434 + // this helps the compiler to finish up the job. 1.435 + if( CompilerThreadHintNoPreempt ) 1.436 + os::hint_no_preempt(); 1.437 1.438 - // Assign the task to the current thread. Mark this compilation 1.439 - // thread as active for the profiler. 1.440 - CompileTaskWrapper ctw(task); 1.441 - nmethodLocker result_handle; // (handle for the nmethod produced by this task) 1.442 - task->set_code_handle(&result_handle); 1.443 - methodHandle method(thread, task->method()); 1.444 + // trace per thread time and compile statistics 1.445 + CompilerCounters* counters = ((CompilerThread*)thread)->counters(); 1.446 + PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter()); 1.447 1.448 - // Never compile a method if breakpoints are present in it 1.449 - if (method()->number_of_breakpoints() == 0) { 1.450 - // Compile the method. 1.451 - if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) { 1.452 + // Assign the task to the current thread. Mark this compilation 1.453 + // thread as active for the profiler. 1.454 + CompileTaskWrapper ctw(task); 1.455 + nmethodLocker result_handle; // (handle for the nmethod produced by this task) 1.456 + task->set_code_handle(&result_handle); 1.457 + methodHandle method(thread, task->method()); 1.458 + 1.459 + // Never compile a method if breakpoints are present in it 1.460 + if (method()->number_of_breakpoints() == 0) { 1.461 + // Compile the method. 1.462 + if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) { 1.463 #ifdef COMPILER1 1.464 - // Allow repeating compilations for the purpose of benchmarking 1.465 - // compile speed. This is not useful for customers. 1.466 - if (CompilationRepeat != 0) { 1.467 - int compile_count = CompilationRepeat; 1.468 - while (compile_count > 0) { 1.469 - invoke_compiler_on_method(task); 1.470 - nmethod* nm = method->code(); 1.471 - if (nm != NULL) { 1.472 - nm->make_zombie(); 1.473 - method->clear_code(); 1.474 - } 1.475 - compile_count--; 1.476 + // Allow repeating compilations for the purpose of benchmarking 1.477 + // compile speed. This is not useful for customers. 1.478 + if (CompilationRepeat != 0) { 1.479 + int compile_count = CompilationRepeat; 1.480 + while (compile_count > 0) { 1.481 + invoke_compiler_on_method(task); 1.482 + nmethod* nm = method->code(); 1.483 + if (nm != NULL) { 1.484 + nm->make_zombie(); 1.485 + method->clear_code(); 1.486 } 1.487 + compile_count--; 1.488 } 1.489 + } 1.490 #endif /* COMPILER1 */ 1.491 - invoke_compiler_on_method(task); 1.492 - } else { 1.493 - // After compilation is disabled, remove remaining methods from queue 1.494 - method->clear_queued_for_compilation(); 1.495 - } 1.496 + invoke_compiler_on_method(task); 1.497 + } else { 1.498 + // After compilation is disabled, remove remaining methods from queue 1.499 + method->clear_queued_for_compilation(); 1.500 } 1.501 } 1.502 } 1.503 + 1.504 + // Shut down compiler runtime 1.505 + shutdown_compiler_runtime(thread->compiler(), thread); 1.506 } 1.507 1.508 - 1.509 // ------------------------------------------------------------------ 1.510 // CompileBroker::init_compiler_thread_log 1.511 // 1.512 @@ -1718,7 +1838,7 @@ 1.513 CodeCache::print_summary(&s, detailed); 1.514 } 1.515 ttyLocker ttyl; 1.516 - tty->print_cr(s.as_string()); 1.517 + tty->print(s.as_string()); 1.518 } 1.519 1.520 // ------------------------------------------------------------------ 1.521 @@ -1943,10 +2063,17 @@ 1.522 } 1.523 #endif 1.524 if (UseCodeCacheFlushing) { 1.525 - NMethodSweeper::handle_full_code_cache(true); 1.526 + // Since code cache is full, immediately stop new compiles 1.527 + if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) { 1.528 + NMethodSweeper::log_sweep("disable_compiler"); 1.529 + 1.530 + // Switch to 'vm_state'. This ensures that possibly_sweep() can be called 1.531 + // without having to consider the state in which the current thread is. 1.532 + ThreadInVMfromUnknown in_vm; 1.533 + NMethodSweeper::possibly_sweep(); 1.534 + } 1.535 } else { 1.536 - UseCompiler = false; 1.537 - AlwaysCompileLoopMethods = false; 1.538 + disable_compilation_forever(); 1.539 } 1.540 } 1.541 codecache_print(/* detailed= */ true);