src/share/vm/compiler/compileBroker.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/compiler/compileBroker.cpp

src/share/vm/compiler/compileBroker.cpp

Print this page
rev 8995 : 8046155: JEP165: Compiler Control
Summary:
Reviewed-by:

*** 27,36 **** --- 27,37 ---- #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compileLog.hpp" #include "compiler/compilerOracle.hpp" + #include "compiler/directivesparser.hpp" #include "interpreter/linkResolver.hpp" #include "memory/allocation.inline.hpp" #include "oops/methodData.hpp" #include "oops/method.hpp" #include "oops/oop.inline.hpp"
*** 98,107 **** --- 99,109 ---- volatile jint CompileBroker::_print_compilation_warning = 0; volatile jint CompileBroker::_should_compile_new_jobs = run_compilation; // The installed compiler(s) AbstractCompiler* CompileBroker::_compilers[2]; + DirectivesStack* CompileBroker::_dirstack; // These counters are used to assign an unique ID to each compilation. volatile jint CompileBroker::_compilation_id = 0; volatile jint CompileBroker::_osr_compilation_id = 0;
*** 195,208 **** } }; static CompilationLog* _compilation_log = NULL; ! void compileBroker_init() { if (LogEvents) { _compilation_log = new CompilationLog(); } } CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) { CompilerThread* thread = CompilerThread::current(); thread->set_task(task); --- 197,225 ---- } }; static CompilationLog* _compilation_log = NULL; ! bool compileBroker_init() { if (LogEvents) { _compilation_log = new CompilationLog(); } + + // init directives stack and add default directives + CompileBroker::set_dirstack(new DirectivesStack()); + + /*CompilerDirectives* _default_directives = new CompilerDirectives(); + char str[] = "*.*"; + const char* error_msg = NULL; + _default_directives->add_match(str, error_msg); + assert(error_msg == NULL, "Must succeed."); + CompileBroker::dirstack()->push(_default_directives);*/ + + if (DirectivesParser::has_file()) { + DirectivesParser::parse_from_flag(); + } + return true; } CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) { CompilerThread* thread = CompilerThread::current(); thread->set_task(task);
*** 1141,1155 **** (!CICompileOSR || comp == NULL || !comp->supports_osr())) { method->set_not_osr_compilable(comp_level); return true; } // The method may be explicitly excluded by the user. bool quietly; double scale; ! if (CompilerOracle::should_exclude(method, quietly) ! || (CompilerOracle::has_option_value(method, "CompileThresholdScaling", scale) && scale == 0)) { if (!quietly) { // This does not happen quietly... ResourceMark rm; tty->print("### Excluding %s:%s", method->is_native() ? "generation of native wrapper" : "compile", --- 1158,1180 ---- (!CICompileOSR || comp == NULL || !comp->supports_osr())) { method->set_not_osr_compilable(comp_level); return true; } + // Breaking the abstraction - directives are only used inside a compilation otherwise. + DirectiveSet* dirset = dirstack()->getMatchingDirective(method, comp_level); + bool excluded = !dirset->EnabledOption; + { + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + dirset->directive()->dec_refcount(); + } + // The method may be explicitly excluded by the user. bool quietly; double scale; ! if (excluded || (CompilerOracle::has_option_value(method, "CompileThresholdScaling", scale) && scale == 0)) { ! bool quietly = CompilerOracle::should_exclude_quietly(); if (!quietly) { // This does not happen quietly... ResourceMark rm; tty->print("### Excluding %s:%s", method->is_native() ? "generation of native wrapper" : "compile",
*** 1297,1319 **** MutexLocker locker(Compile_lock, thread); system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); } { // Must switch to native to allocate ci_env ThreadToNativeFromVM ttn(thread); ! ciEnv ci_env(NULL, system_dictionary_modification_counter); // Cache Jvmti state ci_env.cache_jvmti_state(); // Cache DTrace flags ci_env.cache_dtrace_flags(); // Switch back to VM state to do compiler initialization ThreadInVMfromNative tv(thread); ResetNoHandleMark rnhm; - if (!comp->is_shark()) { // Perform per-thread and global initializations comp->initialize(); } } --- 1322,1346 ---- MutexLocker locker(Compile_lock, thread); system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); } { + DirectiveSet* dirset = _dirstack->peak(comp); + assert(dirset->directive()->is_default_directive(), "Consistency"); + // Must switch to native to allocate ci_env ThreadToNativeFromVM ttn(thread); ! ciEnv ci_env(NULL, dirset, system_dictionary_modification_counter); // Cache Jvmti state ci_env.cache_jvmti_state(); // Cache DTrace flags ci_env.cache_dtrace_flags(); // Switch back to VM state to do compiler initialization ThreadInVMfromNative tv(thread); ResetNoHandleMark rnhm; if (!comp->is_shark()) { // Perform per-thread and global initializations comp->initialize(); } }
*** 1556,1565 **** --- 1583,1703 ---- } ttyLocker ttyl; tty->print("%s", s.as_string()); } + void CompileBroker::print_directives(outputStream* st) { + dirstack()->print(st); + } + + DirectivesStack* CompileBroker::dirstack() { + return _dirstack; + } + + void CompileBroker::set_dirstack(DirectivesStack* stack) { + _dirstack = stack; + } + + // Create a new dirstack and push a default directive + DirectivesStack::DirectivesStack() : _depth(0), _top(NULL), _bottom(NULL) + { + CompilerDirectives* _default_directives = new CompilerDirectives(); + char str[] = "*.*"; + const char* error_msg = NULL; + _default_directives->add_match(str, error_msg); + assert(error_msg == NULL, "Must succeed."); + push(_default_directives); + } + + DirectiveSet* DirectivesStack::peak(AbstractCompiler* comp) { + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + + assert(_top != NULL, "Must never be empty"); + if (comp->is_c1()) { + return _top->get_for(CompilerDirectives::TargetC1); + } else { + assert(comp->is_c2(), "Must be c2"); + return _top->get_for(CompilerDirectives::TargetC2); + } + // CMH handle shark and others. + } + + void DirectivesStack::push(CompilerDirectives* directive) { + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + + directive->inc_refcount(); + if (_top == NULL) { + assert(_bottom == NULL, "There can only be one default directive"); + _bottom = directive; // default directive, can never be removed. + } + + directive->set_next(_top); + _top = directive; + _depth++; + + if (PrintCompilerDirectives) { + directive->print(tty); + } + } + + void DirectivesStack::pop() { + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + pop_inner(); + } + + void DirectivesStack::pop_inner() { + assert(DirectivesStack_lock->owned_by_self(), ""); + + if (_top->next() == NULL) { + return; // Do nothing - dont allow an empty stack + } + CompilerDirectives* tmp = _top; + _top = _top->next(); + _depth--; + tmp->dec_refcount(); + return; + } + + void DirectivesStack::clear() { + // holding the lock during the whole operation ensuring consistent result + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + while (_top->next() != NULL) { + DirectivesStack::pop_inner(); + } + } + + void DirectivesStack::print(outputStream* st) { + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + CompilerDirectives* tmp = _top; + while (tmp != NULL) { + tmp->print(st); + tmp = tmp->next(); + } + } + + DirectiveSet* DirectivesStack::getMatchingDirective(methodHandle mh, int comp_level) { + assert(_depth > 0, "Must never be empty"); + CompilerDirectives* dir = _top; + assert(dir != NULL, "Must be initialized"); + + DirectiveSet* match = NULL; + { + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + while (dir != NULL) { + if (dir->is_default_directive() || dir->match(mh, comp_level)) { + match = dir->get_for(comp_level); + break; + } + dir = dir->next(); + } + } + guarantee(match != NULL, "There should always be a default directive that matches"); + + // Check for legacy compile commands update, without DirectivesStack_lock + return match->late_cc_init(mh); + } + // ------------------------------------------------------------------ // CompileBroker::invoke_compiler_on_method // // Compile a method. //
*** 1582,1601 **** int osr_bci = task->osr_bci(); bool is_osr = (osr_bci != standard_entry_bci); bool should_log = (thread->log() != NULL); bool should_break = false; int task_level = task->comp_level(); { // create the handle inside it's own block so it can't // accidentally be referenced once the thread transitions to // native. The NoHandleMark before the transition should catch // any cases where this occurs in the future. methodHandle method(thread, task->method()); - should_break = check_break_at(method, compile_id, is_osr); - if (should_log && !CompilerOracle::should_log(method)) { - should_log = false; - } assert(!method->is_native(), "no longer compile natives"); // Save information about this method in case of failure. set_last_compile(thread, method, is_osr, task_level); --- 1720,1743 ---- int osr_bci = task->osr_bci(); bool is_osr = (osr_bci != standard_entry_bci); bool should_log = (thread->log() != NULL); bool should_break = false; int task_level = task->comp_level(); + + // Look up matching directives + DirectiveSet* dir = CompileBroker::_dirstack->getMatchingDirective(task->method(), task_level); + + should_break = dir->BreakAtExecuteOption || task->check_break_at_flags(); + if (should_log && !dir->LogOption) { + dir->set_Log((void*)false); + } { // create the handle inside it's own block so it can't // accidentally be referenced once the thread transitions to // native. The NoHandleMark before the transition should catch // any cases where this occurs in the future. methodHandle method(thread, task->method()); assert(!method->is_native(), "no longer compile natives"); // Save information about this method in case of failure. set_last_compile(thread, method, is_osr, task_level);
*** 1614,1627 **** } NoHandleMark nhm; ThreadToNativeFromVM ttn(thread); ! ciEnv ci_env(task, system_dictionary_modification_counter); ! if (should_break) { ! ci_env.set_break_at_compile(true); ! } if (should_log) { ci_env.set_log(thread->log()); } assert(thread->env() == &ci_env, "set by ci_env"); // The thread-env() field is cleared in ~CompileTaskWrapper. --- 1756,1766 ---- } NoHandleMark nhm; ThreadToNativeFromVM ttn(thread); ! ciEnv ci_env(task, dir, system_dictionary_modification_counter); if (should_log) { ci_env.set_log(thread->log()); } assert(thread->env() == &ci_env, "set by ci_env"); // The thread-env() field is cleared in ~CompileTaskWrapper.
*** 1879,1903 **** thread->set_active_handles(java_handles); compile_handles->set_pop_frame_link(NULL); JNIHandleBlock::release_block(compile_handles, thread); // may block } - - // ------------------------------------------------------------------ - // CompileBroker::check_break_at - // - // Should the compilation break at the current compilation. - bool CompileBroker::check_break_at(methodHandle method, int compile_id, bool is_osr) { - if (CICountOSR && is_osr && (compile_id == CIBreakAtOSR)) { - return true; - } else if( CompilerOracle::should_break_at(method) ) { // break when compiling - return true; - } else { - return (compile_id == CIBreakAt); - } - } - // ------------------------------------------------------------------ // CompileBroker::collect_statistics // // Collect statistics about the compilation. --- 2018,2027 ----
*** 2073,2077 **** --- 2197,2202 ---- #ifndef PRODUCT st->print_cr("Compiler thread printing unimplemented."); st->cr(); #endif } +
src/share/vm/compiler/compileBroker.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File