8329488: Move OopStorage code from safepoint cleanup and remove safepoint cleanup code

Reviewed-by: kbarrett, eosterlund
This commit is contained in:
Coleen Phillimore 2024-04-12 12:16:49 +00:00
parent 77a217df60
commit 3e9c381166
14 changed files with 54 additions and 281 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -410,7 +410,7 @@ OopStorage::Block::block_for_ptr(const OopStorage* owner, const oop* ptr) {
// allocations until some entries in it are released. // allocations until some entries in it are released.
// //
// release() is performed lock-free. (Note: This means it can't notify the // release() is performed lock-free. (Note: This means it can't notify the
// service thread of pending cleanup work. It must be lock-free because // ServiceThread of pending cleanup work. It must be lock-free because
// it is called in all kinds of contexts where even quite low ranked locks // it is called in all kinds of contexts where even quite low ranked locks
// may be held.) release() first looks up the block for // may be held.) release() first looks up the block for
// the entry, using address alignment to find the enclosing block (thereby // the entry, using address alignment to find the enclosing block (thereby
@ -705,7 +705,7 @@ void OopStorage::Block::release_entries(uintx releasing, OopStorage* owner) {
// Only request cleanup for to-empty transitions, not for from-full. // Only request cleanup for to-empty transitions, not for from-full.
// There isn't any rush to process from-full transitions. Allocation // There isn't any rush to process from-full transitions. Allocation
// will reduce deferrals before allocating new blocks, so may process // will reduce deferrals before allocating new blocks, so may process
// some. And the service thread will drain the entire deferred list // some. And the ServiceThread will drain the entire deferred list
// if there are any pending to-empty transitions. // if there are any pending to-empty transitions.
if (releasing == old_allocated) { if (releasing == old_allocated) {
owner->record_needs_cleanup(); owner->record_needs_cleanup();
@ -880,67 +880,51 @@ bool OopStorage::should_report_num_dead() const {
} }
// Managing service thread notifications. // Managing service thread notifications.
//
// We don't want cleanup work to linger indefinitely, but we also don't want
// to run the service thread too often. We're also very limited in what we
// can do in a release operation, where cleanup work is created.
//
// When a release operation changes a block's state to empty, it records the // When a release operation changes a block's state to empty, it records the
// need for cleanup in both the associated storage object and in the global // need for cleanup in both the associated storage object and in the global
// request state. A safepoint cleanup task notifies the service thread when // request state. The ServiceThread checks at timed intervals if
// there may be cleanup work for any storage object, based on the global // there may be cleanup work for any storage object, based on the global
// request state. But that notification is deferred if the service thread // request state. We don't want to run empty block cleanup too often in the
// has run recently, and we also avoid duplicate notifications. The service // face of frequent explicit ServiceThread wakeups, hence the defer period.
// thread updates the timestamp and resets the state flags on every iteration.
// Global cleanup request state. // Global cleanup request state.
static volatile bool needs_cleanup_requested = false; static volatile bool needs_cleanup_requested = false;
// Flag for avoiding duplicate notifications. // Time after which a cleanup is permitted.
static bool needs_cleanup_triggered = false; static jlong cleanup_permit_time = 0;
// Time after which a notification can be made. // Minimum time between ServiceThread cleanups.
static jlong cleanup_trigger_permit_time = 0; // The value of 500ms was an arbitrary choice; frequent, but not too frequent.
const jlong cleanup_defer_period = 500 * NANOSECS_PER_MILLISEC;
// Minimum time since last service thread check before notification is
// permitted. The value of 500ms was an arbitrary choice; frequent, but not
// too frequent.
const jlong cleanup_trigger_defer_period = 500 * NANOSECS_PER_MILLISEC;
void OopStorage::trigger_cleanup_if_needed() {
MonitorLocker ml(Service_lock, Monitor::_no_safepoint_check_flag);
if (Atomic::load(&needs_cleanup_requested) &&
!needs_cleanup_triggered &&
(os::javaTimeNanos() > cleanup_trigger_permit_time)) {
needs_cleanup_triggered = true;
ml.notify_all();
}
}
bool OopStorage::has_cleanup_work_and_reset() { bool OopStorage::has_cleanup_work_and_reset() {
assert_lock_strong(Service_lock); assert_lock_strong(Service_lock);
cleanup_trigger_permit_time =
os::javaTimeNanos() + cleanup_trigger_defer_period; if (Atomic::load_acquire(&needs_cleanup_requested) &&
needs_cleanup_triggered = false; os::javaTimeNanos() > cleanup_permit_time) {
// Set the request flag false and return its old value. cleanup_permit_time =
// Needs to be atomic to avoid dropping a concurrent request. os::javaTimeNanos() + cleanup_defer_period;
// Can't use Atomic::xchg, which may not support bool. // Set the request flag false and return its old value.
return Atomic::cmpxchg(&needs_cleanup_requested, true, false); Atomic::release_store(&needs_cleanup_requested, false);
return true;
} else {
return false;
}
} }
// Record that cleanup is needed, without notifying the Service thread. // Record that cleanup is needed, without notifying the Service thread, because
// Used by release(), where we can't lock even Service_lock. // we can't lock the Service_lock. Used by release().
void OopStorage::record_needs_cleanup() { void OopStorage::record_needs_cleanup() {
// Set local flag first, else service thread could wake up and miss // Set local flag first, else ServiceThread could wake up and miss
// the request. This order may instead (rarely) unnecessarily notify. // the request.
Atomic::release_store(&_needs_cleanup, true); Atomic::release_store(&_needs_cleanup, true);
Atomic::release_store_fence(&needs_cleanup_requested, true); Atomic::release_store_fence(&needs_cleanup_requested, true);
} }
bool OopStorage::delete_empty_blocks() { bool OopStorage::delete_empty_blocks() {
// Service thread might have oopstorage work, but not for this object. // ServiceThread might have oopstorage work, but not for this object.
// Check for deferred updates even though that's not a service thread // But check for deferred updates, which might provide cleanup work.
// trigger; since we're here, we might as well process them.
if (!Atomic::load_acquire(&_needs_cleanup) && if (!Atomic::load_acquire(&_needs_cleanup) &&
(Atomic::load_acquire(&_deferred_updates) == nullptr)) { (Atomic::load_acquire(&_deferred_updates) == nullptr)) {
return false; return false;
@ -986,7 +970,7 @@ bool OopStorage::delete_empty_blocks() {
// Don't interfere with an active concurrent iteration. // Don't interfere with an active concurrent iteration.
// Instead, give up immediately. There is more work to do, // Instead, give up immediately. There is more work to do,
// but don't re-notify, to avoid useless spinning of the // but don't re-notify, to avoid useless spinning of the
// service thread. Instead, iteration completion notifies. // ServiceThread. Instead, iteration completion notifies.
if (_concurrent_iteration_count > 0) return true; if (_concurrent_iteration_count > 0) return true;
_active_array->remove(block); _active_array->remove(block);
} }
@ -998,10 +982,8 @@ bool OopStorage::delete_empty_blocks() {
ThreadBlockInVM tbiv(JavaThread::current()); ThreadBlockInVM tbiv(JavaThread::current());
} }
} }
// Exceeded work limit or can't delete last block. This will // Exceeded work limit or can't delete last block so still needs cleanup
// cause the service thread to loop, giving other subtasks an // for the next time.
// opportunity to run too. There's no need for a notification,
// because we are part of the service thread (unless gtesting).
record_needs_cleanup(); record_needs_cleanup();
return true; return true;
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it This code is free software; you can redistribute it and/or modify it
@ -684,17 +684,6 @@
<Field type="int" name="iterations" label="Iterations" description="Number of state check iterations" /> <Field type="int" name="iterations" label="Iterations" description="Number of state check iterations" />
</Event> </Event>
<Event name="SafepointCleanup" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Cleanup" description="Safepointing begin running cleanup tasks"
thread="true">
<Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
</Event>
<Event name="SafepointCleanupTask" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Cleanup Task" description="Safepointing begin running cleanup tasks"
thread="true">
<Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
<Field type="string" name="name" label="Task Name" description="The task name" />
</Event>
<Event name="SafepointEnd" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint End" description="Safepointing end" thread="true"> <Event name="SafepointEnd" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint End" description="Safepointing end" thread="true">
<Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" /> <Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
</Event> </Event>

View File

@ -1282,6 +1282,11 @@ const int ObjectAlignmentInBytes = 8;
"(0 means none)") \ "(0 means none)") \
range(0, max_jint) \ range(0, max_jint) \
\ \
product(intx, ServiceThreadCleanupInterval, 1000, DIAGNOSTIC, \
"Wake the ServiceThread to do periodic cleanup checks every so " \
"many milliseconds (0 means none)") \
range(0, max_jint) \
\
product(double, SafepointTimeoutDelay, 10000, \ product(double, SafepointTimeoutDelay, 10000, \
"Delay in milliseconds for option SafepointTimeout; " \ "Delay in milliseconds for option SafepointTimeout; " \
"supports sub-millisecond resolution with fractional values.") \ "supports sub-millisecond resolution with fractional values.") \

View File

@ -80,12 +80,6 @@ static void post_safepoint_begin_event(EventSafepointBegin& event,
} }
} }
static void post_safepoint_cleanup_event(EventSafepointCleanup& event, uint64_t safepoint_id) {
if (event.should_commit()) {
event.set_safepointId(safepoint_id);
event.commit();
}
}
static void post_safepoint_synchronize_event(EventSafepointStateSynchronization& event, static void post_safepoint_synchronize_event(EventSafepointStateSynchronization& event,
uint64_t safepoint_id, uint64_t safepoint_id,
@ -101,16 +95,6 @@ static void post_safepoint_synchronize_event(EventSafepointStateSynchronization&
} }
} }
static void post_safepoint_cleanup_task_event(EventSafepointCleanupTask& event,
uint64_t safepoint_id,
const char* name) {
if (event.should_commit()) {
event.set_safepointId(safepoint_id);
event.set_name(name);
event.commit();
}
}
static void post_safepoint_end_event(EventSafepointEnd& event, uint64_t safepoint_id) { static void post_safepoint_end_event(EventSafepointEnd& event, uint64_t safepoint_id) {
if (event.should_commit()) { if (event.should_commit()) {
event.set_safepointId(safepoint_id); event.set_safepointId(safepoint_id);
@ -435,14 +419,7 @@ void SafepointSynchronize::begin() {
SafepointTracing::synchronized(nof_threads, initial_running, _nof_threads_hit_polling_page); SafepointTracing::synchronized(nof_threads, initial_running, _nof_threads_hit_polling_page);
// We do the safepoint cleanup first since a GC related safepoint
// needs cleanup to be completed before running the GC op.
EventSafepointCleanup cleanup_event;
do_cleanup_tasks();
post_safepoint_cleanup_event(cleanup_event, _safepoint_id);
post_safepoint_begin_event(begin_event, _safepoint_id, nof_threads, _current_jni_active_count); post_safepoint_begin_event(begin_event, _safepoint_id, nof_threads, _current_jni_active_count);
SafepointTracing::cleanup();
} }
void SafepointSynchronize::disarm_safepoint() { void SafepointSynchronize::disarm_safepoint() {
@ -507,68 +484,6 @@ void SafepointSynchronize::end() {
post_safepoint_end_event(event, safepoint_id()); post_safepoint_end_event(event, safepoint_id());
} }
class ParallelCleanupTask : public WorkerTask {
private:
SubTasksDone _subtasks;
class Tracer {
private:
const char* _name;
EventSafepointCleanupTask _event;
TraceTime _timer;
public:
Tracer(const char* name) :
_name(name),
_event(),
_timer(name, TRACETIME_LOG(Info, safepoint, cleanup)) {}
~Tracer() {
post_safepoint_cleanup_task_event(_event, SafepointSynchronize::safepoint_id(), _name);
}
};
public:
ParallelCleanupTask() :
WorkerTask("Parallel Safepoint Cleanup"),
_subtasks(SafepointSynchronize::SAFEPOINT_CLEANUP_NUM_TASKS) {}
uint expected_num_workers() const {
uint workers = 0;
return MAX2<uint>(1, workers);
}
void work(uint worker_id) {
if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_REQUEST_OOPSTORAGE_CLEANUP)) {
// Don't bother reporting event or time for this very short operation.
// To have any utility we'd also want to report whether needed.
OopStorage::trigger_cleanup_if_needed();
}
_subtasks.all_tasks_claimed();
}
};
// Various cleaning tasks that should be done periodically at safepoints.
void SafepointSynchronize::do_cleanup_tasks() {
TraceTime timer("safepoint cleanup tasks", TRACETIME_LOG(Info, safepoint, cleanup));
CollectedHeap* heap = Universe::heap();
assert(heap != nullptr, "heap not initialized yet?");
ParallelCleanupTask cleanup;
WorkerThreads* cleanup_workers = heap->safepoint_workers();
const uint expected_num_workers = cleanup.expected_num_workers();
if (cleanup_workers != nullptr && expected_num_workers > 1) {
// Parallel cleanup using GC provided thread pool.
const uint num_workers = MIN2(expected_num_workers, cleanup_workers->active_workers());
cleanup_workers->run_task(&cleanup, num_workers);
} else {
// Serial cleanup using VMThread.
cleanup.work(0);
}
}
// Methods for determining if a JavaThread is safepoint safe. // Methods for determining if a JavaThread is safepoint safe.
// False means unsafe with undetermined state. // False means unsafe with undetermined state.
@ -946,7 +861,6 @@ void ThreadSafepointState::handle_polling_page_exception() {
jlong SafepointTracing::_last_safepoint_begin_time_ns = 0; jlong SafepointTracing::_last_safepoint_begin_time_ns = 0;
jlong SafepointTracing::_last_safepoint_sync_time_ns = 0; jlong SafepointTracing::_last_safepoint_sync_time_ns = 0;
jlong SafepointTracing::_last_safepoint_cleanup_time_ns = 0;
jlong SafepointTracing::_last_safepoint_end_time_ns = 0; jlong SafepointTracing::_last_safepoint_end_time_ns = 0;
jlong SafepointTracing::_last_app_time_ns = 0; jlong SafepointTracing::_last_app_time_ns = 0;
int SafepointTracing::_nof_threads = 0; int SafepointTracing::_nof_threads = 0;
@ -954,7 +868,6 @@ int SafepointTracing::_nof_running = 0;
int SafepointTracing::_page_trap = 0; int SafepointTracing::_page_trap = 0;
VM_Operation::VMOp_Type SafepointTracing::_current_type; VM_Operation::VMOp_Type SafepointTracing::_current_type;
jlong SafepointTracing::_max_sync_time = 0; jlong SafepointTracing::_max_sync_time = 0;
jlong SafepointTracing::_max_cleanup_time = 0;
jlong SafepointTracing::_max_vmop_time = 0; jlong SafepointTracing::_max_vmop_time = 0;
uint64_t SafepointTracing::_op_count[VM_Operation::VMOp_Terminating] = {0}; uint64_t SafepointTracing::_op_count[VM_Operation::VMOp_Terminating] = {0};
@ -970,7 +883,7 @@ static void print_header(outputStream* st) {
st->print("VM Operation " st->print("VM Operation "
"[ threads: total initial_running ]" "[ threads: total initial_running ]"
"[ time: sync cleanup vmop total ]"); "[ time: sync vmop total ]");
st->print_cr(" page_trap_count"); st->print_cr(" page_trap_count");
} }
@ -999,11 +912,9 @@ void SafepointTracing::statistics_log() {
_nof_threads, _nof_threads,
_nof_running); _nof_running);
ls.print("[ " ls.print("[ "
INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " ]",
INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " ]",
(int64_t)(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns), (int64_t)(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns),
(int64_t)(_last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns), (int64_t)(_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns),
(int64_t)(_last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns),
(int64_t)(_last_safepoint_end_time_ns - _last_safepoint_begin_time_ns)); (int64_t)(_last_safepoint_end_time_ns - _last_safepoint_begin_time_ns));
ls.print_cr(INT32_FORMAT_W(16), _page_trap); ls.print_cr(INT32_FORMAT_W(16), _page_trap);
@ -1024,8 +935,6 @@ void SafepointTracing::statistics_exit_log() {
log_info(safepoint, stats)("Maximum sync time " INT64_FORMAT" ns", log_info(safepoint, stats)("Maximum sync time " INT64_FORMAT" ns",
(int64_t)(_max_sync_time)); (int64_t)(_max_sync_time));
log_info(safepoint, stats)("Maximum cleanup time " INT64_FORMAT" ns",
(int64_t)(_max_cleanup_time));
log_info(safepoint, stats)("Maximum vm operation time (except for Exit VM operation) " log_info(safepoint, stats)("Maximum vm operation time (except for Exit VM operation) "
INT64_FORMAT " ns", INT64_FORMAT " ns",
(int64_t)(_max_vmop_time)); (int64_t)(_max_vmop_time));
@ -1038,7 +947,6 @@ void SafepointTracing::begin(VM_Operation::VMOp_Type type) {
// update the time stamp to begin recording safepoint time // update the time stamp to begin recording safepoint time
_last_safepoint_begin_time_ns = os::javaTimeNanos(); _last_safepoint_begin_time_ns = os::javaTimeNanos();
_last_safepoint_sync_time_ns = 0; _last_safepoint_sync_time_ns = 0;
_last_safepoint_cleanup_time_ns = 0;
_last_app_time_ns = _last_safepoint_begin_time_ns - _last_safepoint_end_time_ns; _last_app_time_ns = _last_safepoint_begin_time_ns - _last_safepoint_end_time_ns;
_last_safepoint_end_time_ns = 0; _last_safepoint_end_time_ns = 0;
@ -1054,19 +962,12 @@ void SafepointTracing::synchronized(int nof_threads, int nof_running, int traps)
RuntimeService::record_safepoint_synchronized(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns); RuntimeService::record_safepoint_synchronized(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns);
} }
void SafepointTracing::cleanup() {
_last_safepoint_cleanup_time_ns = os::javaTimeNanos();
}
void SafepointTracing::end() { void SafepointTracing::end() {
_last_safepoint_end_time_ns = os::javaTimeNanos(); _last_safepoint_end_time_ns = os::javaTimeNanos();
if (_max_sync_time < (_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns)) { if (_max_sync_time < (_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns)) {
_max_sync_time = _last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns; _max_sync_time = _last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns;
} }
if (_max_cleanup_time < (_last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns)) {
_max_cleanup_time = _last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns;
}
if (_max_vmop_time < (_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns)) { if (_max_vmop_time < (_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns)) {
_max_vmop_time = _last_safepoint_end_time_ns - _last_safepoint_sync_time_ns; _max_vmop_time = _last_safepoint_end_time_ns - _last_safepoint_sync_time_ns;
} }
@ -1078,14 +979,12 @@ void SafepointTracing::end() {
"Safepoint \"%s\", " "Safepoint \"%s\", "
"Time since last: " JLONG_FORMAT " ns, " "Time since last: " JLONG_FORMAT " ns, "
"Reaching safepoint: " JLONG_FORMAT " ns, " "Reaching safepoint: " JLONG_FORMAT " ns, "
"Cleanup: " JLONG_FORMAT " ns, "
"At safepoint: " JLONG_FORMAT " ns, " "At safepoint: " JLONG_FORMAT " ns, "
"Total: " JLONG_FORMAT " ns", "Total: " JLONG_FORMAT " ns",
VM_Operation::name(_current_type), VM_Operation::name(_current_type),
_last_app_time_ns, _last_app_time_ns,
_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns, _last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns,
_last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns, _last_safepoint_end_time_ns - _last_safepoint_sync_time_ns,
_last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns,
_last_safepoint_end_time_ns - _last_safepoint_begin_time_ns _last_safepoint_end_time_ns - _last_safepoint_begin_time_ns
); );

View File

@ -68,13 +68,6 @@ class SafepointSynchronize : AllStatic {
// VM thread and any NonJavaThread may be running. // VM thread and any NonJavaThread may be running.
}; };
// The enums are listed in the order of the tasks when done serially.
enum SafepointCleanupTasks {
SAFEPOINT_CLEANUP_REQUEST_OOPSTORAGE_CLEANUP,
// Leave this one last.
SAFEPOINT_CLEANUP_NUM_TASKS
};
private: private:
friend class SafepointMechanism; friend class SafepointMechanism;
friend class ThreadSafepointState; friend class ThreadSafepointState;
@ -155,8 +148,6 @@ public:
// Exception handling for page polling // Exception handling for page polling
static void handle_polling_page_exception(JavaThread *thread); static void handle_polling_page_exception(JavaThread *thread);
static void do_cleanup_tasks();
static void set_is_at_safepoint() { _state = _synchronized; } static void set_is_at_safepoint() { _state = _synchronized; }
static void set_is_not_at_safepoint() { _state = _not_synchronized; } static void set_is_not_at_safepoint() { _state = _not_synchronized; }
@ -239,7 +230,6 @@ private:
// Absolute // Absolute
static jlong _last_safepoint_begin_time_ns; static jlong _last_safepoint_begin_time_ns;
static jlong _last_safepoint_sync_time_ns; static jlong _last_safepoint_sync_time_ns;
static jlong _last_safepoint_cleanup_time_ns;
static jlong _last_safepoint_end_time_ns; static jlong _last_safepoint_end_time_ns;
// Relative // Relative
@ -251,7 +241,6 @@ private:
static VM_Operation::VMOp_Type _current_type; static VM_Operation::VMOp_Type _current_type;
static jlong _max_sync_time; static jlong _max_sync_time;
static jlong _max_cleanup_time;
static jlong _max_vmop_time; static jlong _max_vmop_time;
static uint64_t _op_count[VM_Operation::VMOp_Terminating]; static uint64_t _op_count[VM_Operation::VMOp_Terminating];
@ -262,7 +251,6 @@ public:
static void begin(VM_Operation::VMOp_Type type); static void begin(VM_Operation::VMOp_Type type);
static void synchronized(int nof_threads, int nof_running, int traps); static void synchronized(int nof_threads, int nof_running, int traps);
static void cleanup();
static void end(); static void end();
static void statistics_exit_log(); static void statistics_exit_log();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -126,8 +126,9 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
(cldg_cleanup_work = ClassLoaderDataGraph::should_clean_metaspaces_and_reset()) | (cldg_cleanup_work = ClassLoaderDataGraph::should_clean_metaspaces_and_reset()) |
(jvmti_tagmap_work = JvmtiTagMap::has_object_free_events_and_reset()) (jvmti_tagmap_work = JvmtiTagMap::has_object_free_events_and_reset())
) == 0) { ) == 0) {
// Wait until notified that there is some work to do. // Wait until notified that there is some work to do or timer expires.
ml.wait(); // Some cleanup requests don't notify the ServiceThread so work needs to be done at periodic intervals.
ml.wait(ServiceThreadCleanupInterval);
} }
if (has_jvmti_events) { if (has_jvmti_events) {

View File

@ -1,5 +1,5 @@
; ;
; Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. ; Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
; ;
; This code is free software; you can redistribute it and/or modify it ; This code is free software; you can redistribute it and/or modify it
@ -525,13 +525,13 @@ form = "COLUMN 'Event Count', 'First Recorded Event', 'Last Recorded Event',
[jvm.safepoints] [jvm.safepoints]
label = "Safepoints" label = "Safepoints"
table = "COLUMN 'Start Time', 'Duration', table = "COLUMN 'Start Time', 'Duration',
'State Syncronization', 'Cleanup', 'State Syncronization',
'JNI Critical Threads', 'Total Threads' 'JNI Critical Threads', 'Total Threads'
SELECT B.startTime, DIFF([B|E].startTime), SELECT B.startTime, DIFF([B|E].startTime),
S.duration, C.duration, S.duration,
jniCriticalThreadCount, totalThreadCount jniCriticalThreadCount, totalThreadCount
FROM SafepointBegin AS B, SafepointEnd AS E, FROM SafepointBegin AS B, SafepointEnd AS E,
SafepointCleanup AS C, SafepointStateSynchronization AS S SafepointStateSynchronization AS S
GROUP BY safepointId ORDER BY B.startTime" GROUP BY safepointId ORDER BY B.startTime"
[jvm.longest-compilations] [jvm.longest-compilations]

View File

@ -200,16 +200,6 @@
<setting name="threshold">10 ms</setting> <setting name="threshold">10 ms</setting>
</event> </event>
<event name="jdk.SafepointCleanup">
<setting name="enabled">false</setting>
<setting name="threshold">10 ms</setting>
</event>
<event name="jdk.SafepointCleanupTask">
<setting name="enabled">false</setting>
<setting name="threshold">10 ms</setting>
</event>
<event name="jdk.SafepointEnd"> <event name="jdk.SafepointEnd">
<setting name="enabled">false</setting> <setting name="enabled">false</setting>
<setting name="threshold">10 ms</setting> <setting name="threshold">10 ms</setting>

View File

@ -200,16 +200,6 @@
<setting name="threshold">0 ms</setting> <setting name="threshold">0 ms</setting>
</event> </event>
<event name="jdk.SafepointCleanup">
<setting name="enabled">false</setting>
<setting name="threshold">0 ms</setting>
</event>
<event name="jdk.SafepointCleanupTask">
<setting name="enabled">false</setting>
<setting name="threshold">0 ms</setting>
</event>
<event name="jdk.SafepointEnd"> <event name="jdk.SafepointEnd">
<setting name="enabled">false</setting> <setting name="enabled">false</setting>
<setting name="threshold">0 ms</setting> <setting name="threshold">0 ms</setting>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -55,7 +55,7 @@ public class TestReclaimStringsLeaksMemory {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ArrayList<String> baseargs = new ArrayList<>(Arrays.asList("-Xms256M", ArrayList<String> baseargs = new ArrayList<>(Arrays.asList("-Xms256M",
"-Xmx256M", "-Xmx256M",
"-Xlog:gc*,stringtable*=debug:gc.log", "-Xlog:gc*,stringtable*=debug,oopstorage+blocks=debug:gc.log",
"-XX:NativeMemoryTracking=summary", "-XX:NativeMemoryTracking=summary",
"-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockDiagnosticVMOptions",
"-XX:+PrintNMTStatistics" )); "-XX:+PrintNMTStatistics" ));

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) 2016, 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.
*/
/*
* @test
* @bug 8149991
* @summary safepoint+cleanup=info should have output from the code
* @requires vm.flagless
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
* @run driver SafepointCleanupTest
*/
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
public class SafepointCleanupTest {
static void analyzeOutputOn(ProcessBuilder pb) throws Exception {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("[safepoint,cleanup]");
output.shouldContain("safepoint cleanup tasks");
output.shouldHaveExitValue(0);
}
static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotContain("[safepoint,cleanup]");
output.shouldHaveExitValue(0);
}
public static void main(String[] args) throws Exception {
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:safepoint+cleanup=info",
InnerClass.class.getName());
analyzeOutputOn(pb);
pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:safepoint+cleanup=off",
InnerClass.class.getName());
analyzeOutputOff(pb);
}
public static class InnerClass {
public static void main(String[] args) throws Exception {
System.out.println("Safepoint Cleanup test");
}
}
}

