Skip to content

Commit

Permalink
Ported some more tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
lmesnik committed Mar 6, 2021
1 parent efdb7d0 commit e066dad
Show file tree
Hide file tree
Showing 91 changed files with 12,050 additions and 987 deletions.
46 changes: 45 additions & 1 deletion src/hotspot/share/prims/jvmti.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2316,8 +2316,30 @@ jvmtiEnv *jvmti;
<required id="can_support_virtual_threads"></required>
</capabilities>
<parameters>
<param id="except_count">
<jint min="0"/>
<description>
The number of threads in the list of threads not to be suspended.
</description>
</param>
<param id="except_list">
<inbuf incount="except_count">
<jthread/>
<nullok>not an error if <code>except_count == 0</code></nullok>
</inbuf>
<description>
The list of threads not to be suspended.
</description>
</param>
</parameters>
<errors>
<error id="JVMTI_ERROR_INVALID_THREAD">
A thread in <paramlink id="except_list"></paramlink> was invalid.
</error>
<error id="JVMTI_ERROR_NULL_POINTER">
Both <paramlink id="except_list"></paramlink> was <code>NULL</code>
and <paramlink id="except_count"></paramlink> was non-zero.
</error>
</errors>
</function>

Expand All @@ -2326,7 +2348,7 @@ jvmtiEnv *jvmti;
<description>
Resume all virtual threads except those already resumed.
Virtual threads may be suspended with
<functionlink id="RsuspendAllVirtualThreads"></functionlink> or
<functionlink id="SuspendAllVirtualThreads"></functionlink> or
<functionlink id="SuspendThreadList"></functionlink> or
<functionlink id="SuspendThread"></functionlink>.
Virtual threads that are currently resumed do not change state.
Expand All @@ -2337,8 +2359,30 @@ jvmtiEnv *jvmti;
<required id="can_support_virtual_threads"></required>
</capabilities>
<parameters>
<param id="except_count">
<jint min="0"/>
<description>
The number of threads in the list of threads not to be resumed.
</description>
</param>
<param id="except_list">
<inbuf incount="except_count">
<jthread/>
<nullok>not an error if <code>except_count == 0</code></nullok>
</inbuf>
<description>
The list of threads not to be resumed.
</description>
</param>
</parameters>
<errors>
<error id="JVMTI_ERROR_INVALID_THREAD">
A thread in <paramlink id="except_list"></paramlink> was invalid.
</error>
<error id="JVMTI_ERROR_NULL_POINTER">
Both <paramlink id="except_list"></paramlink> was <code>NULL</code>
and <paramlink id="except_count"></paramlink> was non-zero.
</error>
</errors>
</function>

