8317562: [JFR] Compilation queue statistics
Reviewed-by: kvn
This commit is contained in:
parent
965ae72964
commit
d992033439
@ -331,6 +331,10 @@ void CompileQueue::add(CompileTask* task) {
|
|||||||
_last = task;
|
_last = task;
|
||||||
}
|
}
|
||||||
++_size;
|
++_size;
|
||||||
|
++_total_added;
|
||||||
|
if (_size > _peak_size) {
|
||||||
|
_peak_size = _size;
|
||||||
|
}
|
||||||
|
|
||||||
// Mark the method as being in the compile queue.
|
// Mark the method as being in the compile queue.
|
||||||
task->method()->set_queued_for_compilation();
|
task->method()->set_queued_for_compilation();
|
||||||
@ -487,6 +491,7 @@ void CompileQueue::remove(CompileTask* task) {
|
|||||||
_last = task->prev();
|
_last = task->prev();
|
||||||
}
|
}
|
||||||
--_size;
|
--_size;
|
||||||
|
++_total_removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompileQueue::remove_and_mark_stale(CompileTask* task) {
|
void CompileQueue::remove_and_mark_stale(CompileTask* task) {
|
||||||
@ -516,6 +521,14 @@ CompileQueue* CompileBroker::compile_queue(int comp_level) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompileQueue* CompileBroker::c1_compile_queue() {
|
||||||
|
return _c1_compile_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompileQueue* CompileBroker::c2_compile_queue() {
|
||||||
|
return _c2_compile_queue;
|
||||||
|
}
|
||||||
|
|
||||||
void CompileBroker::print_compile_queues(outputStream* st) {
|
void CompileBroker::print_compile_queues(outputStream* st) {
|
||||||
st->print_cr("Current compiles: ");
|
st->print_cr("Current compiles: ");
|
||||||
|
|
||||||
|
@ -88,6 +88,9 @@ class CompileQueue : public CHeapObj<mtCompiler> {
|
|||||||
CompileTask* _first_stale;
|
CompileTask* _first_stale;
|
||||||
|
|
||||||
int _size;
|
int _size;
|
||||||
|
int _peak_size;
|
||||||
|
uint _total_added;
|
||||||
|
uint _total_removed;
|
||||||
|
|
||||||
void purge_stale_tasks();
|
void purge_stale_tasks();
|
||||||
public:
|
public:
|
||||||
@ -96,6 +99,9 @@ class CompileQueue : public CHeapObj<mtCompiler> {
|
|||||||
_first = nullptr;
|
_first = nullptr;
|
||||||
_last = nullptr;
|
_last = nullptr;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
|
_total_added = 0;
|
||||||
|
_total_removed = 0;
|
||||||
|
_peak_size = 0;
|
||||||
_first_stale = nullptr;
|
_first_stale = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +118,9 @@ class CompileQueue : public CHeapObj<mtCompiler> {
|
|||||||
bool is_empty() const { return _first == nullptr; }
|
bool is_empty() const { return _first == nullptr; }
|
||||||
int size() const { return _size; }
|
int size() const { return _size; }
|
||||||
|
|
||||||
|
int get_peak_size() const { return _peak_size; }
|
||||||
|
uint get_total_added() const { return _total_added; }
|
||||||
|
uint get_total_removed() const { return _total_removed; }
|
||||||
|
|
||||||
// Redefine Classes support
|
// Redefine Classes support
|
||||||
void mark_on_stack();
|
void mark_on_stack();
|
||||||
@ -302,6 +311,9 @@ public:
|
|||||||
int hot_count,
|
int hot_count,
|
||||||
CompileTask::CompileReason compile_reason,
|
CompileTask::CompileReason compile_reason,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
|
static CompileQueue* c1_compile_queue();
|
||||||
|
static CompileQueue* c2_compile_queue();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static nmethod* compile_method(const methodHandle& method,
|
static nmethod* compile_method(const methodHandle& method,
|
||||||
int osr_bci,
|
int osr_bci,
|
||||||
@ -399,6 +411,8 @@ public:
|
|||||||
|
|
||||||
static CompileLog* get_log(CompilerThread* ct);
|
static CompileLog* get_log(CompilerThread* ct);
|
||||||
|
|
||||||
|
static int get_c1_thread_count() { return _compilers[0]->num_compiler_threads(); }
|
||||||
|
static int get_c2_thread_count() { return _compilers[1]->num_compiler_threads(); }
|
||||||
static int get_total_compile_count() { return _total_compile_count; }
|
static int get_total_compile_count() { return _total_compile_count; }
|
||||||
static int get_total_bailout_count() { return _total_bailout_count; }
|
static int get_total_bailout_count() { return _total_bailout_count; }
|
||||||
static int get_total_invalidated_count() { return _total_invalidated_count; }
|
static int get_total_invalidated_count() { return _total_invalidated_count; }
|
||||||
|
@ -848,6 +848,19 @@
|
|||||||
<Field type="float" contentType="hertz" name="switchRate" label="Switch Rate" description="Number of context switches per second" />
|
<Field type="float" contentType="hertz" name="switchRate" label="Switch Rate" description="Number of context switches per second" />
|
||||||
</Event>
|
</Event>
|
||||||
|
|
||||||
|
<Event name="CompilerQueueUtilization" category="Java Virtual Machine, Compiler" label="Compiler Queue Utilization" period="everyChunk">
|
||||||
|
<Field type="CompilerType" name="compiler" label="Compiler" />
|
||||||
|
<Field type="long" contentType="hertz" name="addedRate" label="Requets Added Rate" description="Requests added per second"/>
|
||||||
|
<Field type="long" contentType="hertz" name="removedRate" label="Requests Removed Rate" description="Requests removed per second"/>
|
||||||
|
<Field type="long" name="queueSize" label="Queue Size"/>
|
||||||
|
<Field type="long" name="peakQueueSize" label="Peak Queue Size"/>
|
||||||
|
<Field type="long" name="addedCount" label="Requests Added"/>
|
||||||
|
<Field type="long" name="removedCount" label="Requests Removed"/>
|
||||||
|
<Field type="long" name="totalAddedCount" label="Total Requests Added"/>
|
||||||
|
<Field type="long" name="totalRemovedCount" label="Total Requests Removed"/>
|
||||||
|
<Field type="int" name="compilerThreadCount" label="Compiler Thread Count"/>
|
||||||
|
</Event>
|
||||||
|
|
||||||
<Event name="NetworkUtilization" category="Operating System, Network" label="Network Utilization" period="everyChunk">
|
<Event name="NetworkUtilization" category="Operating System, Network" label="Network Utilization" period="everyChunk">
|
||||||
<Field type="NetworkInterfaceName" name="networkInterface" label="Network Interface" description="Network Interface Name"/>
|
<Field type="NetworkInterfaceName" name="networkInterface" label="Network Interface" description="Network Interface Name"/>
|
||||||
<Field type="long" contentType="bits-per-second" name="readRate" label="Read Rate" description="Number of incoming bits per second"/>
|
<Field type="long" contentType="bits-per-second" name="readRate" label="Read Rate" description="Number of incoming bits per second"/>
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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 "compiler/compileBroker.hpp"
|
||||||
|
#include "jfr/jfrEvents.hpp"
|
||||||
|
#include "jfr/periodic/jfrCompilerQueueUtilization.hpp"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
c1_compiler_queue_id = 1,
|
||||||
|
c2_compiler_queue_id = 2,
|
||||||
|
num_compiler_queues = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*GET_COMPILER_THREAD_COUNT)();
|
||||||
|
|
||||||
|
struct CompilerQueueEntry {
|
||||||
|
CompileQueue* compilerQueue;
|
||||||
|
u8 compiler_queue_id;
|
||||||
|
GET_COMPILER_THREAD_COUNT get_compiler_thread_count;
|
||||||
|
uint64_t added;
|
||||||
|
uint64_t removed;
|
||||||
|
};
|
||||||
|
|
||||||
|
// If current counters are less than previous, we assume the interface has been reset
|
||||||
|
// If no bytes have been either sent or received, we'll also skip the event
|
||||||
|
static uint64_t rate_per_second(uint64_t current, uint64_t old, const JfrTickspan& interval) {
|
||||||
|
assert(interval.value() > 0, "invariant");
|
||||||
|
if (current <= old) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ((current - old) * NANOSECS_PER_SEC) / interval.nanoseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JfrCompilerQueueUtilization::send_events() {
|
||||||
|
static CompilerQueueEntry compilerQueueEntries[num_compiler_queues] = {
|
||||||
|
{CompileBroker::c1_compile_queue(), c1_compiler_queue_id, &CompileBroker::get_c1_thread_count, 0, 0},
|
||||||
|
{CompileBroker::c2_compile_queue(), c2_compiler_queue_id, &CompileBroker::get_c2_thread_count, 0, 0}};
|
||||||
|
|
||||||
|
const JfrTicks cur_time = JfrTicks::now();
|
||||||
|
static JfrTicks last_sample_instant;
|
||||||
|
const JfrTickspan interval = cur_time - last_sample_instant;
|
||||||
|
for (int i = 0; i < num_compiler_queues; i ++) {
|
||||||
|
CompilerQueueEntry* entry = &compilerQueueEntries[i];
|
||||||
|
if (entry->compilerQueue != nullptr) {
|
||||||
|
const uint64_t current_added = entry->compilerQueue->get_total_added();
|
||||||
|
const uint64_t current_removed = entry->compilerQueue->get_total_removed();
|
||||||
|
const uint64_t addedRate = rate_per_second(current_added, entry->added, interval);
|
||||||
|
const uint64_t removedRate = rate_per_second(current_removed, entry->removed, interval);
|
||||||
|
|
||||||
|
EventCompilerQueueUtilization event;
|
||||||
|
event.set_compiler(entry->compiler_queue_id);
|
||||||
|
event.set_addedRate(addedRate);
|
||||||
|
event.set_removedRate(removedRate);
|
||||||
|
event.set_queueSize(entry->compilerQueue->size());
|
||||||
|
event.set_peakQueueSize(entry->compilerQueue->get_peak_size());
|
||||||
|
event.set_addedCount(current_added - entry->added);
|
||||||
|
event.set_removedCount(current_removed - entry->removed);
|
||||||
|
event.set_totalAddedCount(current_added);
|
||||||
|
event.set_totalRemovedCount(current_removed);
|
||||||
|
event.set_compilerThreadCount(entry->get_compiler_thread_count());
|
||||||
|
event.commit();
|
||||||
|
|
||||||
|
entry->added = current_added;
|
||||||
|
entry->removed = current_removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_sample_instant = cur_time;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHARE_JFR_PERIODIC_JFRCOMPILERQUEUEUTILIZATION_HPP
|
||||||
|
#define SHARE_JFR_PERIODIC_JFRCOMPILERQUEUEUTILIZATION_HPP
|
||||||
|
|
||||||
|
#include "memory/allStatic.hpp"
|
||||||
|
|
||||||
|
class JfrCompilerQueueUtilization : public AllStatic {
|
||||||
|
public:
|
||||||
|
static void send_events();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SHARE_JFR_PERIODIC_JFRCOMPILERQUEUEUTILIZATION_HPP
|
@ -36,6 +36,7 @@
|
|||||||
#include "gc/shared/gcVMOperations.hpp"
|
#include "gc/shared/gcVMOperations.hpp"
|
||||||
#include "gc/shared/objectCountEventSender.hpp"
|
#include "gc/shared/objectCountEventSender.hpp"
|
||||||
#include "jfr/jfrEvents.hpp"
|
#include "jfr/jfrEvents.hpp"
|
||||||
|
#include "jfr/periodic/jfrCompilerQueueUtilization.hpp"
|
||||||
#include "jfr/periodic/jfrFinalizerStatisticsEvent.hpp"
|
#include "jfr/periodic/jfrFinalizerStatisticsEvent.hpp"
|
||||||
#include "jfr/periodic/jfrModuleEvent.hpp"
|
#include "jfr/periodic/jfrModuleEvent.hpp"
|
||||||
#include "jfr/periodic/jfrOSInterface.hpp"
|
#include "jfr/periodic/jfrOSInterface.hpp"
|
||||||
@ -221,6 +222,10 @@ TRACE_REQUEST_FUNC(ThreadCPULoad) {
|
|||||||
JfrThreadCPULoadEvent::send_events();
|
JfrThreadCPULoadEvent::send_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE_REQUEST_FUNC(CompilerQueueUtilization) {
|
||||||
|
JfrCompilerQueueUtilization::send_events();
|
||||||
|
}
|
||||||
|
|
||||||
TRACE_REQUEST_FUNC(NetworkUtilization) {
|
TRACE_REQUEST_FUNC(NetworkUtilization) {
|
||||||
JfrNetworkUtilization::send_events();
|
JfrNetworkUtilization::send_events();
|
||||||
}
|
}
|
||||||
|
@ -663,6 +663,11 @@
|
|||||||
<setting name="period">5 s</setting>
|
<setting name="period">5 s</setting>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<event name="jdk.CompilerQueueUtilization">
|
||||||
|
<setting name="enabled">true</setting>
|
||||||
|
<setting name="period">10 s</setting>
|
||||||
|
</event>
|
||||||
|
|
||||||
<event name="jdk.InitialEnvironmentVariable">
|
<event name="jdk.InitialEnvironmentVariable">
|
||||||
<setting name="enabled">true</setting>
|
<setting name="enabled">true</setting>
|
||||||
<setting name="period">beginChunk</setting>
|
<setting name="period">beginChunk</setting>
|
||||||
|
@ -663,6 +663,11 @@
|
|||||||
<setting name="period">5 s</setting>
|
<setting name="period">5 s</setting>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<event name="jdk.CompilerQueueUtilization">
|
||||||
|
<setting name="enabled">true</setting>
|
||||||
|
<setting name="period">5 s</setting>
|
||||||
|
</event>
|
||||||
|
|
||||||
<event name="jdk.InitialEnvironmentVariable">
|
<event name="jdk.InitialEnvironmentVariable">
|
||||||
<setting name="enabled">true</setting>
|
<setting name="enabled">true</setting>
|
||||||
<setting name="period">beginChunk</setting>
|
<setting name="period">beginChunk</setting>
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package jdk.jfr.event.compiler;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jdk.jfr.Recording;
|
||||||
|
import jdk.jfr.consumer.RecordedEvent;
|
||||||
|
import jdk.test.lib.jfr.EventNames;
|
||||||
|
import jdk.test.lib.jfr.Events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @key jfr
|
||||||
|
* @requires vm.hasJFR
|
||||||
|
* @requires vm.compMode!="Xint"
|
||||||
|
* @library /test/lib
|
||||||
|
* @run main/othervm jdk.jfr.event.compiler.TestCompilerQueueUtilization
|
||||||
|
*/
|
||||||
|
public class TestCompilerQueueUtilization {
|
||||||
|
private final static String EVENT_NAME = EventNames.CompilerQueueUtilization;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
try (Recording recording = new Recording()) {
|
||||||
|
recording.enable(EVENT_NAME);
|
||||||
|
recording.start();
|
||||||
|
recording.stop();
|
||||||
|
|
||||||
|
List<RecordedEvent> events = Events.fromRecording(recording);
|
||||||
|
Events.hasEvents(events);
|
||||||
|
for (RecordedEvent event : events) {
|
||||||
|
System.out.println("Event:" + event);
|
||||||
|
Events.assertField(event, "compiler").notEmpty();
|
||||||
|
Events.assertField(event, "addedRate").atLeast(0L);
|
||||||
|
Events.assertField(event, "removedRate").atLeast(0L);
|
||||||
|
Events.assertField(event, "queueSize").atLeast(0L);
|
||||||
|
Events.assertField(event, "peakQueueSize").atLeast(0L);
|
||||||
|
Events.assertField(event, "addedCount").atLeast(0L);
|
||||||
|
Events.assertField(event, "removedCount").atLeast(0L);
|
||||||
|
Events.assertField(event, "totalAddedCount").atLeast(0L);
|
||||||
|
Events.assertField(event, "totalRemovedCount").atLeast(0L);
|
||||||
|
Events.assertField(event, "compilerThreadCount").atLeast(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -160,6 +160,7 @@ public class EventNames {
|
|||||||
public static final String CompilerPhase = PREFIX + "CompilerPhase";
|
public static final String CompilerPhase = PREFIX + "CompilerPhase";
|
||||||
public static final String CompilationFailure = PREFIX + "CompilationFailure";
|
public static final String CompilationFailure = PREFIX + "CompilationFailure";
|
||||||
public static final String CompilerInlining = PREFIX + "CompilerInlining";
|
public static final String CompilerInlining = PREFIX + "CompilerInlining";
|
||||||
|
public static final String CompilerQueueUtilization = PREFIX + "CompilerQueueUtilization";
|
||||||
public static final String CompilerStatistics = PREFIX + "CompilerStatistics";
|
public static final String CompilerStatistics = PREFIX + "CompilerStatistics";
|
||||||
public static final String CompilerConfiguration = PREFIX + "CompilerConfiguration";
|
public static final String CompilerConfiguration = PREFIX + "CompilerConfiguration";
|
||||||
public static final String CodeCacheStatistics = PREFIX + "CodeCacheStatistics";
|
public static final String CodeCacheStatistics = PREFIX + "CodeCacheStatistics";
|
||||||
|
Loading…
Reference in New Issue
Block a user