View File

@ -56,8 +56,7 @@ public class TestLookForUntestedEvents {
Arrays.asList( Arrays.asList(
"DataLoss", "IntFlag", "ReservedStackActivation", "NativeLibraryUnload", "DataLoss", "IntFlag", "ReservedStackActivation", "NativeLibraryUnload",
"DoubleFlag", "UnsignedLongFlagChanged", "IntFlagChanged", "DoubleFlag", "UnsignedLongFlagChanged", "IntFlagChanged",
"UnsignedIntFlag", "UnsignedIntFlagChanged", "DoubleFlagChanged", "UnsignedIntFlag", "UnsignedIntFlagChanged", "DoubleFlagChanged")
"SafepointCleanupTask")
); );
// GC uses specific framework to test the events, instead of using event names literally. // GC uses specific framework to test the events, instead of using event names literally.

View File

@ -52,7 +52,6 @@ public class TestSafepointEvents {
static final String[] EVENT_NAMES = new String[] { static final String[] EVENT_NAMES = new String[] {
EventNames.SafepointBegin, EventNames.SafepointBegin,
EventNames.SafepointStateSynchronization, EventNames.SafepointStateSynchronization,
EventNames.SafepointCleanup,
EventNames.SafepointEnd EventNames.SafepointEnd
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -65,8 +65,6 @@ public class EventNames {
public static final String ClassUnload = PREFIX + "ClassUnload"; public static final String ClassUnload = PREFIX + "ClassUnload";
public static final String SafepointBegin = PREFIX + "SafepointBegin"; public static final String SafepointBegin = PREFIX + "SafepointBegin";
public static final String SafepointStateSynchronization = PREFIX + "SafepointStateSynchronization"; public static final String SafepointStateSynchronization = PREFIX + "SafepointStateSynchronization";
public static final String SafepointCleanup = PREFIX + "SafepointCleanup";
public static final String SafepointCleanupTask = PREFIX + "SafepointCleanupTask";
public static final String SafepointEnd = PREFIX + "SafepointEnd"; public static final String SafepointEnd = PREFIX + "SafepointEnd";
public static final String ExecuteVMOperation = PREFIX + "ExecuteVMOperation"; public static final String ExecuteVMOperation = PREFIX + "ExecuteVMOperation";
public static final String Shutdown = PREFIX + "Shutdown"; public static final String Shutdown = PREFIX + "Shutdown";