Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/back/ThreadReferenceImpl.c
38765 views
1
/*
2
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include "util.h"
27
#include "ThreadReferenceImpl.h"
28
#include "eventHandler.h"
29
#include "threadControl.h"
30
#include "inStream.h"
31
#include "outStream.h"
32
#include "FrameID.h"
33
34
static jboolean
35
name(PacketInputStream *in, PacketOutputStream *out)
36
{
37
JNIEnv *env;
38
jthread thread;
39
40
env = getEnv();
41
42
thread = inStream_readThreadRef(env, in);
43
if (inStream_error(in)) {
44
return JNI_TRUE;
45
}
46
47
if (threadControl_isDebugThread(thread)) {
48
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
49
return JNI_TRUE;
50
}
51
52
WITH_LOCAL_REFS(env, 1) {
53
54
jvmtiThreadInfo info;
55
jvmtiError error;
56
57
(void)memset(&info, 0, sizeof(info));
58
59
error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
60
(gdata->jvmti, thread, &info);
61
62
if (error != JVMTI_ERROR_NONE) {
63
outStream_setError(out, map2jdwpError(error));
64
} else {
65
(void)outStream_writeString(out, info.name);
66
}
67
68
if ( info.name != NULL )
69
jvmtiDeallocate(info.name);
70
71
} END_WITH_LOCAL_REFS(env);
72
73
return JNI_TRUE;
74
}
75
76
static jboolean
77
suspend(PacketInputStream *in, PacketOutputStream *out)
78
{
79
jvmtiError error;
80
jthread thread;
81
82
thread = inStream_readThreadRef(getEnv(), in);
83
if (inStream_error(in)) {
84
return JNI_TRUE;
85
}
86
87
if (threadControl_isDebugThread(thread)) {
88
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
89
return JNI_TRUE;
90
}
91
error = threadControl_suspendThread(thread, JNI_FALSE);
92
if (error != JVMTI_ERROR_NONE) {
93
outStream_setError(out, map2jdwpError(error));
94
}
95
return JNI_TRUE;
96
}
97
98
static jboolean
99
resume(PacketInputStream *in, PacketOutputStream *out)
100
{
101
jvmtiError error;
102
jthread thread;
103
104
thread = inStream_readThreadRef(getEnv(), in);
105
if (inStream_error(in)) {
106
return JNI_TRUE;
107
}
108
109
if (threadControl_isDebugThread(thread)) {
110
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
111
return JNI_TRUE;
112
}
113
114
/* true means it is okay to unblock the commandLoop thread */
115
error = threadControl_resumeThread(thread, JNI_TRUE);
116
if (error != JVMTI_ERROR_NONE) {
117
outStream_setError(out, map2jdwpError(error));
118
}
119
return JNI_TRUE;
120
}
121
122
static jboolean
123
status(PacketInputStream *in, PacketOutputStream *out)
124
{
125
jdwpThreadStatus threadStatus;
126
jint statusFlags;
127
jvmtiError error;
128
jthread thread;
129
130
thread = inStream_readThreadRef(getEnv(), in);
131
if (inStream_error(in)) {
132
return JNI_TRUE;
133
}
134
135
if (threadControl_isDebugThread(thread)) {
136
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
137
return JNI_TRUE;
138
}
139
140
error = threadControl_applicationThreadStatus(thread, &threadStatus,
141
&statusFlags);
142
if (error != JVMTI_ERROR_NONE) {
143
outStream_setError(out, map2jdwpError(error));
144
return JNI_TRUE;
145
}
146
(void)outStream_writeInt(out, threadStatus);
147
(void)outStream_writeInt(out, statusFlags);
148
return JNI_TRUE;
149
}
150
151
static jboolean
152
threadGroup(PacketInputStream *in, PacketOutputStream *out)
153
{
154
JNIEnv *env;
155
jthread thread;
156
157
env = getEnv();
158
159
thread = inStream_readThreadRef(env, in);
160
if (inStream_error(in)) {
161
return JNI_TRUE;
162
}
163
164
if (threadControl_isDebugThread(thread)) {
165
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
166
return JNI_TRUE;
167
}
168
169
WITH_LOCAL_REFS(env, 1) {
170
171
jvmtiThreadInfo info;
172
jvmtiError error;
173
174
(void)memset(&info, 0, sizeof(info));
175
176
error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
177
(gdata->jvmti, thread, &info);
178
179
if (error != JVMTI_ERROR_NONE) {
180
outStream_setError(out, map2jdwpError(error));
181
} else {
182
(void)outStream_writeObjectRef(env, out, info.thread_group);
183
}
184
185
if ( info.name!=NULL )
186
jvmtiDeallocate(info.name);
187
188
} END_WITH_LOCAL_REFS(env);
189
190
return JNI_TRUE;
191
}
192
193
static jboolean
194
validateSuspendedThread(PacketOutputStream *out, jthread thread)
195
{
196
jvmtiError error;
197
jint count;
198
199
error = threadControl_suspendCount(thread, &count);
200
if (error != JVMTI_ERROR_NONE) {
201
outStream_setError(out, map2jdwpError(error));
202
return JNI_FALSE;
203
}
204
205
if (count == 0) {
206
outStream_setError(out, JDWP_ERROR(THREAD_NOT_SUSPENDED));
207
return JNI_FALSE;
208
}
209
210
return JNI_TRUE;
211
}
212
213
static jboolean
214
frames(PacketInputStream *in, PacketOutputStream *out)
215
{
216
jvmtiError error;
217
FrameNumber fnum;
218
jint count;
219
JNIEnv *env;
220
jthread thread;
221
jint startIndex;
222
jint length;
223
224
env = getEnv();
225
226
thread = inStream_readThreadRef(env, in);
227
if (inStream_error(in)) {
228
return JNI_TRUE;
229
}
230
startIndex = inStream_readInt(in);
231
if (inStream_error(in)) {
232
return JNI_TRUE;
233
}
234
length = inStream_readInt(in);
235
if (inStream_error(in)) {
236
return JNI_TRUE;
237
}
238
239
if (threadControl_isDebugThread(thread)) {
240
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
241
return JNI_TRUE;
242
}
243
244
if (!validateSuspendedThread(out, thread)) {
245
return JNI_TRUE;
246
}
247
248
error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
249
(gdata->jvmti, thread, &count);
250
if (error != JVMTI_ERROR_NONE) {
251
outStream_setError(out, map2jdwpError(error));
252
return JNI_TRUE;
253
}
254
255
if (length == -1) {
256
length = count - startIndex;
257
}
258
259
if (length == 0) {
260
(void)outStream_writeInt(out, 0);
261
return JNI_TRUE;
262
}
263
264
if ((startIndex < 0) || (startIndex > count - 1)) {
265
outStream_setError(out, JDWP_ERROR(INVALID_INDEX));
266
return JNI_TRUE;
267
}
268
269
if ((length < 0) || (length + startIndex > count)) {
270
outStream_setError(out, JDWP_ERROR(INVALID_LENGTH));
271
return JNI_TRUE;
272
}
273
274
(void)outStream_writeInt(out, length);
275
276
for(fnum = startIndex ; fnum < startIndex+length ; fnum++ ) {
277
278
WITH_LOCAL_REFS(env, 1) {
279
280
jclass clazz;
281
jmethodID method;
282
jlocation location;
283
284
/* Get location info */
285
error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
286
(gdata->jvmti, thread, fnum, &method, &location);
287
if (error == JVMTI_ERROR_OPAQUE_FRAME) {
288
clazz = NULL;
289
location = -1L;
290
error = JVMTI_ERROR_NONE;
291
} else if ( error == JVMTI_ERROR_NONE ) {
292
error = methodClass(method, &clazz);
293
if ( error == JVMTI_ERROR_NONE ) {
294
FrameID frame;
295
frame = createFrameID(thread, fnum);
296
(void)outStream_writeFrameID(out, frame);
297
writeCodeLocation(out, clazz, method, location);
298
}
299
}
300
301
} END_WITH_LOCAL_REFS(env);
302
303
if (error != JVMTI_ERROR_NONE)
304
break;
305
306
}
307
308
if (error != JVMTI_ERROR_NONE) {
309
outStream_setError(out, map2jdwpError(error));
310
}
311
return JNI_TRUE;
312
}
313
314
static jboolean
315
getFrameCount(PacketInputStream *in, PacketOutputStream *out)
316
{
317
jvmtiError error;
318
jint count;
319
jthread thread;
320
321
thread = inStream_readThreadRef(getEnv(), in);
322
if (inStream_error(in)) {
323
return JNI_TRUE;
324
}
325
326
if (threadControl_isDebugThread(thread)) {
327
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
328
return JNI_TRUE;
329
}
330
331
if (!validateSuspendedThread(out, thread)) {
332
return JNI_TRUE;
333
}
334
335
error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
336
(gdata->jvmti, thread, &count);
337
if (error != JVMTI_ERROR_NONE) {
338
outStream_setError(out, map2jdwpError(error));
339
return JNI_TRUE;
340
}
341
(void)outStream_writeInt(out, count);
342
343
return JNI_TRUE;
344
}
345
346
static jboolean
347
ownedMonitors(PacketInputStream *in, PacketOutputStream *out)
348
{
349
JNIEnv *env;
350
jthread thread;
351
352
env = getEnv();
353
354
thread = inStream_readThreadRef(env, in);
355
if (inStream_error(in)) {
356
return JNI_TRUE;
357
}
358
359
if (threadControl_isDebugThread(thread)) {
360
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
361
return JNI_TRUE;
362
}
363
364
if (!validateSuspendedThread(out, thread)) {
365
return JNI_TRUE;
366
}
367
368
WITH_LOCAL_REFS(env, 1) {
369
370
jvmtiError error;
371
jint count = 0;
372
jobject *monitors = NULL;
373
374
error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorInfo)
375
(gdata->jvmti, thread, &count, &monitors);
376
if (error != JVMTI_ERROR_NONE) {
377
outStream_setError(out, map2jdwpError(error));
378
} else {
379
int i;
380
(void)outStream_writeInt(out, count);
381
for (i = 0; i < count; i++) {
382
jobject monitor = monitors[i];
383
(void)outStream_writeByte(out, specificTypeKey(env, monitor));
384
(void)outStream_writeObjectRef(env, out, monitor);
385
}
386
}
387
if (monitors != NULL)
388
jvmtiDeallocate(monitors);
389
390
} END_WITH_LOCAL_REFS(env);
391
392
return JNI_TRUE;
393
}
394
395
static jboolean
396
currentContendedMonitor(PacketInputStream *in, PacketOutputStream *out)
397
{
398
JNIEnv *env;
399
jthread thread;
400
401
env = getEnv();
402
403
thread = inStream_readThreadRef(env, in);
404
if (inStream_error(in)) {
405
return JNI_TRUE;
406
}
407
408
if (thread == NULL || threadControl_isDebugThread(thread)) {
409
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
410
return JNI_TRUE;
411
}
412
413
if (!validateSuspendedThread(out, thread)) {
414
return JNI_TRUE;
415
}
416
417
WITH_LOCAL_REFS(env, 1) {
418
419
jobject monitor;
420
jvmtiError error;
421
422
error = JVMTI_FUNC_PTR(gdata->jvmti,GetCurrentContendedMonitor)
423
(gdata->jvmti, thread, &monitor);
424
425
if (error != JVMTI_ERROR_NONE) {
426
outStream_setError(out, map2jdwpError(error));
427
} else {
428
(void)outStream_writeByte(out, specificTypeKey(env, monitor));
429
(void)outStream_writeObjectRef(env, out, monitor);
430
}
431
432
} END_WITH_LOCAL_REFS(env);
433
434
return JNI_TRUE;
435
}
436
437
static jboolean
438
stop(PacketInputStream *in, PacketOutputStream *out)
439
{
440
jvmtiError error;
441
jthread thread;
442
jobject throwable;
443
JNIEnv *env;
444
445
env = getEnv();
446
thread = inStream_readThreadRef(env, in);
447
if (inStream_error(in)) {
448
return JNI_TRUE;
449
}
450
throwable = inStream_readObjectRef(env, in);
451
if (inStream_error(in)) {
452
return JNI_TRUE;
453
}
454
455
if (threadControl_isDebugThread(thread)) {
456
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
457
return JNI_TRUE;
458
}
459
460
error = threadControl_stop(thread, throwable);
461
if (error != JVMTI_ERROR_NONE) {
462
outStream_setError(out, map2jdwpError(error));
463
}
464
return JNI_TRUE;
465
}
466
467
static jboolean
468
interrupt(PacketInputStream *in, PacketOutputStream *out)
469
{
470
jvmtiError error;
471
jthread thread;
472
473
thread = inStream_readThreadRef(getEnv(), in);
474
if (inStream_error(in)) {
475
return JNI_TRUE;
476
}
477
478
if (threadControl_isDebugThread(thread)) {
479
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
480
return JNI_TRUE;
481
}
482
483
error = threadControl_interrupt(thread);
484
if (error != JVMTI_ERROR_NONE) {
485
outStream_setError(out, map2jdwpError(error));
486
}
487
return JNI_TRUE;
488
}
489
490
static jboolean
491
suspendCount(PacketInputStream *in, PacketOutputStream *out)
492
{
493
jvmtiError error;
494
jint count;
495
jthread thread;
496
497
thread = inStream_readThreadRef(getEnv(), in);
498
if (inStream_error(in)) {
499
return JNI_TRUE;
500
}
501
502
if (threadControl_isDebugThread(thread)) {
503
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
504
return JNI_TRUE;
505
}
506
507
error = threadControl_suspendCount(thread, &count);
508
if (error != JVMTI_ERROR_NONE) {
509
outStream_setError(out, map2jdwpError(error));
510
return JNI_TRUE;
511
}
512
513
(void)outStream_writeInt(out, count);
514
return JNI_TRUE;
515
}
516
517
static jboolean
518
ownedMonitorsWithStackDepth(PacketInputStream *in, PacketOutputStream *out)
519
{
520
JNIEnv *env;
521
jthread thread;
522
523
thread = inStream_readThreadRef(getEnv(), in);
524
if (inStream_error(in)) {
525
return JNI_TRUE;
526
}
527
528
if (thread == NULL || threadControl_isDebugThread(thread)) {
529
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
530
return JNI_TRUE;
531
}
532
533
if (!validateSuspendedThread(out, thread)) {
534
return JNI_TRUE;
535
}
536
537
env = getEnv();
538
539
WITH_LOCAL_REFS(env, 1) {
540
541
jvmtiError error = JVMTI_ERROR_NONE;
542
jint count = 0;
543
jvmtiMonitorStackDepthInfo *monitors=NULL;
544
545
error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorStackDepthInfo)
546
(gdata->jvmti, thread, &count, &monitors);
547
548
if (error != JVMTI_ERROR_NONE) {
549
outStream_setError(out, map2jdwpError(error));
550
} else {
551
int i;
552
(void)outStream_writeInt(out, count);
553
for (i = 0; i < count; i++) {
554
jobject monitor = monitors[i].monitor;
555
(void)outStream_writeByte(out, specificTypeKey(env, monitor));
556
(void)outStream_writeObjectRef(getEnv(), out, monitor);
557
(void)outStream_writeInt(out,monitors[i].stack_depth);
558
}
559
}
560
if (monitors != NULL) {
561
jvmtiDeallocate(monitors);
562
}
563
564
} END_WITH_LOCAL_REFS(env);
565
566
return JNI_TRUE;
567
}
568
569
static jboolean
570
forceEarlyReturn(PacketInputStream *in, PacketOutputStream *out)
571
{
572
JNIEnv *env;
573
jthread thread;
574
jvalue value;
575
jbyte typeKey;
576
jvmtiError error;
577
578
env = getEnv();
579
thread = inStream_readThreadRef(env, in);
580
if (inStream_error(in)) {
581
return JNI_TRUE;
582
}
583
584
if (threadControl_isDebugThread(thread)) {
585
outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
586
return JNI_TRUE;
587
}
588
589
typeKey = inStream_readByte(in);
590
if (inStream_error(in)) {
591
return JNI_TRUE;
592
}
593
594
if (isObjectTag(typeKey)) {
595
value.l = inStream_readObjectRef(env, in);
596
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnObject)
597
(gdata->jvmti, thread, value.l);
598
} else {
599
switch (typeKey) {
600
case JDWP_TAG(VOID):
601
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnVoid)
602
(gdata->jvmti, thread);
603
break;
604
case JDWP_TAG(BYTE):
605
value.b = inStream_readByte(in);
606
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
607
(gdata->jvmti, thread, value.b);
608
break;
609
610
case JDWP_TAG(CHAR):
611
value.c = inStream_readChar(in);
612
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
613
(gdata->jvmti, thread, value.c);
614
break;
615
616
case JDWP_TAG(FLOAT):
617
value.f = inStream_readFloat(in);
618
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnFloat)
619
(gdata->jvmti, thread, value.f);
620
break;
621
622
case JDWP_TAG(DOUBLE):
623
value.d = inStream_readDouble(in);
624
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnDouble)
625
(gdata->jvmti, thread, value.d);
626
break;
627
628
case JDWP_TAG(INT):
629
value.i = inStream_readInt(in);
630
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
631
(gdata->jvmti, thread, value.i);
632
break;
633
634
case JDWP_TAG(LONG):
635
value.j = inStream_readLong(in);
636
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnLong)
637
(gdata->jvmti, thread, value.j);
638
break;
639
640
case JDWP_TAG(SHORT):
641
value.s = inStream_readShort(in);
642
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
643
(gdata->jvmti, thread, value.s);
644
break;
645
646
case JDWP_TAG(BOOLEAN):
647
value.z = inStream_readBoolean(in);
648
error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
649
(gdata->jvmti, thread, value.z);
650
break;
651
652
default:
653
error = AGENT_ERROR_INVALID_TAG;
654
break;
655
}
656
}
657
{
658
jdwpError serror = map2jdwpError(error);
659
if (serror != JDWP_ERROR(NONE)) {
660
outStream_setError(out, serror);
661
}
662
}
663
return JNI_TRUE;
664
}
665
666
667
void *ThreadReference_Cmds[] = { (void *)14,
668
(void *)name,
669
(void *)suspend,
670
(void *)resume,
671
(void *)status,
672
(void *)threadGroup,
673
(void *)frames,
674
(void *)getFrameCount,
675
(void *)ownedMonitors,
676
(void *)currentContendedMonitor,
677
(void *)stop,
678
(void *)interrupt,
679
(void *)suspendCount,
680
(void *)ownedMonitorsWithStackDepth,
681
(void *)forceEarlyReturn
682
};
683
684