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;
|
||||
}
|
||||
++_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: ");
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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"/>
|
||||
|
@ -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/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();
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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 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";
|
||||
|
Loading…
Reference in New Issue
Block a user