|
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.