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/demo/jvmti/hprof/hprof_io.c
38829 views
1
/*
2
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
*
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* - Neither the name of Oracle nor the names of its
16
* contributors may be used to endorse or promote products derived
17
* from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* This source code is provided to illustrate the usage of a given feature
34
* or technique and has been deliberately simplified. Additional steps
35
* required for a production-quality application, such as security checks,
36
* input validation and proper error handling, might not be present in
37
* this sample code.
38
*/
39
40
41
/* All I/O functionality for hprof. */
42
43
/*
44
* The hprof agent has many forms of output:
45
*
46
* format=b gdata->output_format=='b'
47
* Binary format. Defined below. This is used by HAT.
48
* This is NOT the same format as emitted by JVMPI.
49
*
50
* format=a gdata->output_format=='a'
51
* Ascii format. Not exactly an ascii representation of the binary format.
52
*
53
* And many forms of dumps:
54
*
55
* heap=dump
56
* A large dump that in this implementation is written to a separate
57
* file first before being placed in the output file. Several reasons,
58
* the binary form needs a byte count of the length in the header, and
59
* references in this dump to other items need to be emitted first.
60
* So it's two pass, or use a temp file and copy.
61
* heap=sites
62
* Dumps the sites in the order of most allocations.
63
* cpu=samples
64
* Dumps the traces in order of most hits
65
* cpu=times
66
* Dumps the traces in the order of most time spent there.
67
* cpu=old (format=a only)
68
* Dumps out an older form of cpu output (old -prof format)
69
* monitor=y (format=a only)
70
* Dumps out a list of monitors in order of most contended.
71
*
72
* This file also includes a binary format check function that will read
73
* back in the hprof binary format and verify the syntax looks correct.
74
*
75
* WARNING: Besides the comments below, there is little format spec on this,
76
* however see:
77
* http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html#hprof
78
*/
79
80
#include "hprof.h"
81
82
typedef TableIndex HprofId;
83
84
#include "hprof_ioname.h"
85
#include "hprof_b_spec.h"
86
87
static int type_size[ /*HprofType*/ ] = HPROF_TYPE_SIZES;
88
89
static void dump_heap_segment_and_reset(jlong segment_size);
90
91
static void
92
not_implemented(void)
93
{
94
}
95
96
static IoNameIndex
97
get_name_index(char *name)
98
{
99
if (name != NULL && gdata->output_format == 'b') {
100
return ioname_find_or_create(name, NULL);
101
}
102
return 0;
103
}
104
105
static char *
106
signature_to_name(char *sig)
107
{
108
char *ptr;
109
char *basename;
110
char *name;
111
int i;
112
int len;
113
int name_len;
114
115
if ( sig != NULL ) {
116
switch ( sig[0] ) {
117
case JVM_SIGNATURE_CLASS:
118
ptr = strchr(sig+1, JVM_SIGNATURE_ENDCLASS);
119
if ( ptr == NULL ) {
120
basename = "Unknown_class";
121
break;
122
}
123
/*LINTED*/
124
name_len = (jint)(ptr - (sig+1));
125
name = HPROF_MALLOC(name_len+1);
126
(void)memcpy(name, sig+1, name_len);
127
name[name_len] = 0;
128
for ( i = 0 ; i < name_len ; i++ ) {
129
if ( name[i] == '/' ) name[i] = '.';
130
}
131
return name;
132
case JVM_SIGNATURE_ARRAY:
133
basename = signature_to_name(sig+1);
134
len = (int)strlen(basename);
135
name_len = len+2;
136
name = HPROF_MALLOC(name_len+1);
137
(void)memcpy(name, basename, len);
138
(void)memcpy(name+len, "[]", 2);
139
name[name_len] = 0;
140
HPROF_FREE(basename);
141
return name;
142
case JVM_SIGNATURE_FUNC:
143
ptr = strchr(sig+1, JVM_SIGNATURE_ENDFUNC);
144
if ( ptr == NULL ) {
145
basename = "Unknown_method";
146
break;
147
}
148
basename = "()"; /* Someday deal with method signatures */
149
break;
150
case JVM_SIGNATURE_BYTE:
151
basename = "byte";
152
break;
153
case JVM_SIGNATURE_CHAR:
154
basename = "char";
155
break;
156
case JVM_SIGNATURE_ENUM:
157
basename = "enum";
158
break;
159
case JVM_SIGNATURE_FLOAT:
160
basename = "float";
161
break;
162
case JVM_SIGNATURE_DOUBLE:
163
basename = "double";
164
break;
165
case JVM_SIGNATURE_INT:
166
basename = "int";
167
break;
168
case JVM_SIGNATURE_LONG:
169
basename = "long";
170
break;
171
case JVM_SIGNATURE_SHORT:
172
basename = "short";
173
break;
174
case JVM_SIGNATURE_VOID:
175
basename = "void";
176
break;
177
case JVM_SIGNATURE_BOOLEAN:
178
basename = "boolean";
179
break;
180
default:
181
basename = "Unknown_class";
182
break;
183
}
184
} else {
185
basename = "Unknown_class";
186
}
187
188
/* Simple basename */
189
name_len = (int)strlen(basename);
190
name = HPROF_MALLOC(name_len+1);
191
(void)strcpy(name, basename);
192
return name;
193
}
194
195
static int
196
size_from_field_info(int size)
197
{
198
if ( size == 0 ) {
199
size = (int)sizeof(HprofId);
200
}
201
return size;
202
}
203
204
static void
205
type_from_signature(const char *sig, HprofType *kind, jint *size)
206
{
207
*kind = HPROF_NORMAL_OBJECT;
208
*size = 0;
209
switch ( sig[0] ) {
210
case JVM_SIGNATURE_ENUM:
211
case JVM_SIGNATURE_CLASS:
212
case JVM_SIGNATURE_ARRAY:
213
*kind = HPROF_NORMAL_OBJECT;
214
break;
215
case JVM_SIGNATURE_BOOLEAN:
216
*kind = HPROF_BOOLEAN;
217
break;
218
case JVM_SIGNATURE_CHAR:
219
*kind = HPROF_CHAR;
220
break;
221
case JVM_SIGNATURE_FLOAT:
222
*kind = HPROF_FLOAT;
223
break;
224
case JVM_SIGNATURE_DOUBLE:
225
*kind = HPROF_DOUBLE;
226
break;
227
case JVM_SIGNATURE_BYTE:
228
*kind = HPROF_BYTE;
229
break;
230
case JVM_SIGNATURE_SHORT:
231
*kind = HPROF_SHORT;
232
break;
233
case JVM_SIGNATURE_INT:
234
*kind = HPROF_INT;
235
break;
236
case JVM_SIGNATURE_LONG:
237
*kind = HPROF_LONG;
238
break;
239
default:
240
HPROF_ASSERT(0);
241
break;
242
}
243
*size = type_size[*kind];
244
}
245
246
static void
247
type_array(const char *sig, HprofType *kind, jint *elem_size)
248
{
249
*kind = 0;
250
*elem_size = 0;
251
switch ( sig[0] ) {
252
case JVM_SIGNATURE_ARRAY:
253
type_from_signature(sig+1, kind, elem_size);
254
break;
255
}
256
}
257
258
static void
259
system_error(const char *system_call, int rc, int errnum)
260
{
261
char buf[256];
262
char details[256];
263
264
details[0] = 0;
265
if ( errnum != 0 ) {
266
md_system_error(details, (int)sizeof(details));
267
} else if ( rc >= 0 ) {
268
(void)strcpy(details,"Only part of buffer processed");
269
}
270
if ( details[0] == 0 ) {
271
(void)strcpy(details,"Unknown system error condition");
272
}
273
(void)md_snprintf(buf, sizeof(buf), "System %s failed: %s\n",
274
system_call, details);
275
HPROF_ERROR(JNI_TRUE, buf);
276
}
277
278
static void
279
system_write(int fd, void *buf, int len, jboolean socket)
280
{
281
int res;
282
283
HPROF_ASSERT(fd>=0);
284
if (socket) {
285
res = md_send(fd, buf, len, 0);
286
if (res < 0 || res!=len) {
287
system_error("send", res, errno);
288
}
289
} else {
290
res = md_write(fd, buf, len);
291
if (res < 0 || res!=len) {
292
system_error("write", res, errno);
293
}
294
}
295
}
296
297
static void
298
write_flush(void)
299
{
300
HPROF_ASSERT(gdata->fd >= 0);
301
if (gdata->write_buffer_index) {
302
system_write(gdata->fd, gdata->write_buffer, gdata->write_buffer_index,
303
gdata->socket);
304
gdata->write_buffer_index = 0;
305
}
306
}
307
308
static void
309
heap_flush(void)
310
{
311
HPROF_ASSERT(gdata->heap_fd >= 0);
312
if (gdata->heap_buffer_index) {
313
gdata->heap_write_count += (jlong)gdata->heap_buffer_index;
314
system_write(gdata->heap_fd, gdata->heap_buffer, gdata->heap_buffer_index,
315
JNI_FALSE);
316
gdata->heap_buffer_index = 0;
317
}
318
}
319
320
static void
321
write_raw(void *buf, int len)
322
{
323
HPROF_ASSERT(gdata->fd >= 0);
324
if (gdata->write_buffer_index + len > gdata->write_buffer_size) {
325
write_flush();
326
if (len > gdata->write_buffer_size) {
327
system_write(gdata->fd, buf, len, gdata->socket);
328
return;
329
}
330
}
331
(void)memcpy(gdata->write_buffer + gdata->write_buffer_index, buf, len);
332
gdata->write_buffer_index += len;
333
}
334
335
static void
336
write_u4(unsigned i)
337
{
338
i = md_htonl(i);
339
write_raw(&i, (jint)sizeof(unsigned));
340
}
341
342
static void
343
write_u8(jlong t)
344
{
345
write_u4((jint)jlong_high(t));
346
write_u4((jint)jlong_low(t));
347
}
348
349
static void
350
write_u2(unsigned short i)
351
{
352
i = md_htons(i);
353
write_raw(&i, (jint)sizeof(unsigned short));
354
}
355
356
static void
357
write_u1(unsigned char i)
358
{
359
write_raw(&i, (jint)sizeof(unsigned char));
360
}
361
362
static void
363
write_id(HprofId i)
364
{
365
write_u4(i);
366
}
367
368
static void
369
write_current_ticks(void)
370
{
371
write_u4((jint)(md_get_microsecs() - gdata->micro_sec_ticks));
372
}
373
374
static void
375
write_header(unsigned char type, jint length)
376
{
377
write_u1(type);
378
write_current_ticks();
379
write_u4(length);
380
}
381
382
static void
383
write_index_id(HprofId index)
384
{
385
write_id(index);
386
}
387
388
static IoNameIndex
389
write_name_first(char *name)
390
{
391
if ( name == NULL ) {
392
return 0;
393
}
394
if (gdata->output_format == 'b') {
395
IoNameIndex name_index;
396
jboolean new_one;
397
398
new_one = JNI_FALSE;
399
name_index = ioname_find_or_create(name, &new_one);
400
if ( new_one ) {
401
int len;
402
403
len = (int)strlen(name);
404
write_header(HPROF_UTF8, len + (jint)sizeof(HprofId));
405
write_index_id(name_index);
406
write_raw(name, len);
407
408
}
409
return name_index;
410
}
411
return 0;
412
}
413
414
static void
415
write_printf(char *fmt, ...)
416
{
417
char buf[1024];
418
va_list args;
419
va_start(args, fmt);
420
(void)md_vsnprintf(buf, sizeof(buf), fmt, args);
421
buf[sizeof(buf)-1] = 0;
422
write_raw(buf, (int)strlen(buf));
423
va_end(args);
424
}
425
426
static void
427
write_thread_serial_number(SerialNumber thread_serial_num, int with_comma)
428
{
429
if ( thread_serial_num != 0 ) {
430
CHECK_THREAD_SERIAL_NO(thread_serial_num);
431
if ( with_comma ) {
432
write_printf(" thread %d,", thread_serial_num);
433
} else {
434
write_printf(" thread %d", thread_serial_num);
435
}
436
} else {
437
if ( with_comma ) {
438
write_printf(" <unknown thread>,");
439
} else {
440
write_printf(" <unknown thread>");
441
}
442
}
443
}
444
445
static void
446
heap_raw(void *buf, int len)
447
{
448
HPROF_ASSERT(gdata->heap_fd >= 0);
449
if (gdata->heap_buffer_index + len > gdata->heap_buffer_size) {
450
heap_flush();
451
if (len > gdata->heap_buffer_size) {
452
gdata->heap_write_count += (jlong)len;
453
system_write(gdata->heap_fd, buf, len, JNI_FALSE);
454
return;
455
}
456
}
457
(void)memcpy(gdata->heap_buffer + gdata->heap_buffer_index, buf, len);
458
gdata->heap_buffer_index += len;
459
}
460
461
static void
462
heap_u4(unsigned i)
463
{
464
i = md_htonl(i);
465
heap_raw(&i, (jint)sizeof(unsigned));
466
}
467
468
static void
469
heap_u8(jlong i)
470
{
471
heap_u4((jint)jlong_high(i));
472
heap_u4((jint)jlong_low(i));
473
}
474
475
static void
476
heap_u2(unsigned short i)
477
{
478
i = md_htons(i);
479
heap_raw(&i, (jint)sizeof(unsigned short));
480
}
481
482
static void
483
heap_u1(unsigned char i)
484
{
485
heap_raw(&i, (jint)sizeof(unsigned char));
486
}
487
488
/* Write out the first byte of a heap tag */
489
static void
490
heap_tag(unsigned char tag)
491
{
492
jlong pos;
493
494
/* Current position in virtual heap dump file */
495
pos = gdata->heap_write_count + (jlong)gdata->heap_buffer_index;
496
if ( gdata->segmented == JNI_TRUE ) { /* 1.0.2 */
497
if ( pos >= gdata->maxHeapSegment ) {
498
/* Flush all bytes to the heap dump file */
499
heap_flush();
500
501
/* Send out segment (up to last tag written out) */
502
dump_heap_segment_and_reset(gdata->heap_last_tag_position);
503
504
/* Get new current position */
505
pos = gdata->heap_write_count + (jlong)gdata->heap_buffer_index;
506
}
507
}
508
/* Save position of this tag */
509
gdata->heap_last_tag_position = pos;
510
/* Write out this tag */
511
heap_u1(tag);
512
}
513
514
static void
515
heap_id(HprofId i)
516
{
517
heap_u4(i);
518
}
519
520
static void
521
heap_index_id(HprofId index)
522
{
523
heap_id(index);
524
}
525
526
static void
527
heap_name(char *name)
528
{
529
heap_index_id(get_name_index(name));
530
}
531
532
static void
533
heap_printf(char *fmt, ...)
534
{
535
char buf[1024];
536
va_list args;
537
va_start(args, fmt);
538
(void)md_vsnprintf(buf, sizeof(buf), fmt, args);
539
buf[sizeof(buf)-1] = 0;
540
heap_raw(buf, (int)strlen(buf));
541
va_end(args);
542
}
543
544
static void
545
heap_element(HprofType kind, jint size, jvalue value)
546
{
547
if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
548
HPROF_ASSERT(size==4);
549
heap_id((HprofId)value.i);
550
} else {
551
switch ( size ) {
552
case 8:
553
HPROF_ASSERT(size==8);
554
HPROF_ASSERT(kind==HPROF_LONG || kind==HPROF_DOUBLE);
555
heap_u8(value.j);
556
break;
557
case 4:
558
HPROF_ASSERT(size==4);
559
HPROF_ASSERT(kind==HPROF_INT || kind==HPROF_FLOAT);
560
heap_u4(value.i);
561
break;
562
case 2:
563
HPROF_ASSERT(size==2);
564
HPROF_ASSERT(kind==HPROF_SHORT || kind==HPROF_CHAR);
565
heap_u2(value.s);
566
break;
567
case 1:
568
HPROF_ASSERT(size==1);
569
HPROF_ASSERT(kind==HPROF_BOOLEAN || kind==HPROF_BYTE);
570
HPROF_ASSERT(kind==HPROF_BOOLEAN?(value.b==0 || value.b==1):1);
571
heap_u1(value.b);
572
break;
573
default:
574
HPROF_ASSERT(0);
575
break;
576
}
577
}
578
}
579
580
/* Dump out all elements of an array, objects in jvalues, prims packed */
581
static void
582
heap_elements(HprofType kind, jint num_elements, jint elem_size, void *elements)
583
{
584
int i;
585
jvalue val;
586
static jvalue empty_val;
587
588
if ( num_elements == 0 ) {
589
return;
590
}
591
592
switch ( kind ) {
593
case 0:
594
case HPROF_ARRAY_OBJECT:
595
case HPROF_NORMAL_OBJECT:
596
for (i = 0; i < num_elements; i++) {
597
val = empty_val;
598
val.i = ((ObjectIndex*)elements)[i];
599
heap_element(kind, elem_size, val);
600
}
601
break;
602
case HPROF_BYTE:
603
case HPROF_BOOLEAN:
604
HPROF_ASSERT(elem_size==1);
605
for (i = 0; i < num_elements; i++) {
606
val = empty_val;
607
val.b = ((jboolean*)elements)[i];
608
heap_element(kind, elem_size, val);
609
}
610
break;
611
case HPROF_CHAR:
612
case HPROF_SHORT:
613
HPROF_ASSERT(elem_size==2);
614
for (i = 0; i < num_elements; i++) {
615
val = empty_val;
616
val.s = ((jshort*)elements)[i];
617
heap_element(kind, elem_size, val);
618
}
619
break;
620
case HPROF_FLOAT:
621
case HPROF_INT:
622
HPROF_ASSERT(elem_size==4);
623
for (i = 0; i < num_elements; i++) {
624
val = empty_val;
625
val.i = ((jint*)elements)[i];
626
heap_element(kind, elem_size, val);
627
}
628
break;
629
case HPROF_DOUBLE:
630
case HPROF_LONG:
631
HPROF_ASSERT(elem_size==8);
632
for (i = 0; i < num_elements; i++) {
633
val = empty_val;
634
val.j = ((jlong*)elements)[i];
635
heap_element(kind, elem_size, val);
636
}
637
break;
638
}
639
}
640
641
/* ------------------------------------------------------------------ */
642
643
void
644
io_flush(void)
645
{
646
HPROF_ASSERT(gdata->header!=NULL);
647
write_flush();
648
}
649
650
void
651
io_setup(void)
652
{
653
gdata->write_buffer_size = FILE_IO_BUFFER_SIZE;
654
gdata->write_buffer = HPROF_MALLOC(gdata->write_buffer_size);
655
gdata->write_buffer_index = 0;
656
657
gdata->heap_write_count = (jlong)0;
658
gdata->heap_last_tag_position = (jlong)0;
659
gdata->heap_buffer_size = FILE_IO_BUFFER_SIZE;
660
gdata->heap_buffer = HPROF_MALLOC(gdata->heap_buffer_size);
661
gdata->heap_buffer_index = 0;
662
663
if ( gdata->logflags & LOG_CHECK_BINARY ) {
664
gdata->check_buffer_size = FILE_IO_BUFFER_SIZE;
665
gdata->check_buffer = HPROF_MALLOC(gdata->check_buffer_size);
666
gdata->check_buffer_index = 0;
667
}
668
669
ioname_init();
670
}
671
672
void
673
io_cleanup(void)
674
{
675
if ( gdata->write_buffer != NULL ) {
676
HPROF_FREE(gdata->write_buffer);
677
}
678
gdata->write_buffer_size = 0;
679
gdata->write_buffer = NULL;
680
gdata->write_buffer_index = 0;
681
682
if ( gdata->heap_buffer != NULL ) {
683
HPROF_FREE(gdata->heap_buffer);
684
}
685
gdata->heap_write_count = (jlong)0;
686
gdata->heap_last_tag_position = (jlong)0;
687
gdata->heap_buffer_size = 0;
688
gdata->heap_buffer = NULL;
689
gdata->heap_buffer_index = 0;
690
691
if ( gdata->logflags & LOG_CHECK_BINARY ) {
692
if ( gdata->check_buffer != NULL ) {
693
HPROF_FREE(gdata->check_buffer);
694
}
695
gdata->check_buffer_size = 0;
696
gdata->check_buffer = NULL;
697
gdata->check_buffer_index = 0;
698
}
699
700
ioname_cleanup();
701
}
702
703
void
704
io_write_file_header(void)
705
{
706
HPROF_ASSERT(gdata->header!=NULL);
707
if (gdata->output_format == 'b') {
708
jint settings;
709
jlong t;
710
711
settings = 0;
712
if (gdata->heap_dump || gdata->alloc_sites) {
713
settings |= 1;
714
}
715
if (gdata->cpu_sampling) {
716
settings |= 2;
717
}
718
t = md_get_timemillis();
719
720
write_raw(gdata->header, (int)strlen(gdata->header) + 1);
721
write_u4((jint)sizeof(HprofId));
722
write_u8(t);
723
724
write_header(HPROF_CONTROL_SETTINGS, 4 + 2);
725
write_u4(settings);
726
write_u2((unsigned short)gdata->max_trace_depth);
727
728
} else if ((!gdata->cpu_timing) || (!gdata->old_timing_format)) {
729
/* We don't want the prelude file for the old prof output format */
730
time_t t;
731
char prelude_file[FILENAME_MAX];
732
int prelude_fd;
733
int nbytes;
734
735
t = time(0);
736
737
md_get_prelude_path(prelude_file, sizeof(prelude_file), PRELUDE_FILE);
738
739
prelude_fd = md_open(prelude_file);
740
if (prelude_fd < 0) {
741
char buf[FILENAME_MAX+80];
742
743
(void)md_snprintf(buf, sizeof(buf), "Can't open %s", prelude_file);
744
buf[sizeof(buf)-1] = 0;
745
HPROF_ERROR(JNI_TRUE, buf);
746
}
747
748
write_printf("%s, created %s\n", gdata->header, ctime(&t));
749
750
do {
751
char buf[1024]; /* File is small, small buffer ok here */
752
753
nbytes = md_read(prelude_fd, buf, sizeof(buf));
754
if ( nbytes < 0 ) {
755
system_error("read", nbytes, errno);
756
break;
757
}
758
if (nbytes == 0) {
759
break;
760
}
761
write_raw(buf, nbytes);
762
} while ( nbytes > 0 );
763
764
md_close(prelude_fd);
765
766
write_printf("\n--------\n\n");
767
768
write_flush();
769
}
770
}
771
772
void
773
io_write_file_footer(void)
774
{
775
HPROF_ASSERT(gdata->header!=NULL);
776
}
777
778
void
779
io_write_class_load(SerialNumber class_serial_num, ObjectIndex index,
780
SerialNumber trace_serial_num, char *sig)
781
{
782
CHECK_CLASS_SERIAL_NO(class_serial_num);
783
CHECK_TRACE_SERIAL_NO(trace_serial_num);
784
if (gdata->output_format == 'b') {
785
IoNameIndex name_index;
786
char *class_name;
787
788
class_name = signature_to_name(sig);
789
name_index = write_name_first(class_name);
790
write_header(HPROF_LOAD_CLASS, (2 * (jint)sizeof(HprofId)) + (4 * 2));
791
write_u4(class_serial_num);
792
write_index_id(index);
793
write_u4(trace_serial_num);
794
write_index_id(name_index);
795
HPROF_FREE(class_name);
796
}
797
}
798
799
void
800
io_write_class_unload(SerialNumber class_serial_num, ObjectIndex index)
801
{
802
CHECK_CLASS_SERIAL_NO(class_serial_num);
803
if (gdata->output_format == 'b') {
804
write_header(HPROF_UNLOAD_CLASS, 4);
805
write_u4(class_serial_num);
806
}
807
}
808
809
void
810
io_write_sites_header(const char * comment_str, jint flags, double cutoff,
811
jint total_live_bytes, jint total_live_instances,
812
jlong total_alloced_bytes, jlong total_alloced_instances,
813
jint count)
814
{
815
if ( gdata->output_format == 'b') {
816
write_header(HPROF_ALLOC_SITES, 2 + (8 * 4) + (count * (4 * 6 + 1)));
817
write_u2((unsigned short)flags);
818
write_u4(*(int *)(&cutoff));
819
write_u4(total_live_bytes);
820
write_u4(total_live_instances);
821
write_u8(total_alloced_bytes);
822
write_u8(total_alloced_instances);
823
write_u4(count);
824
} else {
825
time_t t;
826
827
t = time(0);
828
write_printf("SITES BEGIN (ordered by %s) %s", comment_str, ctime(&t));
829
write_printf(
830
" percent live alloc'ed stack class\n");
831
write_printf(
832
" rank self accum bytes objs bytes objs trace name\n");
833
}
834
}
835
836
void
837
io_write_sites_elem(jint index, double ratio, double accum_percent,
838
char *sig, SerialNumber class_serial_num,
839
SerialNumber trace_serial_num, jint n_live_bytes,
840
jint n_live_instances, jint n_alloced_bytes,
841
jint n_alloced_instances)
842
{
843
CHECK_CLASS_SERIAL_NO(class_serial_num);
844
CHECK_TRACE_SERIAL_NO(trace_serial_num);
845
if ( gdata->output_format == 'b') {
846
HprofType kind;
847
jint size;
848
849
type_array(sig, &kind, &size);
850
write_u1(kind);
851
write_u4(class_serial_num);
852
write_u4(trace_serial_num);
853
write_u4(n_live_bytes);
854
write_u4(n_live_instances);
855
write_u4(n_alloced_bytes);
856
write_u4(n_alloced_instances);
857
} else {
858
char *class_name;
859
860
class_name = signature_to_name(sig);
861
write_printf("%5u %5.2f%% %5.2f%% %9u %4u %9u %5u %5u %s\n",
862
index,
863
ratio * 100.0,
864
accum_percent * 100.0,
865
n_live_bytes,
866
n_live_instances,
867
n_alloced_bytes,
868
n_alloced_instances,
869
trace_serial_num,
870
class_name);
871
HPROF_FREE(class_name);
872
}
873
}
874
875
void
876
io_write_sites_footer(void)
877
{
878
if (gdata->output_format == 'b') {
879
not_implemented();
880
} else {
881
write_printf("SITES END\n");
882
}
883
}
884
885
void
886
io_write_thread_start(SerialNumber thread_serial_num,
887
ObjectIndex thread_obj_id,
888
SerialNumber trace_serial_num, char *thread_name,
889
char *thread_group_name, char *thread_parent_name)
890
{
891
CHECK_THREAD_SERIAL_NO(thread_serial_num);
892
CHECK_TRACE_SERIAL_NO(trace_serial_num);
893
if (gdata->output_format == 'b') {
894
IoNameIndex tname_index;
895
IoNameIndex gname_index;
896
IoNameIndex pname_index;
897
898
tname_index = write_name_first(thread_name);
899
gname_index = write_name_first(thread_group_name);
900
pname_index = write_name_first(thread_parent_name);
901
write_header(HPROF_START_THREAD, ((jint)sizeof(HprofId) * 4) + (4 * 2));
902
write_u4(thread_serial_num);
903
write_index_id(thread_obj_id);
904
write_u4(trace_serial_num);
905
write_index_id(tname_index);
906
write_index_id(gname_index);
907
write_index_id(pname_index);
908
909
} else if ( (!gdata->cpu_timing) || (!gdata->old_timing_format)) {
910
/* We don't want thread info for the old prof output format */
911
write_printf("THREAD START "
912
"(obj=%x, id = %d, name=\"%s\", group=\"%s\")\n",
913
thread_obj_id, thread_serial_num,
914
(thread_name==NULL?"":thread_name),
915
(thread_group_name==NULL?"":thread_group_name));
916
}
917
}
918
919
void
920
io_write_thread_end(SerialNumber thread_serial_num)
921
{
922
CHECK_THREAD_SERIAL_NO(thread_serial_num);
923
if (gdata->output_format == 'b') {
924
write_header(HPROF_END_THREAD, 4);
925
write_u4(thread_serial_num);
926
927
} else if ( (!gdata->cpu_timing) || (!gdata->old_timing_format)) {
928
/* we don't want thread info for the old prof output format */
929
write_printf("THREAD END (id = %d)\n", thread_serial_num);
930
}
931
}
932
933
void
934
io_write_frame(FrameIndex index, SerialNumber frame_serial_num,
935
char *mname, char *msig, char *sname,
936
SerialNumber class_serial_num, jint lineno)
937
{
938
CHECK_CLASS_SERIAL_NO(class_serial_num);
939
if (gdata->output_format == 'b') {
940
IoNameIndex mname_index;
941
IoNameIndex msig_index;
942
IoNameIndex sname_index;
943
944
mname_index = write_name_first(mname);
945
msig_index = write_name_first(msig);
946
sname_index = write_name_first(sname);
947
948
write_header(HPROF_FRAME, ((jint)sizeof(HprofId) * 4) + (4 * 2));
949
write_index_id(index);
950
write_index_id(mname_index);
951
write_index_id(msig_index);
952
write_index_id(sname_index);
953
write_u4(class_serial_num);
954
write_u4(lineno);
955
}
956
}
957
958
void
959
io_write_trace_header(SerialNumber trace_serial_num,
960
SerialNumber thread_serial_num, jint n_frames, char *phase_str)
961
{
962
CHECK_TRACE_SERIAL_NO(trace_serial_num);
963
if (gdata->output_format == 'b') {
964
write_header(HPROF_TRACE, ((jint)sizeof(HprofId) * n_frames) + (4 * 3));
965
write_u4(trace_serial_num);
966
write_u4(thread_serial_num);
967
write_u4(n_frames);
968
} else {
969
write_printf("TRACE %u:", trace_serial_num);
970
if (thread_serial_num) {
971
write_printf(" (thread=%d)", thread_serial_num);
972
}
973
if ( phase_str != NULL ) {
974
write_printf(" (from %s phase of JVM)", phase_str);
975
}
976
write_printf("\n");
977
if (n_frames == 0) {
978
write_printf("\t<empty>\n");
979
}
980
}
981
}
982
983
void
984
io_write_trace_elem(SerialNumber trace_serial_num, FrameIndex frame_index,
985
SerialNumber frame_serial_num,
986
char *csig, char *mname, char *sname, jint lineno)
987
{
988
if (gdata->output_format == 'b') {
989
write_index_id(frame_index);
990
} else {
991
char *class_name;
992
char linebuf[32];
993
994
if (lineno == -2) {
995
(void)md_snprintf(linebuf, sizeof(linebuf), "Compiled method");
996
} else if (lineno == -3) {
997
(void)md_snprintf(linebuf, sizeof(linebuf), "Native method");
998
} else if (lineno == -1) {
999
(void)md_snprintf(linebuf, sizeof(linebuf), "Unknown line");
1000
} else {
1001
(void)md_snprintf(linebuf, sizeof(linebuf), "%d", lineno);
1002
}
1003
linebuf[sizeof(linebuf)-1] = 0;
1004
class_name = signature_to_name(csig);
1005
if ( mname == NULL ) {
1006
mname = "<Unknown Method>";
1007
}
1008
if ( sname == NULL ) {
1009
sname = "<Unknown Source>";
1010
}
1011
write_printf("\t%s.%s(%s:%s)\n", class_name, mname, sname, linebuf);
1012
HPROF_FREE(class_name);
1013
}
1014
}
1015
1016
void
1017
io_write_trace_footer(SerialNumber trace_serial_num,
1018
SerialNumber thread_serial_num, jint n_frames)
1019
{
1020
}
1021
1022
#define CPU_SAMPLES_RECORD_NAME ("CPU SAMPLES")
1023
#define CPU_TIMES_RECORD_NAME ("CPU TIME (ms)")
1024
1025
void
1026
io_write_cpu_samples_header(jlong total_cost, jint n_items)
1027
{
1028
1029
if (gdata->output_format == 'b') {
1030
write_header(HPROF_CPU_SAMPLES, (n_items * (4 * 2)) + (4 * 2));
1031
write_u4((jint)total_cost);
1032
write_u4(n_items);
1033
} else {
1034
time_t t;
1035
char *record_name;
1036
1037
if ( gdata->cpu_sampling ) {
1038
record_name = CPU_SAMPLES_RECORD_NAME;
1039
} else {
1040
record_name = CPU_TIMES_RECORD_NAME;
1041
}
1042
t = time(0);
1043
write_printf("%s BEGIN (total = %d) %s", record_name,
1044
/*jlong*/(int)total_cost, ctime(&t));
1045
if ( n_items > 0 ) {
1046
write_printf("rank self accum count trace method\n");
1047
}
1048
}
1049
}
1050
1051
void
1052
io_write_cpu_samples_elem(jint index, double percent, double accum,
1053
jint num_hits, jlong cost, SerialNumber trace_serial_num,
1054
jint n_frames, char *csig, char *mname)
1055
{
1056
CHECK_TRACE_SERIAL_NO(trace_serial_num);
1057
if (gdata->output_format == 'b') {
1058
write_u4((jint)cost);
1059
write_u4(trace_serial_num);
1060
} else {
1061
write_printf("%4u %5.2f%% %5.2f%% %7u %5u",
1062
index, percent, accum, num_hits,
1063
trace_serial_num);
1064
if (n_frames > 0) {
1065
char * class_name;
1066
1067
class_name = signature_to_name(csig);
1068
write_printf(" %s.%s\n", class_name, mname);
1069
HPROF_FREE(class_name);
1070
} else {
1071
write_printf(" <empty trace>\n");
1072
}
1073
}
1074
}
1075
1076
void
1077
io_write_cpu_samples_footer(void)
1078
{
1079
if (gdata->output_format == 'b') {
1080
not_implemented();
1081
} else {
1082
char *record_name;
1083
1084
if ( gdata->cpu_sampling ) {
1085
record_name = CPU_SAMPLES_RECORD_NAME;
1086
} else {
1087
record_name = CPU_TIMES_RECORD_NAME;
1088
}
1089
write_printf("%s END\n", record_name);
1090
}
1091
}
1092
1093
void
1094
io_write_heap_summary(jlong total_live_bytes, jlong total_live_instances,
1095
jlong total_alloced_bytes, jlong total_alloced_instances)
1096
{
1097
if (gdata->output_format == 'b') {
1098
write_header(HPROF_HEAP_SUMMARY, 4 * 6);
1099
write_u4((jint)total_live_bytes);
1100
write_u4((jint)total_live_instances);
1101
write_u8(total_alloced_bytes);
1102
write_u8(total_alloced_instances);
1103
}
1104
}
1105
1106
void
1107
io_write_oldprof_header(void)
1108
{
1109
if ( gdata->old_timing_format ) {
1110
write_printf("count callee caller time\n");
1111
}
1112
}
1113
1114
void
1115
io_write_oldprof_elem(jint num_hits, jint num_frames, char *csig_callee,
1116
char *mname_callee, char *msig_callee, char *csig_caller,
1117
char *mname_caller, char *msig_caller, jlong cost)
1118
{
1119
if ( gdata->old_timing_format ) {
1120
char * class_name_callee;
1121
char * class_name_caller;
1122
1123
class_name_callee = signature_to_name(csig_callee);
1124
class_name_caller = signature_to_name(csig_caller);
1125
write_printf("%d ", num_hits);
1126
if (num_frames >= 1) {
1127
write_printf("%s.%s%s ", class_name_callee,
1128
mname_callee, msig_callee);
1129
} else {
1130
write_printf("%s ", "<unknown callee>");
1131
}
1132
if (num_frames > 1) {
1133
write_printf("%s.%s%s ", class_name_caller,
1134
mname_caller, msig_caller);
1135
} else {
1136
write_printf("%s ", "<unknown caller>");
1137
}
1138
write_printf("%d\n", (int)cost);
1139
HPROF_FREE(class_name_callee);
1140
HPROF_FREE(class_name_caller);
1141
}
1142
}
1143
1144
void
1145
io_write_oldprof_footer(void)
1146
{
1147
}
1148
1149
void
1150
io_write_monitor_header(jlong total_time)
1151
{
1152
if (gdata->output_format == 'b') {
1153
not_implemented();
1154
} else {
1155
time_t t = time(0);
1156
1157
t = time(0);
1158
write_printf("MONITOR TIME BEGIN (total = %u ms) %s",
1159
(int)total_time, ctime(&t));
1160
if (total_time > 0) {
1161
write_printf("rank self accum count trace monitor\n");
1162
}
1163
}
1164
}
1165
1166
void
1167
io_write_monitor_elem(jint index, double percent, double accum,
1168
jint num_hits, SerialNumber trace_serial_num, char *sig)
1169
{
1170
CHECK_TRACE_SERIAL_NO(trace_serial_num);
1171
if (gdata->output_format == 'b') {
1172
not_implemented();
1173
} else {
1174
char *class_name;
1175
1176
class_name = signature_to_name(sig);
1177
write_printf("%4u %5.2f%% %5.2f%% %7u %5u %s (Java)\n",
1178
index, percent, accum, num_hits,
1179
trace_serial_num, class_name);
1180
HPROF_FREE(class_name);
1181
}
1182
}
1183
1184
void
1185
io_write_monitor_footer(void)
1186
{
1187
if (gdata->output_format == 'b') {
1188
not_implemented();
1189
} else {
1190
write_printf("MONITOR TIME END\n");
1191
}
1192
}
1193
1194
void
1195
io_write_monitor_sleep(jlong timeout, SerialNumber thread_serial_num)
1196
{
1197
if (gdata->output_format == 'b') {
1198
not_implemented();
1199
} else {
1200
if ( thread_serial_num == 0 ) {
1201
write_printf("SLEEP: timeout=%d, <unknown thread>\n",
1202
(int)timeout);
1203
} else {
1204
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1205
write_printf("SLEEP: timeout=%d, thread %d\n",
1206
(int)timeout, thread_serial_num);
1207
}
1208
}
1209
}
1210
1211
void
1212
io_write_monitor_wait(char *sig, jlong timeout,
1213
SerialNumber thread_serial_num)
1214
{
1215
if (gdata->output_format == 'b') {
1216
not_implemented();
1217
} else {
1218
if ( thread_serial_num == 0 ) {
1219
write_printf("WAIT: MONITOR %s, timeout=%d, <unknown thread>\n",
1220
sig, (int)timeout);
1221
} else {
1222
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1223
write_printf("WAIT: MONITOR %s, timeout=%d, thread %d\n",
1224
sig, (int)timeout, thread_serial_num);
1225
}
1226
}
1227
}
1228
1229
void
1230
io_write_monitor_waited(char *sig, jlong time_waited,
1231
SerialNumber thread_serial_num)
1232
{
1233
if (gdata->output_format == 'b') {
1234
not_implemented();
1235
} else {
1236
if ( thread_serial_num == 0 ) {
1237
write_printf("WAITED: MONITOR %s, time_waited=%d, <unknown thread>\n",
1238
sig, (int)time_waited);
1239
} else {
1240
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1241
write_printf("WAITED: MONITOR %s, time_waited=%d, thread %d\n",
1242
sig, (int)time_waited, thread_serial_num);
1243
}
1244
}
1245
}
1246
1247
void
1248
io_write_monitor_exit(char *sig, SerialNumber thread_serial_num)
1249
{
1250
if (gdata->output_format == 'b') {
1251
not_implemented();
1252
} else {
1253
if ( thread_serial_num == 0 ) {
1254
write_printf("EXIT: MONITOR %s, <unknown thread>\n", sig);
1255
} else {
1256
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1257
write_printf("EXIT: MONITOR %s, thread %d\n",
1258
sig, thread_serial_num);
1259
}
1260
}
1261
}
1262
1263
void
1264
io_write_monitor_dump_header(void)
1265
{
1266
if (gdata->output_format == 'b') {
1267
not_implemented();
1268
} else {
1269
write_printf("MONITOR DUMP BEGIN\n");
1270
}
1271
}
1272
1273
void
1274
io_write_monitor_dump_thread_state(SerialNumber thread_serial_num,
1275
SerialNumber trace_serial_num,
1276
jint threadState)
1277
{
1278
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1279
CHECK_TRACE_SERIAL_NO(trace_serial_num);
1280
if (gdata->output_format == 'b') {
1281
not_implemented();
1282
} else {
1283
char tstate[20];
1284
1285
tstate[0] = 0;
1286
1287
if (threadState & JVMTI_THREAD_STATE_SUSPENDED) {
1288
(void)strcat(tstate,"S|");
1289
}
1290
if (threadState & JVMTI_THREAD_STATE_INTERRUPTED) {
1291
(void)strcat(tstate,"intr|");
1292
}
1293
if (threadState & JVMTI_THREAD_STATE_IN_NATIVE) {
1294
(void)strcat(tstate,"native|");
1295
}
1296
if ( ! ( threadState & JVMTI_THREAD_STATE_ALIVE ) ) {
1297
if ( threadState & JVMTI_THREAD_STATE_TERMINATED ) {
1298
(void)strcat(tstate,"ZO");
1299
} else {
1300
(void)strcat(tstate,"NS");
1301
}
1302
} else {
1303
if ( threadState & JVMTI_THREAD_STATE_SLEEPING ) {
1304
(void)strcat(tstate,"SL");
1305
} else if ( threadState & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER ) {
1306
(void)strcat(tstate,"MW");
1307
} else if ( threadState & JVMTI_THREAD_STATE_WAITING ) {
1308
(void)strcat(tstate,"CW");
1309
} else if ( threadState & JVMTI_THREAD_STATE_RUNNABLE ) {
1310
(void)strcat(tstate,"R");
1311
} else {
1312
(void)strcat(tstate,"UN");
1313
}
1314
}
1315
write_printf(" THREAD %d, trace %d, status: %s\n",
1316
thread_serial_num, trace_serial_num, tstate);
1317
}
1318
}
1319
1320
void
1321
io_write_monitor_dump_state(char *sig, SerialNumber thread_serial_num,
1322
jint entry_count,
1323
SerialNumber *waiters, jint waiter_count,
1324
SerialNumber *notify_waiters, jint notify_waiter_count)
1325
{
1326
if (gdata->output_format == 'b') {
1327
not_implemented();
1328
} else {
1329
int i;
1330
1331
if ( thread_serial_num != 0 ) {
1332
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1333
write_printf(" MONITOR %s\n", sig);
1334
write_printf("\towner: thread %d, entry count: %d\n",
1335
thread_serial_num, entry_count);
1336
} else {
1337
write_printf(" MONITOR %s unowned\n", sig);
1338
}
1339
write_printf("\twaiting to enter:");
1340
for (i = 0; i < waiter_count; i++) {
1341
write_thread_serial_number(waiters[i],
1342
(i != (waiter_count-1)));
1343
}
1344
write_printf("\n");
1345
write_printf("\twaiting to be notified:");
1346
for (i = 0; i < notify_waiter_count; i++) {
1347
write_thread_serial_number(notify_waiters[i],
1348
(i != (notify_waiter_count-1)));
1349
}
1350
write_printf("\n");
1351
}
1352
}
1353
1354
void
1355
io_write_monitor_dump_footer(void)
1356
{
1357
if (gdata->output_format == 'b') {
1358
not_implemented();
1359
} else {
1360
write_printf("MONITOR DUMP END\n");
1361
}
1362
}
1363
1364
/* ----------------------------------------------------------------- */
1365
/* These functions write to a separate file */
1366
1367
void
1368
io_heap_header(jlong total_live_instances, jlong total_live_bytes)
1369
{
1370
if (gdata->output_format != 'b') {
1371
time_t t;
1372
1373
t = time(0);
1374
heap_printf("HEAP DUMP BEGIN (%u objects, %u bytes) %s",
1375
/*jlong*/(int)total_live_instances,
1376
/*jlong*/(int)total_live_bytes, ctime(&t));
1377
}
1378
}
1379
1380
void
1381
io_heap_root_thread_object(ObjectIndex thread_obj_id,
1382
SerialNumber thread_serial_num, SerialNumber trace_serial_num)
1383
{
1384
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1385
CHECK_TRACE_SERIAL_NO(trace_serial_num);
1386
if (gdata->output_format == 'b') {
1387
heap_tag(HPROF_GC_ROOT_THREAD_OBJ);
1388
heap_id(thread_obj_id);
1389
heap_u4(thread_serial_num);
1390
heap_u4(trace_serial_num);
1391
} else {
1392
heap_printf("ROOT %x (kind=<thread>, id=%u, trace=%u)\n",
1393
thread_obj_id, thread_serial_num, trace_serial_num);
1394
}
1395
}
1396
1397
void
1398
io_heap_root_unknown(ObjectIndex obj_id)
1399
{
1400
if (gdata->output_format == 'b') {
1401
heap_tag(HPROF_GC_ROOT_UNKNOWN);
1402
heap_id(obj_id);
1403
} else {
1404
heap_printf("ROOT %x (kind=<unknown>)\n", obj_id);
1405
}
1406
}
1407
1408
void
1409
io_heap_root_jni_global(ObjectIndex obj_id, SerialNumber gref_serial_num,
1410
SerialNumber trace_serial_num)
1411
{
1412
CHECK_TRACE_SERIAL_NO(trace_serial_num);
1413
if (gdata->output_format == 'b') {
1414
heap_tag(HPROF_GC_ROOT_JNI_GLOBAL);
1415
heap_id(obj_id);
1416
heap_id(gref_serial_num);
1417
} else {
1418
heap_printf("ROOT %x (kind=<JNI global ref>, "
1419
"id=%x, trace=%u)\n",
1420
obj_id, gref_serial_num, trace_serial_num);
1421
}
1422
}
1423
1424
void
1425
io_heap_root_jni_local(ObjectIndex obj_id, SerialNumber thread_serial_num,
1426
jint frame_depth)
1427
{
1428
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1429
if (gdata->output_format == 'b') {
1430
heap_tag(HPROF_GC_ROOT_JNI_LOCAL);
1431
heap_id(obj_id);
1432
heap_u4(thread_serial_num);
1433
heap_u4(frame_depth);
1434
} else {
1435
heap_printf("ROOT %x (kind=<JNI local ref>, "
1436
"thread=%u, frame=%d)\n",
1437
obj_id, thread_serial_num, frame_depth);
1438
}
1439
}
1440
1441
void
1442
io_heap_root_system_class(ObjectIndex obj_id, char *sig, SerialNumber class_serial_num)
1443
{
1444
if (gdata->output_format == 'b') {
1445
heap_tag(HPROF_GC_ROOT_STICKY_CLASS);
1446
heap_id(obj_id);
1447
} else {
1448
char *class_name;
1449
1450
class_name = signature_to_name(sig);
1451
heap_printf("ROOT %x (kind=<system class>, name=%s)\n",
1452
obj_id, class_name);
1453
HPROF_FREE(class_name);
1454
}
1455
}
1456
1457
void
1458
io_heap_root_monitor(ObjectIndex obj_id)
1459
{
1460
if (gdata->output_format == 'b') {
1461
heap_tag(HPROF_GC_ROOT_MONITOR_USED);
1462
heap_id(obj_id);
1463
} else {
1464
heap_printf("ROOT %x (kind=<busy monitor>)\n", obj_id);
1465
}
1466
}
1467
1468
void
1469
io_heap_root_thread(ObjectIndex obj_id, SerialNumber thread_serial_num)
1470
{
1471
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1472
if (gdata->output_format == 'b') {
1473
heap_tag(HPROF_GC_ROOT_THREAD_BLOCK);
1474
heap_id(obj_id);
1475
heap_u4(thread_serial_num);
1476
} else {
1477
heap_printf("ROOT %x (kind=<thread block>, thread=%u)\n",
1478
obj_id, thread_serial_num);
1479
}
1480
}
1481
1482
void
1483
io_heap_root_java_frame(ObjectIndex obj_id, SerialNumber thread_serial_num,
1484
jint frame_depth)
1485
{
1486
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1487
if (gdata->output_format == 'b') {
1488
heap_tag(HPROF_GC_ROOT_JAVA_FRAME);
1489
heap_id(obj_id);
1490
heap_u4(thread_serial_num);
1491
heap_u4(frame_depth);
1492
} else {
1493
heap_printf("ROOT %x (kind=<Java stack>, "
1494
"thread=%u, frame=%d)\n",
1495
obj_id, thread_serial_num, frame_depth);
1496
}
1497
}
1498
1499
void
1500
io_heap_root_native_stack(ObjectIndex obj_id, SerialNumber thread_serial_num)
1501
{
1502
CHECK_THREAD_SERIAL_NO(thread_serial_num);
1503
if (gdata->output_format == 'b') {
1504
heap_tag(HPROF_GC_ROOT_NATIVE_STACK);
1505
heap_id(obj_id);
1506
heap_u4(thread_serial_num);
1507
} else {
1508
heap_printf("ROOT %x (kind=<native stack>, thread=%u)\n",
1509
obj_id, thread_serial_num);
1510
}
1511
}
1512
1513
static jboolean
1514
is_static_field(jint modifiers)
1515
{
1516
if ( modifiers & JVM_ACC_STATIC ) {
1517
return JNI_TRUE;
1518
}
1519
return JNI_FALSE;
1520
}
1521
1522
static jboolean
1523
is_inst_field(jint modifiers)
1524
{
1525
if ( modifiers & JVM_ACC_STATIC ) {
1526
return JNI_FALSE;
1527
}
1528
return JNI_TRUE;
1529
}
1530
1531
void
1532
io_heap_class_dump(ClassIndex cnum, char *sig, ObjectIndex class_id,
1533
SerialNumber trace_serial_num,
1534
ObjectIndex super_id, ObjectIndex loader_id,
1535
ObjectIndex signers_id, ObjectIndex domain_id,
1536
jint size,
1537
jint n_cpool, ConstantPoolValue *cpool,
1538
jint n_fields, FieldInfo *fields, jvalue *fvalues)
1539
{
1540
CHECK_TRACE_SERIAL_NO(trace_serial_num);
1541
if (gdata->output_format == 'b') {
1542
int i;
1543
jint n_static_fields;
1544
jint n_inst_fields;
1545
jint inst_size;
1546
jint saved_inst_size;
1547
1548
n_static_fields = 0;
1549
n_inst_fields = 0;
1550
inst_size = 0;
1551
1552
/* These do NOT go into the heap output */
1553
for ( i = 0 ; i < n_fields ; i++ ) {
1554
if ( fields[i].cnum == cnum &&
1555
is_static_field(fields[i].modifiers) ) {
1556
char *field_name;
1557
1558
field_name = string_get(fields[i].name_index);
1559
(void)write_name_first(field_name);
1560
n_static_fields++;
1561
}
1562
if ( is_inst_field(fields[i].modifiers) ) {
1563
inst_size += size_from_field_info(fields[i].primSize);
1564
if ( fields[i].cnum == cnum ) {
1565
char *field_name;
1566
1567
field_name = string_get(fields[i].name_index);
1568
(void)write_name_first(field_name);
1569
n_inst_fields++;
1570
}
1571
}
1572
}
1573
1574
/* Verify that the instance size we have calculated as we went
1575
* through the fields, matches what is saved away with this
1576
* class.
1577
*/
1578
if ( size >= 0 ) {
1579
saved_inst_size = class_get_inst_size(cnum);
1580
if ( saved_inst_size == -1 ) {
1581
class_set_inst_size(cnum, inst_size);
1582
} else if ( saved_inst_size != inst_size ) {
1583
HPROF_ERROR(JNI_TRUE, "Mis-match on instance size in class dump");
1584
}
1585
}
1586
1587
heap_tag(HPROF_GC_CLASS_DUMP);
1588
heap_id(class_id);
1589
heap_u4(trace_serial_num);
1590
heap_id(super_id);
1591
heap_id(loader_id);
1592
heap_id(signers_id);
1593
heap_id(domain_id);
1594
heap_id(0);
1595
heap_id(0);
1596
heap_u4(inst_size); /* Must match inst_size in instance dump */
1597
1598
heap_u2((unsigned short)n_cpool);
1599
for ( i = 0 ; i < n_cpool ; i++ ) {
1600
HprofType kind;
1601
jint size;
1602
1603
type_from_signature(string_get(cpool[i].sig_index),
1604
&kind, &size);
1605
heap_u2((unsigned short)(cpool[i].constant_pool_index));
1606
heap_u1(kind);
1607
HPROF_ASSERT(!HPROF_TYPE_IS_PRIMITIVE(kind));
1608
heap_element(kind, size, cpool[i].value);
1609
}
1610
1611
heap_u2((unsigned short)n_static_fields);
1612
for ( i = 0 ; i < n_fields ; i++ ) {
1613
if ( fields[i].cnum == cnum &&
1614
is_static_field(fields[i].modifiers) ) {
1615
char *field_name;
1616
HprofType kind;
1617
jint size;
1618
1619
type_from_signature(string_get(fields[i].sig_index),
1620
&kind, &size);
1621
field_name = string_get(fields[i].name_index);
1622
heap_name(field_name);
1623
heap_u1(kind);
1624
heap_element(kind, size, fvalues[i]);
1625
}
1626
}
1627
1628
heap_u2((unsigned short)n_inst_fields); /* Does not include super class */
1629
for ( i = 0 ; i < n_fields ; i++ ) {
1630
if ( fields[i].cnum == cnum &&
1631
is_inst_field(fields[i].modifiers) ) {
1632
HprofType kind;
1633
jint size;
1634
char *field_name;
1635
1636
field_name = string_get(fields[i].name_index);
1637
type_from_signature(string_get(fields[i].sig_index),
1638
&kind, &size);
1639
heap_name(field_name);
1640
heap_u1(kind);
1641
}
1642
}
1643
} else {
1644
char * class_name;
1645
int i;
1646
1647
class_name = signature_to_name(sig);
1648
heap_printf("CLS %x (name=%s, trace=%u)\n",
1649
class_id, class_name, trace_serial_num);
1650
HPROF_FREE(class_name);
1651
if (super_id) {
1652
heap_printf("\tsuper\t\t%x\n", super_id);
1653
}
1654
if (loader_id) {
1655
heap_printf("\tloader\t\t%x\n", loader_id);
1656
}
1657
if (signers_id) {
1658
heap_printf("\tsigners\t\t%x\n", signers_id);
1659
}
1660
if (domain_id) {
1661
heap_printf("\tdomain\t\t%x\n", domain_id);
1662
}
1663
for ( i = 0 ; i < n_fields ; i++ ) {
1664
if ( fields[i].cnum == cnum &&
1665
is_static_field(fields[i].modifiers) ) {
1666
HprofType kind;
1667
jint size;
1668
1669
type_from_signature(string_get(fields[i].sig_index),
1670
&kind, &size);
1671
if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
1672
if (fvalues[i].i != 0 ) {
1673
char *field_name;
1674
1675
field_name = string_get(fields[i].name_index);
1676
heap_printf("\tstatic %s\t%x\n", field_name,
1677
fvalues[i].i);
1678
}
1679
}
1680
}
1681
}
1682
for ( i = 0 ; i < n_cpool ; i++ ) {
1683
HprofType kind;
1684
jint size;
1685
1686
type_from_signature(string_get(cpool[i].sig_index), &kind, &size);
1687
if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
1688
if (cpool[i].value.i != 0 ) {
1689
heap_printf("\tconstant pool entry %d\t%x\n",
1690
cpool[i].constant_pool_index, cpool[i].value.i);
1691
}
1692
}
1693
}
1694
}
1695
}
1696
1697
/* Dump the instance fields in the right order. */
1698
static int
1699
dump_instance_fields(ClassIndex cnum,
1700
FieldInfo *fields, jvalue *fvalues, jint n_fields)
1701
{
1702
ClassIndex super_cnum;
1703
int i;
1704
int nbytes;
1705
1706
HPROF_ASSERT(cnum!=0);
1707
1708
nbytes = 0;
1709
for (i = 0; i < n_fields; i++) {
1710
if ( fields[i].cnum == cnum &&
1711
is_inst_field(fields[i].modifiers) ) {
1712
HprofType kind;
1713
int size;
1714
1715
type_from_signature(string_get(fields[i].sig_index),
1716
&kind, &size);
1717
heap_element(kind, size, fvalues[i]);
1718
nbytes += size;
1719
}
1720
}
1721
1722
super_cnum = class_get_super(cnum);
1723
if ( super_cnum != 0 ) {
1724
nbytes += dump_instance_fields(super_cnum, fields, fvalues, n_fields);
1725
}
1726
return nbytes;
1727
}
1728
1729
void
1730
io_heap_instance_dump(ClassIndex cnum, ObjectIndex obj_id,
1731
SerialNumber trace_serial_num,
1732
ObjectIndex class_id, jint size, char *sig,
1733
FieldInfo *fields, jvalue *fvalues, jint n_fields)
1734
{
1735
CHECK_TRACE_SERIAL_NO(trace_serial_num);
1736
if (gdata->output_format == 'b') {
1737
jint inst_size;
1738
jint saved_inst_size;
1739
int i;
1740
int nbytes;
1741
1742
inst_size = 0;
1743
for (i = 0; i < n_fields; i++) {
1744
if ( is_inst_field(fields[i].modifiers) ) {
1745
inst_size += size_from_field_info(fields[i].primSize);
1746
}
1747
}
1748
1749
/* Verify that the instance size we have calculated as we went
1750
* through the fields, matches what is saved away with this
1751
* class.
1752
*/
1753
saved_inst_size = class_get_inst_size(cnum);
1754
if ( saved_inst_size == -1 ) {
1755
class_set_inst_size(cnum, inst_size);
1756
} else if ( saved_inst_size != inst_size ) {
1757
HPROF_ERROR(JNI_TRUE, "Mis-match on instance size in instance dump");
1758
}
1759
1760
heap_tag(HPROF_GC_INSTANCE_DUMP);
1761
heap_id(obj_id);
1762
heap_u4(trace_serial_num);
1763
heap_id(class_id);
1764
heap_u4(inst_size); /* Must match inst_size in class dump */
1765
1766
/* Order must be class, super, super's super, ... */
1767
nbytes = dump_instance_fields(cnum, fields, fvalues, n_fields);
1768
HPROF_ASSERT(nbytes==inst_size);
1769
} else {
1770
char * class_name;
1771
int i;
1772
1773
class_name = signature_to_name(sig);
1774
heap_printf("OBJ %x (sz=%u, trace=%u, class=%s@%x)\n",
1775
obj_id, size, trace_serial_num, class_name, class_id);
1776
HPROF_FREE(class_name);
1777
1778
for (i = 0; i < n_fields; i++) {
1779
if ( is_inst_field(fields[i].modifiers) ) {
1780
HprofType kind;
1781
int size;
1782
1783
type_from_signature(string_get(fields[i].sig_index),
1784
&kind, &size);
1785
if ( !HPROF_TYPE_IS_PRIMITIVE(kind) ) {
1786
if (fvalues[i].i != 0 ) {
1787
char *sep;
1788
ObjectIndex val_id;
1789
char *field_name;
1790
1791
field_name = string_get(fields[i].name_index);
1792
val_id = (ObjectIndex)(fvalues[i].i);
1793
sep = (int)strlen(field_name) < 8 ? "\t" : "";
1794
heap_printf("\t%s\t%s%x\n", field_name, sep, val_id);
1795
}
1796
}
1797
}
1798
}
1799
}
1800
}
1801
1802
void
1803
io_heap_object_array(ObjectIndex obj_id, SerialNumber trace_serial_num,
1804
jint size, jint num_elements, char *sig, ObjectIndex *values,
1805
ObjectIndex class_id)
1806
{
1807
CHECK_TRACE_SERIAL_NO(trace_serial_num);
1808
if (gdata->output_format == 'b') {
1809
1810
heap_tag(HPROF_GC_OBJ_ARRAY_DUMP);
1811
heap_id(obj_id);
1812
heap_u4(trace_serial_num);
1813
heap_u4(num_elements);
1814
heap_id(class_id);
1815
heap_elements(HPROF_NORMAL_OBJECT, num_elements,
1816
(jint)sizeof(HprofId), (void*)values);
1817
} else {
1818
char *name;
1819
int i;
1820
1821
name = signature_to_name(sig);
1822
heap_printf("ARR %x (sz=%u, trace=%u, nelems=%u, elem type=%s@%x)\n",
1823
obj_id, size, trace_serial_num, num_elements,
1824
name, class_id);
1825
for (i = 0; i < num_elements; i++) {
1826
ObjectIndex id;
1827
1828
id = values[i];
1829
if (id != 0) {
1830
heap_printf("\t[%u]\t\t%x\n", i, id);
1831
}
1832
}
1833
HPROF_FREE(name);
1834
}
1835
}
1836
1837
void
1838
io_heap_prim_array(ObjectIndex obj_id, SerialNumber trace_serial_num,
1839
jint size, jint num_elements, char *sig, void *elements)
1840
{
1841
CHECK_TRACE_SERIAL_NO(trace_serial_num);
1842
if (gdata->output_format == 'b') {
1843
HprofType kind;
1844
jint esize;
1845
1846
type_array(sig, &kind, &esize);
1847
HPROF_ASSERT(HPROF_TYPE_IS_PRIMITIVE(kind));
1848
heap_tag(HPROF_GC_PRIM_ARRAY_DUMP);
1849
heap_id(obj_id);
1850
heap_u4(trace_serial_num);
1851
heap_u4(num_elements);
1852
heap_u1(kind);
1853
heap_elements(kind, num_elements, esize, elements);
1854
} else {
1855
char *name;
1856
1857
name = signature_to_name(sig);
1858
heap_printf("ARR %x (sz=%u, trace=%u, nelems=%u, elem type=%s)\n",
1859
obj_id, size, trace_serial_num, num_elements, name);
1860
HPROF_FREE(name);
1861
}
1862
}
1863
1864
/* Move file bytes into supplied raw interface */
1865
static void
1866
write_raw_from_file(int fd, jlong byteCount, void (*raw_interface)(void *,int))
1867
{
1868
char *buf;
1869
int buf_len;
1870
int left;
1871
int nbytes;
1872
1873
HPROF_ASSERT(fd >= 0);
1874
1875
/* Move contents of this file into output file. */
1876
buf_len = FILE_IO_BUFFER_SIZE*2; /* Twice as big! */
1877
buf = HPROF_MALLOC(buf_len);
1878
HPROF_ASSERT(buf!=NULL);
1879
1880
/* Keep track of how many we have left */
1881
left = (int)byteCount;
1882
do {
1883
int count;
1884
1885
count = buf_len;
1886
if ( count > left ) count = left;
1887
nbytes = md_read(fd, buf, count);
1888
if (nbytes < 0) {
1889
system_error("read", nbytes, errno);
1890
break;
1891
}
1892
if (nbytes == 0) {
1893
break;
1894
}
1895
if ( nbytes > 0 ) {
1896
(*raw_interface)(buf, nbytes);
1897
left -= nbytes;
1898
}
1899
} while ( left > 0 );
1900
1901
if (left > 0 && nbytes == 0) {
1902
HPROF_ERROR(JNI_TRUE, "File size is smaller than bytes written");
1903
}
1904
HPROF_FREE(buf);
1905
}
1906
1907
/* Write out a heap segment, and copy remainder to top of file. */
1908
static void
1909
dump_heap_segment_and_reset(jlong segment_size)
1910
{
1911
int fd;
1912
jlong last_chunk_len;
1913
1914
HPROF_ASSERT(gdata->heap_fd >= 0);
1915
1916
/* Flush all bytes to the heap dump file */
1917
heap_flush();
1918
1919
/* Last segment? */
1920
last_chunk_len = gdata->heap_write_count - segment_size;
1921
HPROF_ASSERT(last_chunk_len>=0);
1922
1923
/* Re-open in proper way, binary vs. ascii is important */
1924
if (gdata->output_format == 'b') {
1925
int tag;
1926
1927
if ( gdata->segmented == JNI_TRUE ) { /* 1.0.2 */
1928
tag = HPROF_HEAP_DUMP_SEGMENT; /* 1.0.2 */
1929
} else {
1930
tag = HPROF_HEAP_DUMP; /* Just one segment */
1931
HPROF_ASSERT(last_chunk_len==0);
1932
}
1933
1934
/* Write header for binary heap dump (don't know size until now) */
1935
write_header(tag, (jint)segment_size);
1936
1937
fd = md_open_binary(gdata->heapfilename);
1938
} else {
1939
fd = md_open(gdata->heapfilename);
1940
}
1941
1942
/* Move file bytes into hprof dump file */
1943
write_raw_from_file(fd, segment_size, &write_raw);
1944
1945
/* Clear the byte count and reset the heap file. */
1946
if ( md_seek(gdata->heap_fd, (jlong)0) != (jlong)0 ) {
1947
HPROF_ERROR(JNI_TRUE, "Cannot seek to beginning of heap info file");
1948
}
1949
gdata->heap_write_count = (jlong)0;
1950
gdata->heap_last_tag_position = (jlong)0;
1951
1952
/* Move trailing bytes from heap dump file to beginning of file */
1953
if ( last_chunk_len > 0 ) {
1954
write_raw_from_file(fd, last_chunk_len, &heap_raw);
1955
}
1956
1957
/* Close the temp file handle */
1958
md_close(fd);
1959
}
1960
1961
void
1962
io_heap_footer(void)
1963
{
1964
HPROF_ASSERT(gdata->heap_fd >= 0);
1965
1966
/* Flush all bytes to the heap dump file */
1967
heap_flush();
1968
1969
/* Send out the last (or maybe only) segment */
1970
dump_heap_segment_and_reset(gdata->heap_write_count);
1971
1972
/* Write out the last tag */
1973
if (gdata->output_format != 'b') {
1974
write_printf("HEAP DUMP END\n");
1975
} else {
1976
if ( gdata->segmented == JNI_TRUE ) { /* 1.0.2 */
1977
write_header(HPROF_HEAP_DUMP_END, 0);
1978
}
1979
}
1980
}
1981
1982