Skip to content
Permalink
Browse files
8268855: Cleanup name handling in the Thread class and subclasses
Reviewed-by: lfoltan, coleenp
  • Loading branch information
David Holmes committed Jun 24, 2021
1 parent c79034e commit 08ee7ae67246b45be9684a4a283f0103f5f1c0c4
Showing 16 changed files with 71 additions and 51 deletions.
@@ -116,7 +116,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
log_trace(nmethod, barrier)("deoptimize(nmethod: %s(%p), return_addr: %p, osr: %d, thread: %p(%s), making rsp: %p) -> %p",
nm->method()->name_and_sig_as_C_string(),
nm, *(address *) return_address_ptr, nm->is_osr_method(), thread,
thread->get_thread_name(), frame.sp(), nm->verified_entry_point());
thread->name(), frame.sp(), nm->verified_entry_point());
}

new_frame->sp = frame.sp();
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@@ -132,7 +132,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
ResourceMark mark;
log_trace(nmethod, barrier)("deoptimize(nmethod: %p, return_addr: %p, osr: %d, thread: %p(%s), making rsp: %p) -> %p",
nm, (address *) return_address_ptr, nm->is_osr_method(), jth,
jth->get_thread_name(), callers_rsp, nm->verified_entry_point());
jth->name(), callers_rsp, nm->verified_entry_point());
}

assert(nm->frame_size() >= 3, "invariant");
@@ -1008,9 +1008,9 @@ void CompileBroker::init_compiler_sweeper_threads() {
_compilers[1]->set_num_compiler_threads(i + 1);
if (TraceCompilerThreads) {
ResourceMark rm;
ThreadsListHandle tlh; // get_thread_name() depends on the TLH.
ThreadsListHandle tlh; // name() depends on the TLH.
assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
tty->print_cr("Added initial compiler thread %s", ct->get_thread_name());
tty->print_cr("Added initial compiler thread %s", ct->name());
}
}
}
@@ -1029,9 +1029,9 @@ void CompileBroker::init_compiler_sweeper_threads() {
_compilers[0]->set_num_compiler_threads(i + 1);
if (TraceCompilerThreads) {
ResourceMark rm;
ThreadsListHandle tlh; // get_thread_name() depends on the TLH.
ThreadsListHandle tlh; // name() depends on the TLH.
assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
tty->print_cr("Added initial compiler thread %s", ct->get_thread_name());
tty->print_cr("Added initial compiler thread %s", ct->name());
}
}
}
@@ -1116,10 +1116,10 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {
_compilers[1]->set_num_compiler_threads(i + 1);
if (TraceCompilerThreads) {
ResourceMark rm;
ThreadsListHandle tlh; // get_thread_name() depends on the TLH.
ThreadsListHandle tlh; // name() depends on the TLH.
assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
tty->print_cr("Added compiler thread %s (available memory: %dMB, available non-profiled code cache: %dMB)",
ct->get_thread_name(), (int)(available_memory/M), (int)(available_cc_np/M));
ct->name(), (int)(available_memory/M), (int)(available_cc_np/M));
}
}
}
@@ -1137,10 +1137,10 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {
_compilers[0]->set_num_compiler_threads(i + 1);
if (TraceCompilerThreads) {
ResourceMark rm;
ThreadsListHandle tlh; // get_thread_name() depends on the TLH.
ThreadsListHandle tlh; // name() depends on the TLH.
assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
tty->print_cr("Added compiler thread %s (available memory: %dMB, available profiled code cache: %dMB)",
ct->get_thread_name(), (int)(available_memory/M), (int)(available_cc_p/M));
ct->name(), (int)(available_memory/M), (int)(available_cc_p/M));
}
}
}
@@ -49,6 +49,9 @@ class ConcurrentGCThread: public NamedThread {

bool should_terminate() const;
bool has_terminated() const;

// Printing
const char* type_name() const { return "ConcurrentGCThread"; }
};

#endif // SHARE_GC_SHARED_CONCURRENTGCTHREAD_HPP
@@ -219,6 +219,9 @@ class GangWorker: public WorkerThread {
// Predicate for Thread
bool is_GC_task_thread() const override { return gang()->are_GC_task_threads(); }
bool is_ConcurrentGC_thread() const override { return gang()->are_ConcurrentGC_threads(); }

// Printing
const char* type_name() const override { return "GCTaskThread"; }
};