Expand Down
60 changes: 55 additions & 5 deletions src/hotspot/share/prims/jvmtiEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1064,21 +1064,37 @@ JvmtiEnv::SuspendThreadList(jint request_count, const jthread* request_list, jvm


jvmtiError
JvmtiEnv::SuspendAllVirtualThreads() {
JvmtiEnv::SuspendAllVirtualThreads(jint except_count, const jthread* except_list) {
int needSafepoint = 0; // > 0 if a safepoint is needed
jvmtiError err = JvmtiEnvBase::check_thread_list(except_count, except_list);
if (err != JVMTI_ERROR_NONE) {
return err;
}
if (!JvmtiExport::can_support_virtual_threads()) {
return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
}
{
ResourceMark rm;
JvmtiVTMTDisabler vtmt_disabler;
GrowableArray<jthread>* elist = new GrowableArray<jthread>(except_count);

// Collect threads from except_list which resumed status must be restored.
for (int idx = 0; idx < except_count; idx++) {
jthread thread = except_list[idx];
oop thread_oop = JNIHandles::resolve_external_guard(thread);
if (!JvmtiVTSuspender::vthread_is_ext_suspended(thread_oop)) {
// is resumed, so its resumed status must be restored
elist->append(except_list[idx]);
}
}

for (JavaThreadIteratorWithHandle jtiwh; JavaThread *java_thread = jtiwh.next(); ) {
oop jt_oop = java_thread->threadObj();
if (jt_oop == NULL || java_thread->is_exiting() ||
!java_lang_Thread::is_alive(jt_oop) ||
java_thread->is_jvmti_agent_thread() ||
java_thread->is_hidden_from_external_view()) {
java_thread->is_hidden_from_external_view() ||
is_in_thread_list(except_count, except_list, jt_oop)) {
continue;
}
oop thread_oop = java_thread->mounted_vthread();
Expand All @@ -1092,6 +1108,15 @@ JvmtiEnv::SuspendAllVirtualThreads() {
}
}
JvmtiVTSuspender::register_all_vthreads_suspend();

// Resume threads from except list that were resumed before.
for (int idx = 0; idx < elist->length(); idx++) {
jthread thread = elist->at(idx);
oop thread_oop = JNIHandles::resolve_external_guard(thread);
if (JvmtiVTSuspender::vthread_is_ext_suspended(thread_oop)) {
JvmtiVTSuspender::register_vthread_resume(thread_oop);
}
}
}
if (needSafepoint > 0) {
VM_ThreadsSuspendJVMTI tsj;
Expand Down Expand Up @@ -1144,19 +1169,35 @@ JvmtiEnv::ResumeThreadList(jint request_count, const jthread* request_list, jvmt


jvmtiError
JvmtiEnv::ResumeAllVirtualThreads() {
JvmtiEnv::ResumeAllVirtualThreads(jint except_count, const jthread* except_list) {
jvmtiError err = JvmtiEnvBase::check_thread_list(except_count, except_list);
if (err != JVMTI_ERROR_NONE) {
return err;
}
if (!JvmtiExport::can_support_virtual_threads()) {
return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
}
JvmtiVTMTDisabler vtmt_disabler;
ResourceMark rm;
JvmtiVTMTDisabler vtmt_disabler;
GrowableArray<jthread>* elist = new GrowableArray<jthread>(except_count);

// Collect threads from except_list which suspended status must be restored.
for (int idx = 0; idx < except_count; idx++) {
jthread thread = except_list[idx];
oop thread_oop = JNIHandles::resolve_external_guard(thread);
if (JvmtiVTSuspender::vthread_is_ext_suspended(thread_oop)) {
// is suspended, so its suspended status must be restored
elist->append(except_list[idx]);
}
}

for (JavaThreadIteratorWithHandle jtiwh; JavaThread *java_thread = jtiwh.next(); ) {
oop jt_oop = java_thread->threadObj();
if (jt_oop == NULL || java_thread->is_exiting() ||
!java_lang_Thread::is_alive(jt_oop) ||
java_thread->is_jvmti_agent_thread() ||
java_thread->is_hidden_from_external_view()) {
java_thread->is_hidden_from_external_view() ||
is_in_thread_list(except_count, except_list, jt_oop)) {
continue;
}
oop thread_oop = java_thread->mounted_vthread();
Expand All @@ -1167,6 +1208,15 @@ JvmtiEnv::ResumeAllVirtualThreads() {
}
}
JvmtiVTSuspender::register_all_vthreads_resume();

// Suspend threads from except list that were suspended before.
for (int idx = 0; idx < elist->length(); idx++) {
jthread thread = elist->at(idx);
oop thread_oop = JNIHandles::resolve_external_guard(thread);
if (!JvmtiVTSuspender::vthread_is_ext_suspended(thread_oop)) {
JvmtiVTSuspender::register_vthread_suspend(thread_oop);
}
}
return JVMTI_ERROR_NONE;
}

Expand Down
27 changes: 27 additions & 0 deletions src/hotspot/share/prims/jvmtiEnvBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,33 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
return JVMTI_ERROR_NONE;
}

jvmtiError
JvmtiEnvBase::check_thread_list(jint count, const jthread* list) {
if (list == NULL && count != 0) {
return JVMTI_ERROR_NULL_POINTER;
}
for (int i = 0; i < count; i++) {
jthread thread = list[i];
oop thread_oop = JNIHandles::resolve_external_guard(thread);
if (thread_oop == NULL || !thread_oop->is_a(vmClasses::VirtualThread_klass())) {
return JVMTI_ERROR_INVALID_THREAD;
}
}
return JVMTI_ERROR_NONE;
}

bool
JvmtiEnvBase::is_in_thread_list(jint count, const jthread* list, oop jt_oop) {
for (int idx = 0; idx < count; idx++) {
jthread thread = list[idx];
oop thread_oop = JNIHandles::resolve_external_guard(thread);
if (thread_oop == jt_oop) {
return true;
}
}
return false;
}

jvmtiError
JvmtiEnvBase::suspend_thread(oop thread_oop, JavaThread* java_thread, bool single_suspend,
int* need_safepoint_p) {
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/prims/jvmtiEnvBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class JvmtiEnvBase : public CHeapObj<mtInternal> {
static jvmtiError suspend_thread(oop thread_oop, JavaThread* java_thread, bool single_suspend,
int* need_safepoint_p);
static jvmtiError resume_thread(oop thread_oop, JavaThread* java_thread, bool single_suspend);
static jvmtiError check_thread_list(jint count, const jthread* list);
static bool is_in_thread_list(jint count, const jthread* list, oop jt_oop);
private:

enum {
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/prims/jvmtiThreadState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,13 +358,15 @@ JvmtiVTSuspender::register_all_vthreads_suspend() {

_vthread_suspend_mode = vthread_suspend_all;
_vthread_suspend_list->invalidate();
_vthread_resume_list->invalidate();
}

void
JvmtiVTSuspender::register_all_vthreads_resume() {
MonitorLocker ml(JvmtiVTMT_lock, Mutex::_no_safepoint_check_flag);

_vthread_suspend_mode = vthread_suspend_none;
_vthread_suspend_list->invalidate();
_vthread_resume_list->invalidate();
}

Expand Down
15 changes: 9 additions & 6 deletions src/jdk.jdwp.agent/share/native/libjdwp/ThreadReferenceImpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,25 @@ name(PacketInputStream *in, PacketOutputStream *out)
return JNI_TRUE;
}

WITH_LOCAL_REFS(env, 3) {
/* Get the thread name */
WITH_LOCAL_REFS(env, 1) {

jvmtiThreadInfo info;
jvmtiError error;

(void)memset(&info, 0, sizeof(info));

error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
(gdata->jvmti, thread, &info);
(gdata->jvmti, thread, &info);

if (error != JVMTI_ERROR_NONE) {
outStream_setError(out, map2jdwpError(error));
} else {
(void)outStream_writeString(out, info.name);
}

if ( info.name != NULL ) {
if ( info.name != NULL )
jvmtiDeallocate(info.name);
}

} END_WITH_LOCAL_REFS(env);

return JNI_TRUE;
Expand Down Expand Up @@ -169,9 +170,11 @@ threadGroup(PacketInputStream *in, PacketOutputStream *out)

jvmtiThreadInfo info;
jvmtiError error;

(void)memset(&info, 0, sizeof(info));

error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
(gdata->jvmti, thread, &info);
(gdata->jvmti, thread, &info);

if (error != JVMTI_ERROR_NONE) {
outStream_setError(out, map2jdwpError(error));
Expand Down
12 changes: 2 additions & 10 deletions src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ debugLoop_run(void)
jboolean shouldListen;
jdwpPacket p;
jvmtiStartFunction func;
JNIEnv *env = getEnv();

/* Initialize all statics */
/* We may be starting a new connection after an error */
Expand Down Expand Up @@ -158,15 +157,8 @@ debugLoop_run(void)
*/
outStream_setError(&out, JDWP_ERROR(VM_DEAD));
} else {
/* Provide 64 localrefs by default. */
/* vthread fixme: Now that this default set of localrefs is in place, we can remove a
* bunch of WITH_LOCAL_REFS/END_WITH_LOCAL_REFS blocks. The only ones needed are
* ones that could potentially go over 64, likes ones within loops. Note this only
* refers to command handlers called from here, not all uses of WITH_LOCAL_REFS. */
WITH_LOCAL_REFS(env, 64) {
/* Call the command handler */
replyToSender = func(&in, &out);
} END_WITH_LOCAL_REFS(env);
/* Call the command handler */
replyToSender = func(&in, &out);
}

/* Reply to the sender */
Expand Down
21 changes: 0 additions & 21 deletions src/jdk.jdwp.agent/share/native/libjdwp/eventFilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,27 +977,6 @@ eventFilter_setStepFilter(HandlerNode *node, jint index,
return JVMTI_ERROR_NONE;
}

/*
* Finds the step filter in a node, and sets the thread for that filter.
* vthread fixme: not used. delete once we know for sure we'll never need it.
*/
void
eventFilter_setStepFilterThread(HandlerNode *node, jthread thread)
{
JNIEnv *env = getEnv();
Filter *filter = FILTERS_ARRAY(node);
int i;
for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
switch (filter->modifier) {
case JDWP_REQUEST_MODIFIER(Step):
tossGlobalRef(env, &(filter->u.Step.thread));
saveGlobalRef(env, thread, &(filter->u.Step.thread));
return;
}
}
JDI_ASSERT(JNI_FALSE); /* We should have found a step filter, but didn't. */
}

jvmtiError
eventFilter_setSourceNameMatchFilter(HandlerNode *node,
jint index,
Expand Down
1 change: 0 additions & 1 deletion src/jdk.jdwp.agent/share/native/libjdwp/eventFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ jvmtiError eventFilter_setStepFilter(HandlerNode *node,
jint index,
jthread thread,
jint size, jint depth);
void eventFilter_setStepFilterThread(HandlerNode *node, jthread thread);
jvmtiError eventFilter_setSourceNameMatchFilter(HandlerNode *node,
jint index,
char *sourceNamePattern);
Expand Down
15 changes: 2 additions & 13 deletions src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ filterAndAddVThread(JNIEnv *env, EventInfo *evinfo, EventIndex ei, jbyte eventSe
* consumes the event.
*/
static void
event_callback_helper(JNIEnv *env, EventInfo *evinfo)
event_callback(JNIEnv *env, EventInfo *evinfo)
{
struct bag *eventBag;
jbyte eventSessionID = currentSessionID; /* session could change */
Expand Down Expand Up @@ -743,8 +743,7 @@ event_callback_helper(JNIEnv *env, EventInfo *evinfo)
* resources can be allocated. This must be done before
* grabbing any locks.
*/
eventBag = threadControl_onEventHandlerEntry(
eventSessionID, evinfo, currentException);
eventBag = threadControl_onEventHandlerEntry(eventSessionID, evinfo, currentException);
if ( eventBag == NULL ) {
jboolean invoking;
do {
Expand Down Expand Up @@ -829,16 +828,6 @@ event_callback_helper(JNIEnv *env, EventInfo *evinfo)
}
}

static void
event_callback(JNIEnv *env, EventInfo *evinfo)
{
/* vthread fixme: There are a bunch of WITH_LOCAL_REFS that we can remove now that
* we are doing one here. */
WITH_LOCAL_REFS(env, 64) {
event_callback_helper(env, evinfo);
} END_WITH_LOCAL_REFS(env);
}

/* Returns a local ref to the declaring class for an object. */
static jclass
getObjectClass(jobject object)
Expand Down
Loading

0 comments on commit e066dad

Please sign in to comment.