8317562: [JFR] Compilation queue statistics

Reviewed-by: kvn
This commit is contained in:
Mat Carter 2023-11-13 20:56:58 +00:00 committed by Vladimir Kozlov
parent 965ae72964
commit d992033439
10 changed files with 249 additions and 0 deletions

View File

@ -331,6 +331,10 @@ void CompileQueue::add(CompileTask* task) {
_last = task;
}
++_size;
++_total_added;
if (_size > _peak_size) {
_peak_size = _size;
}
// Mark the method as being in the compile queue.
task->method()->set_queued_for_compilation();
@ -487,6 +491,7 @@ void CompileQueue::remove(CompileTask* task) {
_last = task->prev();
}
--_size;
++_total_removed;
}
void CompileQueue::remove_and_mark_stale(CompileTask* task) {
@ -516,6 +521,14 @@ CompileQueue* CompileBroker::compile_queue(int comp_level) {
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) {
st->print_cr("Current compiles: ");

View File

@ -88,6 +88,9 @@ class CompileQueue : public CHeapObj<mtCompiler> {
CompileTask* _first_stale;
int _size;
int _peak_size;
uint _total_added;
uint _total_removed;
void purge_stale_tasks();
public:
@ -96,6 +99,9 @@ class CompileQueue : public CHeapObj<mtCompiler> {
_first = nullptr;
_last = nullptr;
_size = 0;
_total_added = 0;
_total_removed = 0;
_peak_size = 0;
_first_stale = nullptr;
}
@ -112,6 +118,9 @@ class CompileQueue : public CHeapObj<mtCompiler> {
bool is_empty() const { return _first == nullptr; }
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
void mark_on_stack();
@ -302,6 +311,9 @@ public:
int hot_count,
CompileTask::CompileReason compile_reason,
TRAPS);
static CompileQueue* c1_compile_queue();
static CompileQueue* c2_compile_queue();
private:
static nmethod* compile_method(const methodHandle& method,
int osr_bci,
@ -399,6 +411,8 @@ public:
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_bailout_count() { return _total_bailout_count; }
static int get_total_invalidated_count() { return _total_invalidated_count; }

View File

@ -848,6 +848,19 @@
<Field type="float" contentType="hertz" name="switchRate" label="Switch Rate" description="Number of context switches per second" />
</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">
<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"/>

View File

@ -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;
}
}

View File

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

View File

@ -36,6 +36,7 @@
#include "gc/shared/gcVMOperations.hpp"
#include "gc/shared/objectCountEventSender.hpp"
#include "jfr/jfrEvents.hpp"
#include "jfr/periodic/jfrCompilerQueueUtilization.hpp"
#include "jfr/periodic/jfrFinalizerStatisticsEvent.hpp"
#include "jfr/periodic/jfrModuleEvent.hpp"
#include "jfr/periodic/jfrOSInterface.hpp"
@ -221,6 +222,10 @@ TRACE_REQUEST_FUNC(ThreadCPULoad) {
JfrThreadCPULoadEvent::send_events();
}
TRACE_REQUEST_FUNC(CompilerQueueUtilization) {
JfrCompilerQueueUtilization::send_events();
}
TRACE_REQUEST_FUNC(NetworkUtilization) {
JfrNetworkUtilization::send_events();
}

View File

@ -663,6 +663,11 @@
<setting name="period">5 s</setting>
</event>
<event name="jdk.CompilerQueueUtilization">
<setting name="enabled">true</setting>
<setting name="period">10 s</setting>
</event>
<event name="jdk.InitialEnvironmentVariable">
<setting name="enabled">true</setting>
<setting name="period">beginChunk</setting>

View File

@ -663,6 +663,11 @@
<setting name="period">5 s</setting>
</event>
<event name="jdk.CompilerQueueUtilization">
<setting name="enabled">true</setting>
<setting name="period">5 s</setting>
</event>
<event name="jdk.InitialEnvironmentVariable">
<setting name="enabled">true</setting>
<setting name="period">beginChunk</setting>

View File

@ -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);
}
}
}
}

View File

@ -160,6 +160,7 @@ public class EventNames {
public static final String CompilerPhase = PREFIX + "CompilerPhase";
public static final String CompilationFailure = PREFIX + "CompilationFailure";
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 CompilerConfiguration = PREFIX + "CompilerConfiguration";
public static final String CodeCacheStatistics = PREFIX + "CodeCacheStatistics";