1 /* |
|
2 * Copyright (c) 2003, 2014, 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 /* Primary hprof #include file, should be included by most if not |
|
42 * all hprof source files. Gives access to the global data structure |
|
43 * and all global macros, and everything declared in the #include |
|
44 * files of each of the source files. |
|
45 */ |
|
46 |
|
47 #ifndef HPROF_H |
|
48 #define HPROF_H |
|
49 |
|
50 /* Standard C functions used throughout. */ |
|
51 |
|
52 #include <stdio.h> |
|
53 #include <stdlib.h> |
|
54 #include <ctype.h> |
|
55 #include <string.h> |
|
56 #include <stddef.h> |
|
57 #include <stdarg.h> |
|
58 #include <limits.h> |
|
59 #include <time.h> |
|
60 #include <errno.h> |
|
61 |
|
62 /* General JVM/Java functions, types and macros. */ |
|
63 |
|
64 #include <sys/types.h> |
|
65 #include "jni.h" |
|
66 #include "jvmti.h" |
|
67 #include "classfile_constants.h" |
|
68 #include "jvm_md.h" |
|
69 |
|
70 /* Macros to extract the upper and lower 32 bits of a jlong */ |
|
71 |
|
72 #define jlong_high(a) ((jint)((a)>>32)) |
|
73 #define jlong_low(a) ((jint)(a)) |
|
74 #define jlong_to_jint(a) ((jint)(a)) |
|
75 #define jint_to_jlong(a) ((jlong)(a)) |
|
76 |
|
77 #define jlong_add(a, b) ((a) + (b)) |
|
78 |
|
79 |
|
80 /* The type used to contain a generic 32bit "serial number". */ |
|
81 |
|
82 typedef unsigned SerialNumber; |
|
83 |
|
84 /* How the options get to OnLoad: */ |
|
85 |
|
86 #define AGENTNAME "hprof" |
|
87 #define XRUN "-Xrun" AGENTNAME |
|
88 #define AGENTLIB "-agentlib:" AGENTNAME |
|
89 |
|
90 /* Name of prelude file, found at runtime relative to java binary location */ |
|
91 |
|
92 #define PRELUDE_FILE "jvm.hprof.txt" |
|
93 |
|
94 /* File I/O buffer size to be used with any file i/o operation */ |
|
95 |
|
96 #define FILE_IO_BUFFER_SIZE (1024*64) |
|
97 |
|
98 /* Machine dependent functions. */ |
|
99 |
|
100 #include "hprof_md.h" |
|
101 |
|
102 /* Table index types */ |
|
103 |
|
104 typedef unsigned TableIndex; |
|
105 typedef TableIndex ClassIndex; |
|
106 typedef TableIndex FrameIndex; |
|
107 typedef TableIndex IoNameIndex; |
|
108 typedef TableIndex MonitorIndex; |
|
109 typedef TableIndex ObjectIndex; |
|
110 typedef TableIndex LoaderIndex; |
|
111 typedef TableIndex RefIndex; |
|
112 typedef TableIndex SiteIndex; |
|
113 typedef TableIndex StringIndex; |
|
114 typedef TableIndex TlsIndex; |
|
115 typedef TableIndex TraceIndex; |
|
116 |
|
117 /* Index for method tables in classes */ |
|
118 |
|
119 typedef int MethodIndex; |
|
120 |
|
121 /* The different kinds of class status bits. */ |
|
122 |
|
123 enum ClassStatus { |
|
124 CLASS_PREPARED = 0x00000001, |
|
125 CLASS_LOADED = 0x00000002, |
|
126 CLASS_UNLOADED = 0x00000004, |
|
127 CLASS_SPECIAL = 0x00000008, |
|
128 CLASS_IN_LOAD_LIST = 0x00000010, |
|
129 CLASS_SYSTEM = 0x00000020, |
|
130 CLASS_DUMPED = 0x00000040 |
|
131 }; |
|
132 typedef jint ClassStatus; |
|
133 |
|
134 /* The different kind of objects we track with heap=dump */ |
|
135 |
|
136 typedef unsigned char ObjectKind; |
|
137 enum { |
|
138 OBJECT_NORMAL = 1, |
|
139 OBJECT_CLASS = 2, |
|
140 OBJECT_SYSTEM = 3, |
|
141 OBJECT_HPROF = 4, |
|
142 OBJECT_LOADER = 5 |
|
143 }; |
|
144 |
|
145 /* Used by site_write() when writing out the heap=sites data. */ |
|
146 |
|
147 enum { |
|
148 SITE_DUMP_INCREMENTAL = 0x01, |
|
149 SITE_SORT_BY_ALLOC = 0x02, |
|
150 SITE_FORCE_GC = 0x04 |
|
151 }; |
|
152 |
|
153 /* Used to hold information about a field, and potentially a value too. */ |
|
154 |
|
155 typedef struct FieldInfo { |
|
156 ClassIndex cnum; |
|
157 StringIndex name_index; |
|
158 StringIndex sig_index; |
|
159 unsigned short modifiers; |
|
160 unsigned char primType; |
|
161 unsigned char primSize; |
|
162 } FieldInfo; |
|
163 |
|
164 /* Used to hold information about a constant pool entry value for a class. */ |
|
165 |
|
166 typedef struct ConstantPoolValue { |
|
167 unsigned constant_pool_index; |
|
168 StringIndex sig_index; |
|
169 jvalue value; |
|
170 } ConstantPoolValue; |
|
171 |
|
172 /* All machine independent functions */ |
|
173 |
|
174 #include "hprof_error.h" |
|
175 #include "hprof_util.h" |
|
176 #include "hprof_blocks.h" |
|
177 #include "hprof_stack.h" |
|
178 #include "hprof_init.h" |
|
179 #include "hprof_table.h" |
|
180 #include "hprof_string.h" |
|
181 #include "hprof_class.h" |
|
182 #include "hprof_tracker.h" |
|
183 #include "hprof_frame.h" |
|
184 #include "hprof_monitor.h" |
|
185 #include "hprof_trace.h" |
|
186 #include "hprof_site.h" |
|
187 #include "hprof_event.h" |
|
188 #include "hprof_reference.h" |
|
189 #include "hprof_object.h" |
|
190 #include "hprof_loader.h" |
|
191 #include "hprof_tls.h" |
|
192 #include "hprof_check.h" |
|
193 #include "hprof_io.h" |
|
194 #include "hprof_listener.h" |
|
195 #include "hprof_cpu.h" |
|
196 #include "hprof_tag.h" |
|
197 |
|
198 /* Global data structure */ |
|
199 |
|
200 struct LineTable; |
|
201 |
|
202 typedef struct { |
|
203 |
|
204 jvmtiEnv *jvmti; /* JVMTI env for this session */ |
|
205 JavaVM *jvm; /* JavaVM* for this session */ |
|
206 jint cachedJvmtiVersion; /* JVMTI version number */ |
|
207 |
|
208 char *header; /* "JAVA PROFILE 1.0.[12]" */ |
|
209 jboolean segmented; /* JNI_TRUE if 1.0.2 */ |
|
210 jlong maxHeapSegment; |
|
211 jlong maxMemory; |
|
212 |
|
213 /* Option settings */ |
|
214 char * options; /* option string copy */ |
|
215 char * utf8_output_filename;/* file=filename */ |
|
216 int net_port; /* net=hostname:port */ |
|
217 char * net_hostname; /* net=hostname:port */ |
|
218 char output_format; /* format=a|b */ |
|
219 int max_trace_depth; /* depth=max_trace_depth */ |
|
220 int prof_trace_depth; /* max_trace_depth or 2 (old) */ |
|
221 int sample_interval; /* interval=sample_interval (ms) */ |
|
222 double cutoff_point; /* cutoff=cutoff_point */ |
|
223 jboolean cpu_sampling; /* cpu=samples|y */ |
|
224 jboolean cpu_timing; /* cpu=times */ |
|
225 jboolean old_timing_format; /* cpu=old (old) output format */ |
|
226 jboolean heap_dump; /* heap=dump|all */ |
|
227 jboolean alloc_sites; /* heap=sites|all */ |
|
228 jboolean thread_in_traces; /* thread=y|n */ |
|
229 jboolean lineno_in_traces; /* lineno=y|n */ |
|
230 jboolean dump_on_exit; /* doe=y|n */ |
|
231 jboolean micro_state_accounting; /* msa=y|n */ |
|
232 jboolean force_output; /* force=y|n */ |
|
233 jboolean monitor_tracing; /* monitor=y|n */ |
|
234 jboolean gc_okay; /* gc_okay=y|n (Not used) */ |
|
235 |
|
236 unsigned logflags; /* logflags=bitmask */ |
|
237 |
|
238 #define DEBUGFLAG_UNPREPARED_CLASSES 0x001 |
|
239 unsigned debugflags; /* debugflags=bitmask */ |
|
240 |
|
241 jboolean coredump; /* coredump=y|n */ |
|
242 jboolean errorexit; /* errorexit=y|n */ |
|
243 jboolean pause; /* pause=y|n */ |
|
244 jboolean debug; /* debug=y|n */ |
|
245 jboolean verbose; /* verbose=y|n */ |
|
246 jboolean primfields; /* primfields=y|n */ |
|
247 jboolean primarrays; /* primarrays=y|n */ |
|
248 jint experiment; /* X=NUMBER */ |
|
249 |
|
250 int fd; /* file or socket (net=addr). */ |
|
251 jboolean socket; /* True if fd is a socket (net=addr). */ |
|
252 jboolean bci; /* True if any kind of BCI being done */ |
|
253 jboolean obj_watch; /* True if bci and watching allocs */ |
|
254 |
|
255 int bci_counter; /* Class BCI counter */ |
|
256 |
|
257 int heap_fd; |
|
258 char *output_filename; /* file=filename */ |
|
259 char *heapfilename; |
|
260 |
|
261 int check_fd; |
|
262 char *checkfilename; |
|
263 |
|
264 volatile jboolean dump_in_process; /* Dump in process */ |
|
265 volatile jboolean jvm_initializing; /* VMInit happening */ |
|
266 volatile jboolean jvm_initialized; /* VMInit happened */ |
|
267 volatile jboolean jvm_shut_down; /* VMDeath happened */ |
|
268 jboolean vm_death_callback_active; /* VMDeath happening */ |
|
269 |
|
270 /* Stack of objects freed during GC */ |
|
271 Stack * object_free_stack; |
|
272 jrawMonitorID object_free_lock; |
|
273 |
|
274 /* Lock for debug_malloc() */ |
|
275 jrawMonitorID debug_malloc_lock; |
|
276 |
|
277 /* Count of classes that JVMTI thinks are active */ |
|
278 jint class_count; |
|
279 |
|
280 /* Used to track callbacks for VM_DEATH */ |
|
281 jrawMonitorID callbackBlock; |
|
282 jrawMonitorID callbackLock; |
|
283 jint active_callbacks; |
|
284 |
|
285 /* Running totals on all bytes allocated */ |
|
286 jlong total_alloced_bytes; |
|
287 jlong total_alloced_instances; |
|
288 jint total_live_bytes; |
|
289 jint total_live_instances; |
|
290 |
|
291 /* Running total on all time spent in GC (very rough estimate) */ |
|
292 jlong gc_start_time; |
|
293 jlong time_in_gc; |
|
294 |
|
295 /* Global Data access Lock */ |
|
296 jrawMonitorID data_access_lock; |
|
297 |
|
298 /* Global Dump lock */ |
|
299 jrawMonitorID dump_lock; |
|
300 |
|
301 /* Milli-second clock when hprof onload started */ |
|
302 jlong micro_sec_ticks; |
|
303 |
|
304 /* Thread class (for starting agent threads) */ |
|
305 ClassIndex thread_cnum; |
|
306 |
|
307 /* Agent threads started information */ |
|
308 jboolean listener_loop_running; |
|
309 jrawMonitorID listener_loop_lock; |
|
310 jboolean cpu_loop_running; |
|
311 jrawMonitorID cpu_loop_lock; |
|
312 jrawMonitorID cpu_sample_lock; /* cpu=samples loop */ |
|
313 jint gc_finish; /* Count of GC finish events */ |
|
314 jboolean gc_finish_active; /* True if thread active */ |
|
315 jboolean gc_finish_stop_request; /* True if we want it to stop */ |
|
316 jrawMonitorID gc_finish_lock; |
|
317 |
|
318 jboolean pause_cpu_sampling; /* temp pause in cpu sampling */ |
|
319 |
|
320 /* Output buffer, position, size, and position in dump if reading */ |
|
321 char * write_buffer; |
|
322 int write_buffer_index; |
|
323 int write_buffer_size; |
|
324 char * heap_buffer; |
|
325 int heap_buffer_index; |
|
326 int heap_buffer_size; |
|
327 jlong heap_last_tag_position; |
|
328 jlong heap_write_count; |
|
329 char * check_buffer; |
|
330 int check_buffer_index; |
|
331 int check_buffer_size; |
|
332 |
|
333 /* Serial number counters for tables (see hprof_table.c), classes, |
|
334 * tls (thread local storage), and traces. |
|
335 */ |
|
336 SerialNumber table_serial_number_start; |
|
337 SerialNumber class_serial_number_start; |
|
338 SerialNumber thread_serial_number_start; |
|
339 SerialNumber trace_serial_number_start; |
|
340 SerialNumber object_serial_number_start; |
|
341 SerialNumber frame_serial_number_start; |
|
342 SerialNumber gref_serial_number_start; |
|
343 |
|
344 SerialNumber table_serial_number_counter; |
|
345 SerialNumber class_serial_number_counter; |
|
346 SerialNumber thread_serial_number_counter; |
|
347 SerialNumber trace_serial_number_counter; |
|
348 SerialNumber object_serial_number_counter; |
|
349 SerialNumber frame_serial_number_counter; |
|
350 SerialNumber gref_serial_number_counter; |
|
351 |
|
352 /* The methodID for the Object <init> method. */ |
|
353 jmethodID object_init_method; |
|
354 |
|
355 /* Keeping track of the tracker class and it's methods */ |
|
356 volatile jint tracking_engaged; /* !=0 means it's on */ |
|
357 ClassIndex tracker_cnum; |
|
358 int tracker_method_count; |
|
359 struct { |
|
360 StringIndex name; /* String index for name */ |
|
361 StringIndex sig; /* String index for signature */ |
|
362 jmethodID method; /* Method ID */ |
|
363 } tracker_methods[12]; /* MAX 12 Tracker class methods */ |
|
364 |
|
365 /* Index to some common items */ |
|
366 LoaderIndex system_loader; |
|
367 SerialNumber unknown_thread_serial_num; |
|
368 TraceIndex system_trace_index; |
|
369 SiteIndex system_object_site_index; |
|
370 jint system_class_size; |
|
371 TraceIndex hprof_trace_index; |
|
372 SiteIndex hprof_site_index; |
|
373 |
|
374 /* Tables for strings, classes, sites, etc. */ |
|
375 struct LookupTable * string_table; |
|
376 struct LookupTable * ioname_table; |
|
377 struct LookupTable * class_table; |
|
378 struct LookupTable * site_table; |
|
379 struct LookupTable * object_table; |
|
380 struct LookupTable * reference_table; |
|
381 struct LookupTable * frame_table; |
|
382 struct LookupTable * trace_table; |
|
383 struct LookupTable * monitor_table; |
|
384 struct LookupTable * tls_table; |
|
385 struct LookupTable * loader_table; |
|
386 |
|
387 /* Handles to java_crw_demo library */ |
|
388 void * java_crw_demo_library; |
|
389 void * java_crw_demo_function; |
|
390 void * java_crw_demo_classname_function; |
|
391 |
|
392 /* Indication that the agent has been loaded */ |
|
393 jboolean isLoaded; |
|
394 |
|
395 } GlobalData; |
|
396 |
|
397 /* This should be the only 'extern' in the library (not exported). */ |
|
398 |
|
399 extern GlobalData * gdata; |
|
400 |
|
401 #endif |
|