32
32
#include "perf-map-file.h"
33
33
34
34
#define STRING_BUFFER_SIZE 2000
35
+ #define BIG_STRING_BUFFER_SIZE 20000
35
36
36
37
bool unfold_inlined_methods = false;
37
38
bool unfold_simple = false;
39
+ bool unfold_all = false;
38
40
bool print_method_signatures = false;
39
41
bool print_source_loc = false;
40
42
bool clean_class_names = false;
43
+ bool debug_dump_unfold_entries = false;
41
44
42
45
FILE * method_file = NULL ;
43
46
void open_map_file () {
@@ -140,7 +143,7 @@ void generate_unfolded_entry(jvmtiEnv *jvmti, jmethodID method, char *buffer, si
140
143
/* Generates and writes a single entry for a given inlined method. */
141
144
void write_unfolded_entry (
142
145
jvmtiEnv * jvmti ,
143
- jmethodID cur_method ,
146
+ PCStackInfo * info ,
144
147
jmethodID root_method ,
145
148
const char * root_name ,
146
149
const void * start_addr ,
@@ -149,15 +152,60 @@ void write_unfolded_entry(
149
152
char inlined_name [STRING_BUFFER_SIZE * 2 + 4 ];
150
153
const char * entry_p ;
151
154
152
- if (cur_method != root_method ) {
153
- generate_unfolded_entry (jvmti , cur_method , inlined_name , sizeof (inlined_name ), root_name );
154
- entry_p = inlined_name ;
155
- } else
156
- entry_p = root_name ;
155
+ if (unfold_all ) {
156
+ char full_name [BIG_STRING_BUFFER_SIZE ];
157
+ full_name [0 ] = '\0' ;
158
+ int i ;
159
+ for (i = info -> numstackframes - 1 ; i >= 0 ; i -- ) {
160
+ //printf("At %d method is %d len %d remaining %d\n", i, info->methods[i], strlen(full_name), sizeof(full_name) - 1 - strlen(full_name));
161
+ sig_string (jvmti , info -> methods [i ], inlined_name , sizeof (inlined_name ));
162
+ strncat (full_name , inlined_name , sizeof (full_name ) - 1 - strlen (full_name )); // TODO optimize
163
+ if (i != 0 ) strncat (full_name , "->" , sizeof (full_name ));
164
+ }
165
+ entry_p = full_name ;
166
+ } else {
167
+ jmethodID cur_method = info -> methods [0 ]; // top of stack
168
+ if (cur_method != root_method ) {
169
+ generate_unfolded_entry (jvmti , cur_method , inlined_name , sizeof (inlined_name ), root_name );
170
+ entry_p = inlined_name ;
171
+ } else
172
+ entry_p = root_name ;
173
+ }
157
174
158
175
perf_map_write_entry (method_file , start_addr , end_addr - start_addr , entry_p );
159
176
}
160
177
178
+ void dump_entries (
179
+ jvmtiEnv * jvmti ,
180
+ jmethodID root_method ,
181
+ jint code_size ,
182
+ const void * code_addr ,
183
+ jint map_length ,
184
+ const jvmtiAddrLocationMap * map ,
185
+ const void * compile_info ) {
186
+ const jvmtiCompiledMethodLoadRecordHeader * header = compile_info ;
187
+ char root_name [STRING_BUFFER_SIZE ];
188
+ sig_string (jvmti , root_method , root_name , sizeof (root_name ));
189
+ printf ("At %s size %x from %p to %p" , root_name , code_size , code_addr , code_addr + code_size );
190
+ if (header -> kind == JVMTI_CMLR_INLINE_INFO ) {
191
+ const jvmtiCompiledMethodLoadInlineRecord * record = (jvmtiCompiledMethodLoadInlineRecord * ) header ;
192
+ printf (" with %d entries\n" , record -> numpcs );
193
+
194
+ int i ;
195
+ for (i = 0 ; i < record -> numpcs ; i ++ ) {
196
+ PCStackInfo * info = & record -> pcinfo [i ];
197
+ printf (" %p has %d stack entries\n" , info -> pc , info -> numstackframes );
198
+
199
+ int j ;
200
+ for (j = 0 ; j < info -> numstackframes ; j ++ ) {
201
+ char buf [2000 ];
202
+ sig_string (jvmti , info -> methods [j ], buf , sizeof (buf ));
203
+ printf (" %s\n" , buf );
204
+ }
205
+ }
206
+ } else printf (" with no inline info\n" );
207
+ }
208
+
161
209
void generate_unfolded_entries (
162
210
jvmtiEnv * jvmti ,
163
211
jmethodID root_method ,
@@ -170,6 +218,10 @@ void generate_unfolded_entries(
170
218
char root_name [STRING_BUFFER_SIZE ];
171
219
172
220
sig_string (jvmti , root_method , root_name , sizeof (root_name ));
221
+
222
+ if (debug_dump_unfold_entries )
223
+ dump_entries (jvmti , root_method , code_size , code_addr , map_length , map , compile_info );
224
+
173
225
if (header -> kind == JVMTI_CMLR_INLINE_INFO ) {
174
226
const jvmtiCompiledMethodLoadInlineRecord * record = (jvmtiCompiledMethodLoadInlineRecord * ) header ;
175
227
@@ -185,10 +237,13 @@ void generate_unfolded_entries(
185
237
186
238
// as long as the top method remains the same we delay recording
187
239
if (cur_method != top_method ) {
188
-
189
240
// top method has changed, record the range for current method
190
241
void * end_addr = info -> pc ;
191
- write_unfolded_entry (jvmti , cur_method , root_method , root_name , start_addr , end_addr );
242
+
243
+ if (i > 0 )
244
+ write_unfolded_entry (jvmti , & record -> pcinfo [i - 1 ], root_method , root_name , start_addr , end_addr );
245
+ else
246
+ generate_single_entry (jvmti , root_method , start_addr , end_addr - start_addr );
192
247
193
248
start_addr = info -> pc ;
194
249
cur_method = top_method ;
@@ -199,7 +254,11 @@ void generate_unfolded_entries(
199
254
if (start_addr != code_addr + code_size ) {
200
255
// end_addr is end of this complete code blob
201
256
const void * end_addr = code_addr + code_size ;
202
- write_unfolded_entry (jvmti , cur_method , root_method , root_name , start_addr , end_addr );
257
+
258
+ if (i > 0 )
259
+ write_unfolded_entry (jvmti , & record -> pcinfo [i - 1 ], root_method , root_name , start_addr , end_addr );
260
+ else
261
+ generate_single_entry (jvmti , root_method , start_addr , end_addr - start_addr );
203
262
}
204
263
} else
205
264
generate_single_entry (jvmti , root_method , code_addr , code_size );
@@ -265,10 +324,12 @@ Agent_OnAttach(JavaVM *vm, char *options, void *reserved) {
265
324
open_map_file ();
266
325
267
326
unfold_simple = strstr (options , "unfoldsimple" ) != NULL ;
268
- unfold_inlined_methods = strstr (options , "unfold" ) != NULL || unfold_simple ;
327
+ unfold_all = strstr (options , "unfoldall" ) != NULL ;
328
+ unfold_inlined_methods = strstr (options , "unfold" ) != NULL || unfold_simple || unfold_all ;
269
329
print_method_signatures = strstr (options , "msig" ) != NULL ;
270
330
print_source_loc = strstr (options , "sourcepos" ) != NULL ;
271
331
clean_class_names = strstr (options , "dottedclass" ) != NULL ;
332
+ debug_dump_unfold_entries = strstr (options , "debug_dump_unfold_entries" ) != NULL ;
272
333
273
334
jvmtiEnv * jvmti ;
274
335
(* vm )-> GetEnv (vm , (void * * )& jvmti , JVMTI_VERSION_1 );
0 commit comments