|
Java example source code file (advancedThresholdPolicy.cpp)
The advancedThresholdPolicy.cpp Java example source code/* * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #include "precompiled.hpp" #include "runtime/advancedThresholdPolicy.hpp" #include "runtime/simpleThresholdPolicy.inline.hpp" #ifdef TIERED // Print an event. void AdvancedThresholdPolicy::print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { tty->print(" rate="); if (mh->prev_time() == 0) tty->print("n/a"); else tty->print("%f", mh->rate()); tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback), threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback)); } void AdvancedThresholdPolicy::initialize() { // Turn on ergonomic compiler count selection if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) { FLAG_SET_DEFAULT(CICompilerCountPerCPU, true); } int count = CICompilerCount; if (CICompilerCountPerCPU) { // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n int log_cpu = log2_intptr(os::active_processor_count()); int loglog_cpu = log2_intptr(MAX2(log_cpu, 1)); count = MAX2(log_cpu * loglog_cpu, 1) * 3 / 2; } set_c1_count(MAX2(count / 3, 1)); set_c2_count(MAX2(count - count / 3, 1)); // Some inlining tuning #ifdef X86 if (FLAG_IS_DEFAULT(InlineSmallCode)) { FLAG_SET_DEFAULT(InlineSmallCode, 2000); } #endif #ifdef SPARC if (FLAG_IS_DEFAULT(InlineSmallCode)) { FLAG_SET_DEFAULT(InlineSmallCode, 2500); } #endif set_increase_threshold_at_ratio(); set_start_time(os::javaTimeMillis()); } // update_rate() is called from select_task() while holding a compile queue lock. void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) { JavaThread* THREAD = JavaThread::current(); if (is_old(m)) { // We don't remove old methods from the queue, // so we can just zero the rate. m->set_rate(0, THREAD); return; } // We don't update the rate if we've just came out of a safepoint. // delta_s is the time since last safepoint in milliseconds. jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement // How many events were there since the last time? int event_count = m->invocation_count() + m->backedge_count(); int delta_e = event_count - m->prev_event_count(); // We should be running for at least 1ms. if (delta_s >= TieredRateUpdateMinTime) { // And we must've taken the previous point at least 1ms before. if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) { m->set_prev_time(t, THREAD); m->set_prev_event_count(event_count, THREAD); m->set_rate((float)delta_e / (float)delta_t, THREAD); // Rate is events per millisecond } else if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) { // If nothing happened for 25ms, zero the rate. Don't modify prev values. m->set_rate(0, THREAD); } } } // Check if this method has been stale from a given number of milliseconds. // See select_task(). bool AdvancedThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) { jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); jlong delta_t = t - m->prev_time(); if (delta_t > timeout && delta_s > timeout) { int event_count = m->invocation_count() + m->backedge_count(); int delta_e = event_count - m->prev_event_count(); // Return true if there were no events. return delta_e == 0; } return false; } // We don't remove old methods from the compile queue even if they have // very low activity. See select_task(). bool AdvancedThresholdPolicy::is_old(Method* method) { return method->invocation_count() > 50000 || method->backedge_count() > 500000; } double AdvancedThresholdPolicy::weight(Method* method) { return (method->rate() + 1) * ((method->invocation_count() + 1) * (method->backedge_count() + 1)); } // Apply heuristics and return true if x should be compiled before y bool AdvancedThresholdPolicy::compare_methods(Method* x, Method* y) { if (x->highest_comp_level() > y->highest_comp_level()) { // recompilation after deopt return true; } else if (x->highest_comp_level() == y->highest_comp_level()) { if (weight(x) > weight(y)) { return true; } } return false; } // Is method profiled enough? bool AdvancedThresholdPolicy::is_method_profiled(Method* method) { MethodData* mdo = method->method_data(); if (mdo != NULL) { int i = mdo->invocation_count_delta(); int b = mdo->backedge_count_delta(); return call_predicate_helper<CompLevel_full_profile>(i, b, 1); } return false; } // Called with the queue locked and with at least one element CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { CompileTask *max_task = NULL; Method* max_method = NULL; jlong t = os::javaTimeMillis(); // Iterate through the queue and find a method with a maximum rate. for (CompileTask* task = compile_queue->first(); task != NULL;) { CompileTask* next_task = task->next(); Method* method = task->method(); MethodData* mdo = method->method_data(); update_rate(t, method); if (max_task == NULL) { max_task = task; max_method = method; } else { // If a method has been stale for some time, remove it from the queue. if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) { if (PrintTieredEvents) { print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); } CompileTaskWrapper ctw(task); // Frees the task compile_queue->remove(task); method->clear_queued_for_compilation(); task = next_task; continue; } // Select a method with a higher rate if (compare_methods(method, max_method)) { max_task = task; max_method = method; } } task = next_task; } if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile && is_method_profiled(max_method)) { max_task->set_comp_level(CompLevel_limited_profile); if (PrintTieredEvents) { print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); } } return max_task; } double AdvancedThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) { double queue_size = CompileBroker::queue_size(level); int comp_count = compiler_count(level); double k = queue_size / (feedback_k * comp_count) + 1; // Increase C1 compile threshold when the code cache is filled more // than specified by IncreaseFirstTierCompileThresholdAt percentage. // The main intention is to keep enough free space for C2 compiled code // to achieve peak performance if the code cache is under stress. if ((TieredStopAtLevel == CompLevel_full_optimization) && (level != CompLevel_full_optimization)) { double current_reverse_free_ratio = CodeCache::reverse_free_ratio(); if (current_reverse_free_ratio > _increase_threshold_at_ratio) { k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio); } } return k; } // Call and loop predicates determine whether a transition to a higher // compilation level should be performed (pointers to predicate functions // are passed to common()). // Tier?LoadFeedback is basically a coefficient that determines of // how many methods per compiler thread can be in the queue before // the threshold values double. bool AdvancedThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level) { switch(cur_level) { case CompLevel_none: case CompLevel_limited_profile: { double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); return loop_predicate_helper<CompLevel_none>(i, b, k); } case CompLevel_full_profile: { double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); return loop_predicate_helper<CompLevel_full_profile>(i, b, k); } default: return true; } } bool AdvancedThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level) { switch(cur_level) { case CompLevel_none: case CompLevel_limited_profile: { double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); return call_predicate_helper<CompLevel_none>(i, b, k); } case CompLevel_full_profile: { double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); return call_predicate_helper<CompLevel_full_profile>(i, b, k); } default: return true; } } // If a method is old enough and is still in the interpreter we would want to // start profiling without waiting for the compiled method to arrive. // We also take the load on compilers into the account. bool AdvancedThresholdPolicy::should_create_mdo(Method* method, CompLevel cur_level) { if (cur_level == CompLevel_none && CompileBroker::queue_size(CompLevel_full_optimization) <= Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { int i = method->invocation_count(); int b = method->backedge_count(); double k = Tier0ProfilingStartPercentage / 100.0; return call_predicate_helper<CompLevel_none>(i, b, k) || loop_predicate_helper Other Java examples (source code examples)Here is a short list of links related to this Java advancedThresholdPolicy.cpp source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.