src/share/vm/compiler/compileBroker.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/compiler/compileBroker.cpp	Fri Sep 25 16:23:21 2015
--- new/src/share/vm/compiler/compileBroker.cpp	Fri Sep 25 16:23:21 2015

*** 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"
*** 195,208 **** --- 196,217 ---- } }; static CompilationLog* _compilation_log = NULL; ! void compileBroker_init() { ! bool compileBroker_init() { if (LogEvents) { _compilation_log = new CompilationLog(); } + + // init directives stack, adding default directive + DirectivesStack::init(); + + if (DirectivesParser::has_file()) { + return DirectivesParser::parse_from_flag(); + } + return true; } CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) { CompilerThread* thread = CompilerThread::current(); thread->set_task(task);
*** 1141,1155 **** --- 1150,1169 ---- (!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 = DirectivesStack::getMatchingDirective(method, comp); + bool excluded = !dirset->EnabledOption; + DirectivesStack::release(dirset); + // 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 (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",
*** 1309,1319 **** --- 1323,1332 ---- // 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 **** --- 1569,1691 ---- } ttyLocker ttyl; tty->print("%s", s.as_string()); } + // Create a new dirstack and push a default directive + + int DirectivesStack::_depth = 0; + CompilerDirectives* DirectivesStack::_top = NULL; + CompilerDirectives* DirectivesStack::_bottom = NULL; + + void DirectivesStack::init() { + 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::getDefaultDirective(AbstractCompiler* comp) { + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + + assert(_bottom != NULL, "Must never be empty"); + return _bottom->get_for(comp); + } + + 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++; + } + + 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 - don't allow an empty stack + } + CompilerDirectives* tmp = _top; + _top = _top->next(); + _depth--; + + DirectivesStack::release(tmp); + } + + 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) { + 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(); + } + } + + void DirectivesStack::release(DirectiveSet* set) { + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + if (set->is_exclusive_copy()) { + // Old CompilecCmmands forced us to create an exclusive copy + delete set; + } else { + assert(set->directive() != NULL, ""); + release(set->directive()); + } + } + + + void DirectivesStack::release(CompilerDirectives* dir) { + assert(DirectivesStack_lock->owned_by_self(), ""); + dir->dec_refcount(); + if (dir->refcount() == 0) { + delete dir; + } + } + + DirectiveSet* DirectivesStack::getMatchingDirective(methodHandle mh, AbstractCompiler *comp) { + 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)) { + match = dir->get_for(comp); + 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->compilecommand_compatibility_init(mh); + } + // ------------------------------------------------------------------ // CompileBroker::invoke_compiler_on_method // // Compile a method. //
*** 1582,1601 **** --- 1708,1732 ---- 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* dirset = DirectivesStack::getMatchingDirective(task->method(), compiler(task_level)); + + should_break = dirset->BreakAtExecuteOption || task->check_break_at_flags(); + if (should_log && !dirset->LogOption) { + int val = 0; + dirset->set_Log((void*)&val); + } { // 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);
*** 1615,1627 **** --- 1746,1755 ---- 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.
*** 1645,1655 **** --- 1773,1783 ---- MonitorLockerEx locker(Compilation_lock, Mutex::_no_safepoint_check_flag); while (WhiteBox::compilation_locked) { locker.wait(Mutex::_no_safepoint_check_flag); } } ! comp->compile_method(&ci_env, target, osr_bci, dirset); } if (!ci_env.failing() && task->code() == NULL) { //assert(false, "compiler should always document failure"); // The compiler elected, without comment, not to register a result.
*** 1694,1703 **** --- 1822,1832 ---- event.set_codeSize((task->code() == NULL) ? 0 : task->code()->total_size()); event.set_inlinedBytes(task->num_inlined_bytecodes()); event.commit(); } } + DirectivesStack::release(dirset); pop_jni_handle_block(); methodHandle method(thread, task->method()); DTRACE_METHOD_COMPILE_END_PROBE(method, compiler_name(task_level), task->is_success());
*** 1879,1903 **** --- 2008,2017 ---- 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.
*** 2073,2077 **** --- 2187,2192 ---- #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