// Check if the method can be compiled, change level if necessary void SimpleThresholdPolicy::compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) { assert(level <= TieredStopAtLevel, "Invalid compilation level"); if (level == CompLevel_none) { return; } // Check if the method can be compiled. If it cannot be compiled with C1, continue profiling // in the interpreter and then compile with C2 (the transition function will request that, // see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with // pure C1. if (!can_be_compiled(mh, level)) { if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) { compile(mh, bci, CompLevel_simple, thread); } return; } if (bci != InvocationEntryBci && mh->is_not_osr_compilable(level)) { return; } if (!CompileBroker::compilation_is_in_queue(mh)) { if (PrintTieredEvents) { print_event(COMPILE, mh, mh, bci, level); } submit_compile(mh, bci, level, thread); } }
// Returns true if m must be compiled before executing it // This is intended to force compiles for methods (usually for // debugging) that would otherwise be interpreted for some reason. bool CompilationPolicy::must_be_compiled(methodHandle m, int comp_level) { if (m->has_compiled_code()) return false; // already compiled if (!can_be_compiled(m, comp_level)) return false; return !UseInterpreter || // must compile all methods (UseCompiler && AlwaysCompileLoopMethods && m->has_loops() && CompileBroker::should_compile_new_jobs()); // eagerly compile loop methods }
void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) { int hot_count = m->backedge_count(); const char* comment = "backedge_count"; if (is_compilation_enabled() && !m->is_not_osr_compilable() && can_be_compiled(m)) { CompileBroker::compile_method(m, bci, CompLevel_highest_tier, m, hot_count, comment, thread); NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true));) }
void SimpleCompPolicy::method_invocation_event(const methodHandle& m, JavaThread* thread) { const int comp_level = CompLevel_highest_tier; const int hot_count = m->invocation_count(); reset_counter_for_invocation_event(m); const char* comment = "count"; if (is_compilation_enabled() && can_be_compiled(m, comp_level)) { nmethod* nm = m->code(); if (nm == NULL ) { CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread); } } }
// Returns true if m is allowed to be osr compiled bool CompilationPolicy::can_be_osr_compiled(methodHandle m, int comp_level) { bool result = false; if (comp_level == CompLevel_all) { if (TieredCompilation) { // enough to be osr compilable at any level for tiered result = !m->is_not_osr_compilable(CompLevel_simple) || !m->is_not_osr_compilable(CompLevel_full_optimization); } else { // must be osr compilable at available level for non-tiered result = !m->is_not_osr_compilable(CompLevel_highest_tier); } } else if (is_compile(comp_level)) { result = !m->is_not_osr_compilable(comp_level); } return (result && can_be_compiled(m, comp_level)); }
// ------------------------------------------------------------------ // ciMethod::ciMethod // // Loaded method. ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) { assert(h_m() != NULL, "no null method"); // These fields are always filled in in loaded methods. _flags = ciFlags(h_m()->access_flags()); // Easy to compute, so fill them in now. _max_stack = h_m()->max_stack(); _max_locals = h_m()->max_locals(); _code_size = h_m()->code_size(); _intrinsic_id = h_m()->intrinsic_id(); _handler_count = h_m()->exception_table_length(); _uses_monitors = h_m()->access_flags().has_monitor_bytecodes(); _balanced_monitors = !_uses_monitors || h_m()->access_flags().is_monitor_matching(); _is_c1_compilable = !h_m()->is_not_c1_compilable(); _is_c2_compilable = !h_m()->is_not_c2_compilable(); // Lazy fields, filled in on demand. Require allocation. _code = NULL; _exception_handlers = NULL; _liveness = NULL; _method_blocks = NULL; #if defined(COMPILER2) || defined(SHARK) _flow = NULL; _bcea = NULL; #endif // COMPILER2 || SHARK ciEnv *env = CURRENT_ENV; if (env->jvmti_can_hotswap_or_post_breakpoint() && can_be_compiled()) { // 6328518 check hotswap conditions under the right lock. MutexLocker locker(Compile_lock); if (Dependencies::check_evol_method(h_m()) != NULL) { _is_c1_compilable = false; _is_c2_compilable = false; } } else { CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); } if (h_m()->method_holder()->is_linked()) { _can_be_statically_bound = h_m()->can_be_statically_bound(); } else { // Have to use a conservative value in this case. _can_be_statically_bound = false; } // Adjust the definition of this condition to be more useful: // %%% take these conditions into account in vtable generation if (!_can_be_statically_bound && h_m()->is_private()) _can_be_statically_bound = true; if (_can_be_statically_bound && h_m()->is_abstract()) _can_be_statically_bound = false; // generating _signature may allow GC and therefore move m. // These fields are always filled in. _name = env->get_symbol(h_m()->name()); _holder = env->get_instance_klass(h_m()->method_holder()); ciSymbol* sig_symbol = env->get_symbol(h_m()->signature()); constantPoolHandle cpool = h_m()->constants(); _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol); _method_data = NULL; // Take a snapshot of these values, so they will be commensurate with the MDO. if (ProfileInterpreter || TieredCompilation) { int invcnt = h_m()->interpreter_invocation_count(); // if the value overflowed report it as max int _interpreter_invocation_count = invcnt < 0 ? max_jint : invcnt ; _interpreter_throwout_count = h_m()->interpreter_throwout_count(); } else { _interpreter_invocation_count = 0; _interpreter_throwout_count = 0; } if (_interpreter_invocation_count == 0) _interpreter_invocation_count = 1; _instructions_size = -1; #ifdef ASSERT if (ReplayCompiles) { ciReplay::initialize(this); } #endif }