// A class that acts as a synchronisation barrier. Workers enter
@@ -143,7 +143,7 @@ class ShenandoahControlThread: public ConcurrentGCThread {
void prepare_for_graceful_shutdown();
bool in_graceful_shutdown();

char* name() const { return (char*)"ShenandoahControlThread";}
const char* name() const { return "ShenandoahControlThread";}

// Printing
void print_on(outputStream* st) const;
@@ -343,7 +343,8 @@ class JfrThreadSampler : public NonJavaThread {
protected:
virtual void post_run();
public:
virtual char* name() const { return (char*)"JFR Thread Sampler"; }
virtual const char* name() const { return "JFR Thread Sampler"; }
virtual const char* type_name() const { return "JfrThreadSampler"; }
bool is_JfrSampler_thread() const { return true; }
void run();
static Monitor* transition_block() { return JfrThreadSampler_lock; }
@@ -2279,7 +2279,7 @@ C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jb

JavaVMAttachArgs attach_args;
attach_args.version = JNI_VERSION_1_2;
attach_args.name = thread->name();
attach_args.name = const_cast<char*>(thread->name());
attach_args.group = NULL;
JNIEnv* peerJNIEnv;
if (runtime->GetEnv(thread, (void**) &peerJNIEnv, JNI_VERSION_1_2) == JNI_OK) {
@@ -205,7 +205,7 @@ void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
ResourceMark rm; // Thread name is resource allocated
JavaVMAttachArgs attach_args;
attach_args.version = JNI_VERSION_1_2;
attach_args.name = thread->name();
attach_args.name = const_cast<char*>(thread->name());
attach_args.group = NULL;
if (_runtime->AttachCurrentThread(thread, (void**) &_env, &attach_args) != JNI_OK) {
fatal("Error attaching current thread (%s) to JVMCI shared library JNI interface", attach_args.name);
@@ -160,7 +160,8 @@ class AsyncLogWriter : public NonJavaThread {
NonJavaThread::pre_run();
log_debug(logging, thread)("starting AsyncLog Thread tid = " INTX_FORMAT, os::current_thread_id());
}
char* name() const override { return (char*)"AsyncLog Thread"; }
const char* name() const override { return "AsyncLog Thread"; }
const char* type_name() const override { return "AsyncLogWriter"; }
void print_on(outputStream* st) const override {
st->print("\"%s\" ", name());
Thread::print_on(st);
@@ -576,7 +576,7 @@ JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env))
if (thread != NULL && thread->threadObj() != NULL) {
ResourceMark rm(THREAD);
jio_fprintf(defaultStream::error_stream(),
"in thread \"%s\" ", thread->get_thread_name());
"in thread \"%s\" ", thread->name());
}
if (ex->is_a(vmClasses::Throwable_klass())) {
JavaValue result(T_VOID);
@@ -70,8 +70,10 @@ class NonJavaThread::Iterator : public StackObj {
void step();
};

// Name support for threads. non-JavaThread subclasses with multiple
// uniquely named instances should derive from this.
// A base class for non-JavaThread subclasses with multiple
// uniquely named instances. NamedThreads also provide a common
// location to store GC information needed by GC threads
// and the VMThread.
class NamedThread: public NonJavaThread {
friend class VMStructs;
enum {
@@ -89,7 +91,8 @@ class NamedThread: public NonJavaThread {
// May only be called once per thread.
void set_name(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
virtual bool is_Named_thread() const { return true; }
virtual char* name() const { return _name == NULL ? (char*)"Unknown Thread" : _name; }
virtual const char* name() const { return _name == NULL ? "Unknown Thread" : _name; }
virtual const char* type_name() const { return "NamedThread"; }
Thread *processed_thread() { return _processed_thread; }
void set_processed_thread(Thread *thread) { _processed_thread = thread; }
virtual void print_on(outputStream* st) const;
@@ -117,6 +120,10 @@ class WorkerThread: public NamedThread {

void set_id(uint work_id) { _id = work_id; }
uint id() const { return _id; }

// Printing
virtual const char* type_name() const { return "WorkerThread"; }

};

// A single WatcherThread is used for simulating timer interrupts.
@@ -132,6 +139,7 @@ class WatcherThread: public NonJavaThread {
// volatile due to at least one lock-free read
volatile static bool _should_terminate;
public:

enum SomeConstants {
delay_interval = 10 // interrupt delay in milliseconds
};
@@ -148,7 +156,8 @@ class WatcherThread: public NonJavaThread {
bool is_Watcher_thread() const { return true; }

// Printing
char* name() const { return (char*)"VM Periodic Task Thread"; }
const char* name() const { return "VM Periodic Task Thread"; }
const char* type_name() const { return "WatcherThread"; }
void print_on(outputStream* st) const;
void unpark();

@@ -162,7 +162,7 @@ void universe_post_module_init(); // must happen after call_initPhase2
{ \
ResourceMark rm(this); \
int len = 0; \
const char* name = (javathread)->get_thread_name(); \
const char* name = (javathread)->name(); \
len = strlen(name); \
HOTSPOT_THREAD_PROBE_##probe(/* probe = start, stop */ \
(char *) name, len, \
@@ -609,17 +609,7 @@ void Thread::print() const { print_on(tty); }
void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
assert(!(is_Compiler_thread() || is_Java_thread()), "Can't call name() here if it allocates");

if (is_VM_thread()) { st->print("VMThread"); }
else if (is_GC_task_thread()) { st->print("GCTaskThread"); }
else if (is_Watcher_thread()) { st->print("WatcherThread"); }
else if (is_ConcurrentGC_thread()) { st->print("ConcurrentGCThread"); }
else if (this == AsyncLogWriter::instance()) {
st->print("%s", this->name());
} else { st->print("Thread"); }

if (is_Named_thread()) {
st->print(" \"%s\"", name());
}
st->print("%s \"%s\"", type_name(), name());

OSThread* os_thr = osthread();
if (os_thr != NULL) {
@@ -1272,7 +1262,7 @@ void JavaThread::thread_main_inner() {
!java_lang_Thread::is_stillborn(this->threadObj())) {
{
ResourceMark rm(this);
this->set_native_thread_name(this->get_thread_name());
this->set_native_thread_name(this->name());
}
HandleMark hm(this);
this->entry_point()(this, this);
@@ -1351,7 +1341,7 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
"\nException: %s thrown from the UncaughtExceptionHandler"
" in thread \"%s\"\n",
pending_exception()->klass()->external_name(),
get_thread_name());
name());
CLEAR_PENDING_EXCEPTION;
}
}
@@ -1456,7 +1446,7 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
char* thread_name = NULL;
if (log_is_enabled(Debug, os, thread, timer)) {
ResourceMark rm(this);
thread_name = os::strdup(get_thread_name());
thread_name = os::strdup(name());
}

log_info(os, thread)("JavaThread %s (tid: " UINTX_FORMAT ").",
@@ -2053,7 +2043,7 @@ void JavaThread::print_thread_state_on(outputStream *st) const {
// Called by Threads::print() for VM_PrintThreads operation
void JavaThread::print_on(outputStream *st, bool print_extended_info) const {
st->print_raw("\"");
st->print_raw(get_thread_name());
st->print_raw(name());
st->print_raw("\" ");
oop thread_oop = threadObj();
if (thread_oop != NULL) {
@@ -2091,7 +2081,7 @@ void JavaThread::print_name_on_error(outputStream* st, char *buf, int buflen) co
// Called by fatal error handler. The difference between this and
// JavaThread::print() is that we can't grab lock or allocate memory.
void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const {
st->print("JavaThread \"%s\"", get_thread_name_string(buf, buflen));
st->print("%s \"%s\"", type_name(), get_thread_name_string(buf, buflen));
oop thread_obj = threadObj();
if (thread_obj != NULL) {
if (java_lang_Thread::is_daemon(thread_obj)) st->print(" daemon");
@@ -2139,7 +2129,7 @@ void JavaThread::verify() {
// seen prior to having its threadObj set (e.g., JNI attaching threads and
// if vm exit occurs during initialization). These cases can all be accounted
// for such that this method never returns NULL.
const char* JavaThread::get_thread_name() const {
const char* JavaThread::name() const {
if (Thread::is_JavaThread_protected(this)) {
// The target JavaThread is protected so get_thread_name_string() is safe:
return get_thread_name_string();
@@ -2165,7 +2155,7 @@ const char* JavaThread::get_thread_name_string(char* buf, int buflen) const {
} else if (is_attaching_via_jni()) { // workaround for 6412693 - see 6404306
name_str = "<no-name - thread is attaching>";
} else {
name_str = Thread::name();
name_str = "<un-named>";
}
} else {
name_str = Thread::name();
@@ -352,7 +352,15 @@ class Thread: public ThreadShadow {
// If so it must participate in the safepoint protocol.
virtual bool is_active_Java_thread() const { return false; }

virtual char* name() const { return (char*)"Unknown thread"; }
// All threads are given names. For singleton subclasses we can
// just hard-wire the known name of the instance. JavaThreads and
// NamedThreads support multiple named instances, and dynamic
// changing of the name of an instance.
virtual const char* name() const { return "Unknown thread"; }

// A thread's type name is also made available for debugging
// and logging.
virtual const char* type_name() const { return "Thread"; }

// Returns the current thread (ASSERTS if NULL)
static inline Thread* current();
@@ -568,6 +576,7 @@ class Thread: public ThreadShadow {
virtual void print_on(outputStream* st) const { print_on(st, false); }
void print() const;
virtual void print_on_error(outputStream* st, char* buf, int buflen) const;
// Basic, non-virtual, printing support that is simple and always safe.
void print_value_on(outputStream* st) const;

// Debug-only code
@@ -1347,6 +1356,9 @@ class JavaThread: public Thread {
private:
void set_entry_point(ThreadFunction entry_point) { _entry_point = entry_point; }

// factor out low-level mechanics for use in both normal and error cases
const char* get_thread_name_string(char* buf = NULL, int buflen = 0) const;

public:

// Frame iteration; calls the function f for all frames on the stack
@@ -1366,19 +1378,17 @@ class JavaThread: public Thread {
DEBUG_ONLY(void verify_states_for_handshake();)

// Misc. operations
char* name() const { return (char*)get_thread_name(); }
const char* name() const;
const char* type_name() const { return "JavaThread"; }

void print_on(outputStream* st, bool print_extended_info) const;
void print_on(outputStream* st) const { print_on(st, false); }
void print() const;
void print_thread_state_on(outputStream*) const PRODUCT_RETURN;
void print_on_error(outputStream* st, char* buf, int buflen) const;
void print_name_on_error(outputStream* st, char* buf, int buflen) const;
void verify();
const char* get_thread_name() const;
protected:
// factor out low-level mechanics for use in both normal and error cases
virtual const char* get_thread_name_string(char* buf = NULL, int buflen = 0) const;
public:

// Accessing frames
frame last_frame() {
_anchor.make_walkable(this);
@@ -130,6 +130,9 @@ class VMThread: public NamedThread {

static void wait_until_executed(VM_Operation* op);

// Printing
const char* type_name() const { return "VMThread"; }

private:
// VM_Operation support
static VM_Operation* _cur_vm_operation; // Current VM operation
@@ -975,7 +975,7 @@ void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const
waitingToLockRawMonitor = currentThread->current_pending_raw_monitor();
waitingToLockBlocker = currentThread->current_park_blocker();
st->cr();
st->print_cr("\"%s\":", currentThread->get_thread_name());
st->print_cr("\"%s\":", currentThread->name());
const char* owner_desc = ",\n which is held by";

// Note: As the JVM TI "monitor contended enter" event callback is executed after ObjectMonitor
@@ -987,7 +987,7 @@ void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const
if (owner != NULL) {
if (owner->is_Java_thread()) {
currentThread = JavaThread::cast(owner);
st->print_cr("%s \"%s\"", owner_desc, currentThread->get_thread_name());
st->print_cr("%s \"%s\"", owner_desc, currentThread->name());
} else {
st->print_cr(",\n which has now been released");
}
@@ -1026,7 +1026,7 @@ void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const
currentThread = java_lang_Thread::thread(ownerObj);
assert(currentThread != NULL, "AbstractOwnableSynchronizer owning thread is unexpectedly NULL");
}
st->print_cr("%s \"%s\"", owner_desc, currentThread->get_thread_name());
st->print_cr("%s \"%s\"", owner_desc, currentThread->name());
}

st->cr();
@@ -1038,7 +1038,7 @@ void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const
st->print_cr("===================================================");
for (int j = 0; j < len; j++) {
currentThread = _threads->at(j);
st->print_cr("\"%s\":", currentThread->get_thread_name());
st->print_cr("\"%s\":", currentThread->name());
currentThread->print_stack_on(st);
}
JavaMonitorsInStackTrace = oldJavaMonitorsInStackTrace;

1 comment on commit 08ee7ae

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 08ee7ae Jun 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.