Skip to content

Commit

Permalink
8304919: Implementation of Virtual Threads
Browse files Browse the repository at this point in the history
Reviewed-by: lmesnik, cjplummer, psandoz, mchung, sspitsyn, jpai
  • Loading branch information
Alan Bateman committed Apr 11, 2023
1 parent 3939807 commit 2586f36
Show file tree
Hide file tree
Showing 205 changed files with 1,379 additions and 1,342 deletions.
9 changes: 1 addition & 8 deletions src/hotspot/share/classfile/javaClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1498,11 +1498,9 @@ JavaThreadStatus java_lang_Thread_FieldHolder::get_thread_status(oop holder) {


int java_lang_Thread_Constants::_static_VTHREAD_GROUP_offset = 0;
int java_lang_Thread_Constants::_static_NOT_SUPPORTED_CLASSLOADER_offset = 0;

#define THREAD_CONSTANTS_STATIC_FIELDS_DO(macro) \
macro(_static_VTHREAD_GROUP_offset, k, "VTHREAD_GROUP", threadgroup_signature, true); \
macro(_static_NOT_SUPPORTED_CLASSLOADER_offset, k, "NOT_SUPPORTED_CLASSLOADER", classloader_signature, true);
macro(_static_VTHREAD_GROUP_offset, k, "VTHREAD_GROUP", threadgroup_signature, true);

void java_lang_Thread_Constants::compute_offsets() {
assert(_static_VTHREAD_GROUP_offset == 0, "offsets should be initialized only once");
Expand All @@ -1523,11 +1521,6 @@ oop java_lang_Thread_Constants::get_VTHREAD_GROUP() {
return base->obj_field(_static_VTHREAD_GROUP_offset);
}

oop java_lang_Thread_Constants::get_NOT_SUPPORTED_CLASSLOADER() {
InstanceKlass* k = vmClasses::Thread_Constants_klass();
oop base = k->static_field_base_raw();
return base->obj_field(_static_NOT_SUPPORTED_CLASSLOADER_offset);
}

int java_lang_Thread::_holder_offset;
int java_lang_Thread::_name_offset;
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/classfile/javaClasses.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,6 @@ class java_lang_Thread_Constants : AllStatic {

public:
static oop get_VTHREAD_GROUP();
static oop get_NOT_SUPPORTED_CLASSLOADER();

friend class JavaClasses;
};
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/prims/jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
#include "jfr/jfr.hpp"
#endif

static jint CurrentVersion = JNI_VERSION_20;
static jint CurrentVersion = JNI_VERSION_21;

#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
Expand Down
32 changes: 6 additions & 26 deletions src/hotspot/share/prims/jvmti.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="jvmti.xsl"?>
<!--
Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2002, 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
Expand Down Expand Up @@ -1724,13 +1724,9 @@ jvmtiEnv *jvmti;
</errors>
</function>

<function id="SuspendAllVirtualThreads" num="118" since="19">
<function id="SuspendAllVirtualThreads" num="118" since="21">
<synopsis>Suspend All Virtual Threads</synopsis>
<description>
<b> SuspendAllVirtualThreads is a preview API of the Java platform. </b>
<i>Preview features may be removed in a future release, or upgraded to
permanent features of the Java platform.</i>
<p/>
Suspend all virtual threads except those in the exception list.
Virtual threads that are currently suspended do not change state.
Virtual threads may be resumed with
Expand Down Expand Up @@ -1850,13 +1846,9 @@ jvmtiEnv *jvmti;
</errors>
</function>

<function id="ResumeAllVirtualThreads" num="119" since="19">
<function id="ResumeAllVirtualThreads" num="119" since="21">
<synopsis>Resume All Virtual Threads</synopsis>
<description>
<b> ResumeAllVirtualThreads is a preview API of the Java platform. </b>
<i>Preview features may be removed in a future release, or upgraded to
permanent features of the Java platform.</i>
<p/>
Resume all virtual threads except those in the exception list.
Virtual threads that are currently resumed do not change state.
Virtual threads may be suspended with
Expand Down Expand Up @@ -10650,12 +10642,8 @@ myInit() {
called and <eventlink id="SampledObjectAlloc"></eventlink> events can be generated.
</description>
</capabilityfield>
<capabilityfield id="can_support_virtual_threads" since="19">
<capabilityfield id="can_support_virtual_threads" since="21">
<description>
<b> can_support_virtual_threads is a preview API of the Java platform. </b>
<i>Preview features may be removed in a future release, or upgraded to
permanent features of the Java platform.</i>
<p/>
Can support virtual threads.
If this capability is enabled then the following functions can be called:
<functionlink id="SuspendAllVirtualThreads"></functionlink>,
Expand Down Expand Up @@ -13038,12 +13026,8 @@ myInit() {
</event>

<event label="Virtual Thread Start"
id="VirtualThreadStart" const="JVMTI_EVENT_VIRTUAL_THREAD_START" filtered="thread" num="87" phase="start" since="19">
id="VirtualThreadStart" const="JVMTI_EVENT_VIRTUAL_THREAD_START" filtered="thread" num="87" phase="start" since="21">
<description>
<b> VirtualThreadStart is a preview API of the Java platform. </b>
<i>Preview features may be removed in a future release, or upgraded to
permanent features of the Java platform.</i>
<p/>
A virtual thread start event is generated before its initial method executes.
<p/>
The event is sent on the newly started <paramlink id="virtual_thread"></paramlink>.
Expand Down Expand Up @@ -13071,12 +13055,8 @@ myInit() {
</event>

<event label="Virtual Thread End"
id="VirtualThreadEnd" const="JVMTI_EVENT_VIRTUAL_THREAD_END" filtered="thread" num="88" phase="start" since="19">
id="VirtualThreadEnd" const="JVMTI_EVENT_VIRTUAL_THREAD_END" filtered="thread" num="88" phase="start" since="21">
<description>
<b> VirtualThreadEnd is a preview API of the Java platform. </b>
<i>Preview features may be removed in a future release, or upgraded to
permanent features of the Java platform.</i>
<p/>
A virtual thread end event is generated after its initial method has finished execution.
<p/>
The event is sent on the terminating <paramlink id="virtual_thread"></paramlink>.
Expand Down
7 changes: 0 additions & 7 deletions src/hotspot/share/prims/jvmtiEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1311,13 +1311,6 @@ JvmtiEnv::GetThreadInfo(jthread thread, jvmtiThreadInfo* info_ptr) {
}

oop loader = java_lang_Thread::context_class_loader(thread_obj());
if (loader != nullptr) {
// Do the same as Thread.getContextClassLoader and set context_class_loader to be
// the system class loader when the field value is the "not supported" placeholder.
if (loader == java_lang_Thread_Constants::get_NOT_SUPPORTED_CLASSLOADER()) {
loader = SystemDictionary::java_system_loader();
}
}
context_class_loader = Handle(current_thread, loader);

{ const char *n;
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/prims/jvmtiH.xsl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2002, 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
Expand Down Expand Up @@ -116,6 +116,7 @@ enum {
JVMTI_VERSION_9 = 0x30090000,
JVMTI_VERSION_11 = 0x300B0000,
JVMTI_VERSION_19 = 0x30130000,
JVMTI_VERSION_21 = 0x30150000,

JVMTI_VERSION = 0x30000000 + (</xsl:text>
<xsl:value-of select="$majorversion"/>
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/prims/jvmtiTagMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,6 @@ void JvmtiTagMap::iterate_through_heap(jint heap_filter,
const void* user_data)
{
// EA based optimizations on tagged objects are already reverted.
// disabled if vritual threads are enabled with --enable-preview
EscapeBarrier eb(!(heap_filter & JVMTI_HEAP_FILTER_UNTAGGED), JavaThread::current());
eb.deoptimize_objects_all_threads();

Expand Down
10 changes: 9 additions & 1 deletion src/hotspot/share/prims/stackwalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ int StackWalk::fill_in_frames(jlong mode, BaseFrameStream& stream,

int frames_decoded = 0;
for (; !stream.at_end(); stream.next()) {
if (stream.continuation() != nullptr && stream.continuation() != stream.reg_map()->cont()) {
// The code in StackStreamFactory.java has failed to set the continuation because frameBuffer.isAtBottom()
// returns false if the end of a continuation falls precisely at the end of the batch.
// By breaking here, we're signalling the Java code to set the continuation to the parent.
break;
}
assert(stream.continuation() == nullptr || stream.continuation() == stream.reg_map()->cont(), "");
Method* method = stream.method();

Expand All @@ -190,6 +196,8 @@ int StackWalk::fill_in_frames(jlong mode, BaseFrameStream& stream,
method->print_short_name(&ls);
ls.cr();
}
// We end a batch on continuation bottom to let the Java side skip top frames of the next one
if (stream.continuation() != nullptr && method->intrinsic_id() == vmIntrinsics::_Continuation_enter) break;
continue;
}
}
Expand Down Expand Up @@ -576,7 +584,7 @@ jint StackWalk::fetchNextBatch(Handle stackStream, jlong mode, jlong magic,
if (!stream.at_end()) {
int n = fill_in_frames(mode, stream, frame_count, start_index,
frames_array, end_index, CHECK_0);
if (n < 1) {
if (n < 1 && !skip_hidden_frames(mode)) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
}
return end_index;
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/runtime/threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,7 @@ jboolean Threads::is_supported_jni_version(jint version) {
if (version == JNI_VERSION_10) return JNI_TRUE;
if (version == JNI_VERSION_19) return JNI_TRUE;
if (version == JNI_VERSION_20) return JNI_TRUE;
if (version == JNI_VERSION_21) return JNI_TRUE;
return JNI_FALSE;
}

Expand Down
13 changes: 2 additions & 11 deletions src/java.base/share/classes/java/lang/System.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import jdk.internal.vm.annotation.Stable;
import jdk.internal.vm.annotation.ChangesCurrentThread;
import sun.nio.fs.DefaultFileSystemProvider;
import sun.reflect.annotation.AnnotationType;
import sun.nio.ch.Interruptible;
Expand Down Expand Up @@ -2567,17 +2566,9 @@ public Thread currentCarrierThread() {
return Thread.currentCarrierThread();
}

@ChangesCurrentThread
public <V> V executeOnCarrierThread(Callable<V> task) throws Exception {
Thread thread = Thread.currentThread();
if (thread.isVirtual()) {
Thread carrier = Thread.currentCarrierThread();
carrier.setCurrentThread(carrier);
try {
return task.call();
} finally {
carrier.setCurrentThread(thread);
}
if (Thread.currentThread() instanceof VirtualThread vthread) {
return vthread.executeOnCarrierThread(task);
} else {
return task.call();
}
Expand Down
Loading

1 comment on commit 2586f36

@openjdk-notifier
Copy link

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.