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/VirtualMachineImpl.c
38765 views
1
/*
2
* Copyright (c) 1998, 2006, 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 "VirtualMachineImpl.h"
28
#include "commonRef.h"
29
#include "inStream.h"
30
#include "outStream.h"
31
#include "eventHandler.h"
32
#include "eventHelper.h"
33
#include "threadControl.h"
34
#include "SDE.h"
35
#include "FrameID.h"
36
37
static char *versionName = "Java Debug Wire Protocol (Reference Implementation)";
38
static int majorVersion = 1; /* JDWP major version */
39
static int minorVersion = 8; /* JDWP minor version */
40
41
static jboolean
42
version(PacketInputStream *in, PacketOutputStream *out)
43
{
44
char buf[500];
45
char *vmName;
46
char *vmVersion;
47
char *vmInfo;
48
49
if (gdata->vmDead) {
50
outStream_setError(out, JDWP_ERROR(VM_DEAD));
51
return JNI_TRUE;
52
}
53
54
vmVersion = gdata->property_java_version;
55
if (vmVersion == NULL) {
56
vmVersion = "<unknown>";
57
}
58
vmName = gdata->property_java_vm_name;
59
if (vmName == NULL) {
60
vmName = "<unknown>";
61
}
62
vmInfo = gdata->property_java_vm_info;
63
if (vmInfo == NULL) {
64
vmInfo = "<unknown>";
65
}
66
67
/*
68
* Write the descriptive version information
69
*/
70
(void)snprintf(buf, sizeof(buf),
71
"%s version %d.%d\nJVM Debug Interface version %d.%d\n"
72
"JVM version %s (%s, %s)",
73
versionName, majorVersion, minorVersion,
74
jvmtiMajorVersion(), jvmtiMinorVersion(),
75
vmVersion, vmName, vmInfo);
76
(void)outStream_writeString(out, buf);
77
78
/*
79
* Write the JDWP version numbers
80
*/
81
(void)outStream_writeInt(out, majorVersion);
82
(void)outStream_writeInt(out, minorVersion);
83
84
/*
85
* Write the VM version and name
86
*/
87
(void)outStream_writeString(out, vmVersion);
88
(void)outStream_writeString(out, vmName);
89
90
return JNI_TRUE;
91
}
92
93
static jboolean
94
classesForSignature(PacketInputStream *in, PacketOutputStream *out)
95
{
96
JNIEnv *env;
97
char *signature;
98
99
if (gdata->vmDead) {
100
outStream_setError(out, JDWP_ERROR(VM_DEAD));
101
return JNI_TRUE;
102
}
103
104
signature = inStream_readString(in);
105
if (signature == NULL) {
106
outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
107
return JNI_TRUE;
108
}
109
if (inStream_error(in)) {
110
return JNI_TRUE;
111
}
112
113
env = getEnv();
114
115
WITH_LOCAL_REFS(env, 1) {
116
117
jint classCount;
118
jclass *theClasses;
119
jvmtiError error;
120
121
error = allLoadedClasses(&theClasses, &classCount);
122
if ( error == JVMTI_ERROR_NONE ) {
123
/* Count classes in theClasses which match signature */
124
int matchCount = 0;
125
/* Count classes written to the JDWP connection */
126
int writtenCount = 0;
127
int i;
128
129
for (i=0; i<classCount; i++) {
130
jclass clazz = theClasses[i];
131
jint status = classStatus(clazz);
132
char *candidate_signature = NULL;
133
jint wanted =
134
(JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY|
135
JVMTI_CLASS_STATUS_PRIMITIVE);
136
137
/* We want prepared classes, primitives, and arrays only */
138
if ((status & wanted) == 0) {
139
continue;
140
}
141
142
error = classSignature(clazz, &candidate_signature, NULL);
143
if (error != JVMTI_ERROR_NONE) {
144
break;
145
}
146
147
if (strcmp(candidate_signature, signature) == 0) {
148
/* Float interesting classes (those that
149
* are matching and are prepared) to the
150
* beginning of the array.
151
*/
152
theClasses[i] = theClasses[matchCount];
153
theClasses[matchCount++] = clazz;
154
}
155
jvmtiDeallocate(candidate_signature);
156
}
157
158
/* At this point matching prepared classes occupy
159
* indicies 0 thru matchCount-1 of theClasses.
160
*/
161
162
if ( error == JVMTI_ERROR_NONE ) {
163
(void)outStream_writeInt(out, matchCount);
164
for (; writtenCount < matchCount; writtenCount++) {
165
jclass clazz = theClasses[writtenCount];
166
jint status = classStatus(clazz);
167
jbyte tag = referenceTypeTag(clazz);
168
(void)outStream_writeByte(out, tag);
169
(void)outStream_writeObjectRef(env, out, clazz);
170
(void)outStream_writeInt(out, map2jdwpClassStatus(status));
171
/* No point in continuing if there's an error */
172
if (outStream_error(out)) {
173
break;
174
}
175
}
176
}
177
178
jvmtiDeallocate(theClasses);
179
}
180
181
if ( error != JVMTI_ERROR_NONE ) {
182
outStream_setError(out, map2jdwpError(error));
183
}
184
185
} END_WITH_LOCAL_REFS(env);
186
187
jvmtiDeallocate(signature);
188
189
return JNI_TRUE;
190
}
191
192
static jboolean
193
allClasses1(PacketInputStream *in, PacketOutputStream *out, int outputGenerics)
194
{
195
JNIEnv *env;
196
197
if (gdata->vmDead) {
198
outStream_setError(out, JDWP_ERROR(VM_DEAD));
199
return JNI_TRUE;
200
}
201
202
env = getEnv();
203
204
WITH_LOCAL_REFS(env, 1) {
205
206
jint classCount;
207
jclass *theClasses;
208
jvmtiError error;
209
210
error = allLoadedClasses(&theClasses, &classCount);
211
if ( error != JVMTI_ERROR_NONE ) {
212
outStream_setError(out, map2jdwpError(error));
213
} else {
214
/* Count classes in theClasses which are prepared */
215
int prepCount = 0;
216
/* Count classes written to the JDWP connection */
217
int writtenCount = 0;
218
int i;
219
220
for (i=0; i<classCount; i++) {
221
jclass clazz = theClasses[i];
222
jint status = classStatus(clazz);
223
jint wanted =
224
(JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY);
225
226
/* We want prepared classes and arrays only */
227
if ((status & wanted) != 0) {
228
/* Float interesting classes (those that
229
* are prepared) to the beginning of the array.
230
*/
231
theClasses[i] = theClasses[prepCount];
232
theClasses[prepCount++] = clazz;
233
}
234
}
235
236
/* At this point prepared classes occupy
237
* indicies 0 thru prepCount-1 of theClasses.
238
*/
239
240
(void)outStream_writeInt(out, prepCount);
241
for (; writtenCount < prepCount; writtenCount++) {
242
char *signature = NULL;
243
char *genericSignature = NULL;
244
jclass clazz = theClasses[writtenCount];
245
jint status = classStatus(clazz);
246
jbyte tag = referenceTypeTag(clazz);
247
jvmtiError error;
248
249
error = classSignature(clazz, &signature, &genericSignature);
250
if (error != JVMTI_ERROR_NONE) {
251
outStream_setError(out, map2jdwpError(error));
252
break;
253
}
254
255
(void)outStream_writeByte(out, tag);
256
(void)outStream_writeObjectRef(env, out, clazz);
257
(void)outStream_writeString(out, signature);
258
if (outputGenerics == 1) {
259
writeGenericSignature(out, genericSignature);
260
}
261
262
(void)outStream_writeInt(out, map2jdwpClassStatus(status));
263
jvmtiDeallocate(signature);
264
if (genericSignature != NULL) {
265
jvmtiDeallocate(genericSignature);
266
}
267
268
/* No point in continuing if there's an error */
269
if (outStream_error(out)) {
270
break;
271
}
272
}
273
jvmtiDeallocate(theClasses);
274
}
275
276
} END_WITH_LOCAL_REFS(env);
277
278
return JNI_TRUE;
279
}
280
281
static jboolean
282
allClasses(PacketInputStream *in, PacketOutputStream *out)
283
{
284
return allClasses1(in, out, 0);
285
}
286
287
static jboolean
288
allClassesWithGeneric(PacketInputStream *in, PacketOutputStream *out)
289
{
290
return allClasses1(in, out, 1);
291
}
292
293
/***********************************************************/
294
295
296
static jboolean
297
instanceCounts(PacketInputStream *in, PacketOutputStream *out)
298
{
299
jint classCount;
300
jclass *classes;
301
JNIEnv *env;
302
int ii;
303
304
if (gdata->vmDead) {
305
outStream_setError(out, JDWP_ERROR(VM_DEAD));
306
return JNI_TRUE;
307
}
308
309
classCount = inStream_readInt(in);
310
311
if (inStream_error(in)) {
312
return JNI_TRUE;
313
}
314
if (classCount == 0) {
315
(void)outStream_writeInt(out, 0);
316
return JNI_TRUE;
317
}
318
if (classCount < 0) {
319
outStream_setError(out, JDWP_ERROR(ILLEGAL_ARGUMENT));
320
return JNI_TRUE;
321
}
322
env = getEnv();
323
classes = jvmtiAllocate(classCount * (int)sizeof(jclass));
324
for (ii = 0; ii < classCount; ii++) {
325
jdwpError errorCode;
326
classes[ii] = inStream_readClassRef(env, in);
327
errorCode = inStream_error(in);
328
if (errorCode != JDWP_ERROR(NONE)) {
329
/*
330
* A class could have been unloaded/gc'd so
331
* if we get an error, just ignore it and keep
332
* going. An instanceCount of 0 will be returned.
333
*/
334
if (errorCode == JDWP_ERROR(INVALID_OBJECT) ||
335
errorCode == JDWP_ERROR(INVALID_CLASS)) {
336
inStream_clearError(in);
337
classes[ii] = NULL;
338
continue;
339
}
340
jvmtiDeallocate(classes);
341
return JNI_TRUE;
342
}
343
}
344
345
WITH_LOCAL_REFS(env, 1) {
346
jlong *counts;
347
jvmtiError error;
348
349
counts = jvmtiAllocate(classCount * (int)sizeof(jlong));
350
/* Iterate over heap getting info on these classes */
351
error = classInstanceCounts(classCount, classes, counts);
352
if (error != JVMTI_ERROR_NONE) {
353
outStream_setError(out, map2jdwpError(error));
354
} else {
355
(void)outStream_writeInt(out, classCount);
356
for (ii = 0; ii < classCount; ii++) {
357
(void)outStream_writeLong(out, counts[ii]);
358
}
359
}
360
jvmtiDeallocate(counts);
361
} END_WITH_LOCAL_REFS(env);
362
jvmtiDeallocate(classes);
363
return JNI_TRUE;
364
}
365
366
static jboolean
367
redefineClasses(PacketInputStream *in, PacketOutputStream *out)
368
{
369
jvmtiClassDefinition *classDefs;
370
jboolean ok = JNI_TRUE;
371
jint classCount;
372
jint i;
373
JNIEnv *env;
374
375
if (gdata->vmDead) {
376
/* quietly ignore */
377
return JNI_TRUE;
378
}
379
380
classCount = inStream_readInt(in);
381
if (inStream_error(in)) {
382
return JNI_TRUE;
383
}
384
if ( classCount == 0 ) {
385
return JNI_TRUE;
386
}
387
/*LINTED*/
388
classDefs = jvmtiAllocate(classCount*(int)sizeof(jvmtiClassDefinition));
389
if (classDefs == NULL) {
390
outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
391
return JNI_TRUE;
392
}
393
/*LINTED*/
394
(void)memset(classDefs, 0, classCount*sizeof(jvmtiClassDefinition));
395
396
env = getEnv();
397
for (i = 0; i < classCount; ++i) {
398
int byteCount;
399
unsigned char * bytes;
400
jclass clazz;
401
402
clazz = inStream_readClassRef(env, in);
403
if (inStream_error(in)) {
404
ok = JNI_FALSE;
405
break;
406
}
407
byteCount = inStream_readInt(in);
408
if (inStream_error(in)) {
409
ok = JNI_FALSE;
410
break;
411
}
412
if ( byteCount <= 0 ) {
413
outStream_setError(out, JDWP_ERROR(INVALID_CLASS_FORMAT));
414
ok = JNI_FALSE;
415
break;
416
}
417
bytes = (unsigned char *)jvmtiAllocate(byteCount);
418
if (bytes == NULL) {
419
outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
420
ok = JNI_FALSE;
421
break;
422
}
423
(void)inStream_readBytes(in, byteCount, (jbyte *)bytes);
424
if (inStream_error(in)) {
425
ok = JNI_FALSE;
426
break;
427
}
428
429
classDefs[i].klass = clazz;
430
classDefs[i].class_byte_count = byteCount;
431
classDefs[i].class_bytes = bytes;
432
}
433
434
if (ok == JNI_TRUE) {
435
jvmtiError error;
436
437
error = JVMTI_FUNC_PTR(gdata->jvmti,RedefineClasses)
438
(gdata->jvmti, classCount, classDefs);
439
if (error != JVMTI_ERROR_NONE) {
440
outStream_setError(out, map2jdwpError(error));
441
} else {
442
/* zap our BP info */
443
for ( i = 0 ; i < classCount; i++ ) {
444
eventHandler_freeClassBreakpoints(classDefs[i].klass);
445
}
446
}
447
}
448
449
/* free up allocated memory */
450
for ( i = 0 ; i < classCount; i++ ) {
451
if ( classDefs[i].class_bytes != NULL ) {
452
jvmtiDeallocate((void*)classDefs[i].class_bytes);
453
}
454
}
455
jvmtiDeallocate(classDefs);
456
457
return JNI_TRUE;
458
}
459
460
static jboolean
461
setDefaultStratum(PacketInputStream *in, PacketOutputStream *out)
462
{
463
char *stratumId;
464
465
if (gdata->vmDead) {
466
/* quietly ignore */
467
return JNI_TRUE;
468
}
469
470
stratumId = inStream_readString(in);
471
if (inStream_error(in)) {
472
return JNI_TRUE;
473
} else if (strcmp(stratumId, "") == 0) {
474
stratumId = NULL;
475
}
476
setGlobalStratumId(stratumId);
477
478
return JNI_TRUE;
479
}
480
481
static jboolean
482
getAllThreads(PacketInputStream *in, PacketOutputStream *out)
483
{
484
JNIEnv *env;
485
486
if (gdata->vmDead) {
487
outStream_setError(out, JDWP_ERROR(VM_DEAD));
488
return JNI_TRUE;
489
}
490
491
env = getEnv();
492
493
WITH_LOCAL_REFS(env, 1) {
494
495
int i;
496
jint threadCount;
497
jthread *theThreads;
498
499
theThreads = allThreads(&threadCount);
500
if (theThreads == NULL) {
501
outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
502
} else {
503
/* Squish out all of the debugger-spawned threads */
504
threadCount = filterDebugThreads(theThreads, threadCount);
505
506
(void)outStream_writeInt(out, threadCount);
507
for (i = 0; i <threadCount; i++) {
508
(void)outStream_writeObjectRef(env, out, theThreads[i]);
509
}
510
511
jvmtiDeallocate(theThreads);
512
}
513
514
} END_WITH_LOCAL_REFS(env);
515
516
return JNI_TRUE;
517
}
518
519
static jboolean
520
topLevelThreadGroups(PacketInputStream *in, PacketOutputStream *out)
521
{
522
JNIEnv *env;
523
524
if (gdata->vmDead) {
525
outStream_setError(out, JDWP_ERROR(VM_DEAD));
526
return JNI_TRUE;
527
}
528
529
env = getEnv();
530
531
WITH_LOCAL_REFS(env, 1) {
532
533
jvmtiError error;
534
jint groupCount;
535
jthreadGroup *groups;
536
537
groups = NULL;
538
error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups)
539
(gdata->jvmti, &groupCount, &groups);
540
if (error != JVMTI_ERROR_NONE) {
541
outStream_setError(out, map2jdwpError(error));
542
} else {
543
int i;
544
545
(void)outStream_writeInt(out, groupCount);
546
for (i = 0; i < groupCount; i++) {
547
(void)outStream_writeObjectRef(env, out, groups[i]);
548
}
549
550
jvmtiDeallocate(groups);
551
}
552
553
} END_WITH_LOCAL_REFS(env);
554
555
return JNI_TRUE;
556
}
557
558
static jboolean
559
dispose(PacketInputStream *in, PacketOutputStream *out)
560
{
561
return JNI_TRUE;
562
}
563
564
static jboolean
565
idSizes(PacketInputStream *in, PacketOutputStream *out)
566
{
567
(void)outStream_writeInt(out, sizeof(jfieldID)); /* fields */
568
(void)outStream_writeInt(out, sizeof(jmethodID)); /* methods */
569
(void)outStream_writeInt(out, sizeof(jlong)); /* objects */
570
(void)outStream_writeInt(out, sizeof(jlong)); /* referent types */
571
(void)outStream_writeInt(out, sizeof(FrameID)); /* frames */
572
return JNI_TRUE;
573
}
574
575
static jboolean
576
suspend(PacketInputStream *in, PacketOutputStream *out)
577
{
578
jvmtiError error;
579
580
if (gdata->vmDead) {
581
outStream_setError(out, JDWP_ERROR(VM_DEAD));
582
return JNI_TRUE;
583
}
584
error = threadControl_suspendAll();
585
if (error != JVMTI_ERROR_NONE) {
586
outStream_setError(out, map2jdwpError(error));
587
}
588
return JNI_TRUE;
589
}
590
591
static jboolean
592
resume(PacketInputStream *in, PacketOutputStream *out)
593
{
594
jvmtiError error;
595
596
if (gdata->vmDead) {
597
outStream_setError(out, JDWP_ERROR(VM_DEAD));
598
return JNI_TRUE;
599
}
600
error = threadControl_resumeAll();
601
if (error != JVMTI_ERROR_NONE) {
602
outStream_setError(out, map2jdwpError(error));
603
}
604
return JNI_TRUE;
605
}
606
607
static jboolean
608
doExit(PacketInputStream *in, PacketOutputStream *out)
609
{
610
jint exitCode;
611
612
exitCode = inStream_readInt(in);
613
if (gdata->vmDead) {
614
/* quietly ignore */
615
return JNI_FALSE;
616
}
617
618
/* We send the reply from here because we are about to exit. */
619
if (inStream_error(in)) {
620
outStream_setError(out, inStream_error(in));
621
}
622
outStream_sendReply(out);
623
624
forceExit(exitCode);
625
626
/* Shouldn't get here */
627
JDI_ASSERT(JNI_FALSE);
628
629
/* Shut up the compiler */
630
return JNI_FALSE;
631
632
}
633
634
static jboolean
635
createString(PacketInputStream *in, PacketOutputStream *out)
636
{
637
JNIEnv *env;
638
char *cstring;
639
640
if (gdata->vmDead) {
641
outStream_setError(out, JDWP_ERROR(VM_DEAD));
642
return JNI_TRUE;
643
}
644
645
cstring = inStream_readString(in);
646
if (cstring == NULL) {
647
outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
648
return JNI_TRUE;
649
}
650
if (inStream_error(in)) {
651
return JNI_TRUE;
652
}
653
654
env = getEnv();
655
656
WITH_LOCAL_REFS(env, 1) {
657
658
jstring string;
659
660
string = JNI_FUNC_PTR(env,NewStringUTF)(env, cstring);
661
if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
662
outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
663
} else {
664
(void)outStream_writeObjectRef(env, out, string);
665
}
666
667
} END_WITH_LOCAL_REFS(env);
668
669
jvmtiDeallocate(cstring);
670
671
return JNI_TRUE;
672
}
673
674
static jboolean
675
capabilities(PacketInputStream *in, PacketOutputStream *out)
676
{
677
jvmtiCapabilities caps;
678
jvmtiError error;
679
680
if (gdata->vmDead) {
681
outStream_setError(out, JDWP_ERROR(VM_DEAD));
682
return JNI_TRUE;
683
}
684
error = jvmtiGetCapabilities(&caps);
685
if (error != JVMTI_ERROR_NONE) {
686
outStream_setError(out, map2jdwpError(error));
687
return JNI_TRUE;
688
}
689
690
(void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_modification_events);
691
(void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_access_events);
692
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_bytecodes);
693
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_synthetic_attribute);
694
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_owned_monitor_info);
695
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_current_contended_monitor);
696
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_monitor_info);
697
return JNI_TRUE;
698
}
699
700
static jboolean
701
capabilitiesNew(PacketInputStream *in, PacketOutputStream *out)
702
{
703
jvmtiCapabilities caps;
704
jvmtiError error;
705
706
if (gdata->vmDead) {
707
outStream_setError(out, JDWP_ERROR(VM_DEAD));
708
return JNI_TRUE;
709
}
710
error = jvmtiGetCapabilities(&caps);
711
if (error != JVMTI_ERROR_NONE) {
712
outStream_setError(out, map2jdwpError(error));
713
return JNI_TRUE;
714
}
715
716
(void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_modification_events);
717
(void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_access_events);
718
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_bytecodes);
719
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_synthetic_attribute);
720
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_owned_monitor_info);
721
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_current_contended_monitor);
722
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_monitor_info);
723
724
/* new since JDWP version 1.4 */
725
(void)outStream_writeBoolean(out, (jboolean)caps.can_redefine_classes);
726
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE /* can_add_method */ );
727
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE /* can_unrestrictedly_redefine_classes */ );
728
/* 11: canPopFrames */
729
(void)outStream_writeBoolean(out, (jboolean)caps.can_pop_frame);
730
/* 12: canUseInstanceFilters */
731
(void)outStream_writeBoolean(out, (jboolean)JNI_TRUE);
732
/* 13: canGetSourceDebugExtension */
733
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_source_debug_extension);
734
/* 14: canRequestVMDeathEvent */
735
(void)outStream_writeBoolean(out, (jboolean)JNI_TRUE);
736
/* 15: canSetDefaultStratum */
737
(void)outStream_writeBoolean(out, (jboolean)JNI_TRUE);
738
/* 16: canGetInstanceInfo */
739
(void)outStream_writeBoolean(out, (jboolean)caps.can_tag_objects);
740
/* 17: canRequestMonitorEvents */
741
(void)outStream_writeBoolean(out, (jboolean)caps.can_generate_monitor_events);
742
/* 18: canGetMonitorFrameInfo */
743
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_owned_monitor_stack_depth_info);
744
/* remaining reserved */
745
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 19 */
746
/* 20 Can get constant pool information */
747
(void)outStream_writeBoolean(out, (jboolean)caps.can_get_constant_pool);
748
/* 21 Can force early return */
749
(void)outStream_writeBoolean(out, (jboolean)caps.can_force_early_return);
750
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 22 */
751
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 23 */
752
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 24 */
753
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 25 */
754
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 26 */
755
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 27 */
756
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 28 */
757
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 29 */
758
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 30 */
759
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 31 */
760
(void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 32 */
761
return JNI_TRUE;
762
}
763
764
static int
765
countPaths(char *string) {
766
int cnt = 1; /* always have one */
767
char *pos = string;
768
char *ps;
769
770
ps = gdata->property_path_separator;
771
if ( ps == NULL ) {
772
ps = ";";
773
}
774
while ((pos = strchr(pos, ps[0])) != NULL) {
775
++cnt;
776
++pos;
777
}
778
return cnt;
779
}
780
781
static void
782
writePaths(PacketOutputStream *out, char *string) {
783
char *pos;
784
char *ps;
785
char *buf;
786
int npaths;
787
int i;
788
789
buf = jvmtiAllocate((int)strlen(string)+1);
790
791
npaths = countPaths(string);
792
(void)outStream_writeInt(out, npaths);
793
794
ps = gdata->property_path_separator;
795
if ( ps == NULL ) {
796
ps = ";";
797
}
798
799
pos = string;
800
for ( i = 0 ; i < npaths ; i++ ) {
801
char *psPos;
802
int plen;
803
804
psPos = strchr(pos, ps[0]);
805
if ( psPos == NULL ) {
806
plen = (int)strlen(pos);
807
} else {
808
plen = (int)(psPos-pos);
809
psPos++;
810
}
811
(void)memcpy(buf, pos, plen);
812
buf[plen] = 0;
813
(void)outStream_writeString(out, buf);
814
pos = psPos;
815
}
816
817
jvmtiDeallocate(buf);
818
}
819
820
821
822
static jboolean
823
classPaths(PacketInputStream *in, PacketOutputStream *out)
824
{
825
char *ud;
826
char *bp;
827
char *cp;
828
829
ud = gdata->property_user_dir;
830
if ( ud == NULL ) {
831
ud = "";
832
}
833
cp = gdata->property_java_class_path;
834
if ( cp == NULL ) {
835
cp = "";
836
}
837
bp = gdata->property_sun_boot_class_path;
838
if ( bp == NULL ) {
839
bp = "";
840
}
841
(void)outStream_writeString(out, ud);
842
writePaths(out, cp);
843
writePaths(out, bp);
844
return JNI_TRUE;
845
}
846
847
static jboolean
848
disposeObjects(PacketInputStream *in, PacketOutputStream *out)
849
{
850
int i;
851
int refCount;
852
jlong id;
853
int requestCount;
854
JNIEnv *env;
855
856
if (gdata->vmDead) {
857
/* quietly ignore */
858
return JNI_TRUE;
859
}
860
861
requestCount = inStream_readInt(in);
862
if (inStream_error(in)) {
863
return JNI_TRUE;
864
}
865
866
env = getEnv();
867
for (i = 0; i < requestCount; i++) {
868
id = inStream_readObjectID(in);
869
refCount = inStream_readInt(in);
870
if (inStream_error(in)) {
871
return JNI_TRUE;
872
}
873
commonRef_releaseMultiple(env, id, refCount);
874
}
875
876
return JNI_TRUE;
877
}
878
879
static jboolean
880
holdEvents(PacketInputStream *in, PacketOutputStream *out)
881
{
882
eventHelper_holdEvents();
883
return JNI_TRUE;
884
}
885
886
static jboolean
887
releaseEvents(PacketInputStream *in, PacketOutputStream *out)
888
{
889
eventHelper_releaseEvents();
890
return JNI_TRUE;
891
}
892
893
void *VirtualMachine_Cmds[] = { (void *)21
894
,(void *)version
895
,(void *)classesForSignature
896
,(void *)allClasses
897
,(void *)getAllThreads
898
,(void *)topLevelThreadGroups
899
,(void *)dispose
900
,(void *)idSizes
901
,(void *)suspend
902
,(void *)resume
903
,(void *)doExit
904
,(void *)createString
905
,(void *)capabilities
906
,(void *)classPaths
907
,(void *)disposeObjects
908
,(void *)holdEvents
909
,(void *)releaseEvents
910
,(void *)capabilitiesNew
911
,(void *)redefineClasses
912
,(void *)setDefaultStratum
913
,(void *)allClassesWithGeneric
914
,(void *)instanceCounts
915
};
916
917