/* * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Oracle nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This source code is provided to illustrate the usage of a given feature * or technique and has been deliberately simplified. Additional steps * required for a production-quality application, such as security checks, * input validation and proper error handling, might not be present in * this sample code. */ /* Primary hprof #include file, should be included by most if not * all hprof source files. Gives access to the global data structure * and all global macros, and everything declared in the #include * files of each of the source files. */ #ifndef HPROF_H #define HPROF_H /* Standard C functions used throughout. */ #include #include #include #include #include #include #include #include #include /* General JVM/Java functions, types and macros. */ #include #include "jni.h" #include "jvmti.h" #include "classfile_constants.h" #include "jvm_md.h" #ifndef SKIP_NPT #include "npt.h" /* To get NptEnv for doing character conversions */ #endif /* Macros to extract the upper and lower 32 bits of a jlong */ #define jlong_high(a) ((jint)((a)>>32)) #define jlong_low(a) ((jint)(a)) #define jlong_to_jint(a) ((jint)(a)) #define jint_to_jlong(a) ((jlong)(a)) #define jlong_add(a, b) ((a) + (b)) /* The type used to contain a generic 32bit "serial number". */ typedef unsigned SerialNumber; /* How the options get to OnLoad: */ #define AGENTNAME "hprof" #define XRUN "-Xrun" AGENTNAME #define AGENTLIB "-agentlib:" AGENTNAME /* Name of prelude file, found at runtime relative to java binary location */ #define PRELUDE_FILE "jvm.hprof.txt" /* File I/O buffer size to be used with any file i/o operation */ #define FILE_IO_BUFFER_SIZE (1024*64) /* Machine dependent functions. */ #include "hprof_md.h" /* Table index types */ typedef unsigned TableIndex; typedef TableIndex ClassIndex; typedef TableIndex FrameIndex; typedef TableIndex IoNameIndex; typedef TableIndex MonitorIndex; typedef TableIndex ObjectIndex; typedef TableIndex LoaderIndex; typedef TableIndex RefIndex; typedef TableIndex SiteIndex; typedef TableIndex StringIndex; typedef TableIndex TlsIndex; typedef TableIndex TraceIndex; /* Index for method tables in classes */ typedef int MethodIndex; /* The different kinds of class status bits. */ enum ClassStatus { CLASS_PREPARED = 0x00000001, CLASS_LOADED = 0x00000002, CLASS_UNLOADED = 0x00000004, CLASS_SPECIAL = 0x00000008, CLASS_IN_LOAD_LIST = 0x00000010, CLASS_SYSTEM = 0x00000020, CLASS_DUMPED = 0x00000040 }; typedef jint ClassStatus; /* The different kind of objects we track with heap=dump */ typedef unsigned char ObjectKind; enum { OBJECT_NORMAL = 1, OBJECT_CLASS = 2, OBJECT_SYSTEM = 3, OBJECT_HPROF = 4, OBJECT_LOADER = 5 }; /* Used by site_write() when writing out the heap=sites data. */ enum { SITE_DUMP_INCREMENTAL = 0x01, SITE_SORT_BY_ALLOC = 0x02, SITE_FORCE_GC = 0x04 }; /* Used to hold information about a field, and potentially a value too. */ typedef struct FieldInfo { ClassIndex cnum; StringIndex name_index; StringIndex sig_index; unsigned short modifiers; unsigned char primType; unsigned char primSize; } FieldInfo; /* Used to hold information about a constant pool entry value for a class. */ typedef struct ConstantPoolValue { unsigned constant_pool_index; StringIndex sig_index; jvalue value; } ConstantPoolValue; /* All machine independent functions */ #include "hprof_error.h" #include "hprof_util.h" #include "hprof_blocks.h" #include "hprof_stack.h" #include "hprof_init.h" #include "hprof_table.h" #include "hprof_string.h" #include "hprof_class.h" #include "hprof_tracker.h" #include "hprof_frame.h" #include "hprof_monitor.h" #include "hprof_trace.h" #include "hprof_site.h" #include "hprof_event.h" #include "hprof_reference.h" #include "hprof_object.h" #include "hprof_loader.h" #include "hprof_tls.h" #include "hprof_check.h" #include "hprof_io.h" #include "hprof_listener.h" #include "hprof_cpu.h" #include "hprof_tag.h" /* Global data structure */ struct LineTable; typedef struct { jvmtiEnv *jvmti; /* JVMTI env for this session */ JavaVM *jvm; /* JavaVM* for this session */ #ifndef SKIP_NPT NptEnv *npt; /* NptEnv* for this session, see npt.h */ #endif jint cachedJvmtiVersion; /* JVMTI version number */ char *header; /* "JAVA PROFILE 1.0.[12]" */ jboolean segmented; /* JNI_TRUE if 1.0.2 */ jlong maxHeapSegment; jlong maxMemory; /* Option settings */ char * options; /* option string copy */ char * utf8_output_filename;/* file=filename */ int net_port; /* net=hostname:port */ char * net_hostname; /* net=hostname:port */ char output_format; /* format=a|b */ int max_trace_depth; /* depth=max_trace_depth */ int prof_trace_depth; /* max_trace_depth or 2 (old) */ int sample_interval; /* interval=sample_interval (ms) */ double cutoff_point; /* cutoff=cutoff_point */ jboolean cpu_sampling; /* cpu=samples|y */ jboolean cpu_timing; /* cpu=times */ jboolean old_timing_format; /* cpu=old (old) output format */ jboolean heap_dump; /* heap=dump|all */ jboolean alloc_sites; /* heap=sites|all */ jboolean thread_in_traces; /* thread=y|n */ jboolean lineno_in_traces; /* lineno=y|n */ jboolean dump_on_exit; /* doe=y|n */ jboolean micro_state_accounting; /* msa=y|n */ jboolean force_output; /* force=y|n */ jboolean monitor_tracing; /* monitor=y|n */ jboolean gc_okay; /* gc_okay=y|n (Not used) */ unsigned logflags; /* logflags=bitmask */ #define DEBUGFLAG_UNPREPARED_CLASSES 0x001 unsigned debugflags; /* debugflags=bitmask */ jboolean coredump; /* coredump=y|n */ jboolean errorexit; /* errorexit=y|n */ jboolean pause; /* pause=y|n */ jboolean debug; /* debug=y|n */ jboolean verbose; /* verbose=y|n */ jboolean primfields; /* primfields=y|n */ jboolean primarrays; /* primarrays=y|n */ jint experiment; /* X=NUMBER */ int fd; /* file or socket (net=addr). */ jboolean socket; /* True if fd is a socket (net=addr). */ jboolean bci; /* True if any kind of BCI being done */ jboolean obj_watch; /* True if bci and watching allocs */ int bci_counter; /* Class BCI counter */ int heap_fd; char *output_filename; /* file=filename */ char *heapfilename; int check_fd; char *checkfilename; volatile jboolean dump_in_process; /* Dump in process */ volatile jboolean jvm_initializing; /* VMInit happening */ volatile jboolean jvm_initialized; /* VMInit happened */ volatile jboolean jvm_shut_down; /* VMDeath happened */ jboolean vm_death_callback_active; /* VMDeath happening */ /* Stack of objects freed during GC */ Stack * object_free_stack; jrawMonitorID object_free_lock; /* Lock for debug_malloc() */ jrawMonitorID debug_malloc_lock; /* Count of classes that JVMTI thinks are active */ jint class_count; /* Used to track callbacks for VM_DEATH */ jrawMonitorID callbackBlock; jrawMonitorID callbackLock; jint active_callbacks; /* Running totals on all bytes allocated */ jlong total_alloced_bytes; jlong total_alloced_instances; jint total_live_bytes; jint total_live_instances; /* Running total on all time spent in GC (very rough estimate) */ jlong gc_start_time; jlong time_in_gc; /* Global Data access Lock */ jrawMonitorID data_access_lock; /* Global Dump lock */ jrawMonitorID dump_lock; /* Milli-second clock when hprof onload started */ jlong micro_sec_ticks; /* Thread class (for starting agent threads) */ ClassIndex thread_cnum; /* Agent threads started information */ jboolean listener_loop_running; jrawMonitorID listener_loop_lock; jboolean cpu_loop_running; jrawMonitorID cpu_loop_lock; jrawMonitorID cpu_sample_lock; /* cpu=samples loop */ jint gc_finish; /* Count of GC finish events */ jboolean gc_finish_active; /* True if thread active */ jboolean gc_finish_stop_request; /* True if we want it to stop */ jrawMonitorID gc_finish_lock; jboolean pause_cpu_sampling; /* temp pause in cpu sampling */ /* Output buffer, position, size, and position in dump if reading */ char * write_buffer; int write_buffer_index; int write_buffer_size; char * heap_buffer; int heap_buffer_index; int heap_buffer_size; jlong heap_last_tag_position; jlong heap_write_count; char * check_buffer; int check_buffer_index; int check_buffer_size; /* Serial number counters for tables (see hprof_table.c), classes, * tls (thread local storage), and traces. */ SerialNumber table_serial_number_start; SerialNumber class_serial_number_start; SerialNumber thread_serial_number_start; SerialNumber trace_serial_number_start; SerialNumber object_serial_number_start; SerialNumber frame_serial_number_start; SerialNumber gref_serial_number_start; SerialNumber table_serial_number_counter; SerialNumber class_serial_number_counter; SerialNumber thread_serial_number_counter; SerialNumber trace_serial_number_counter; SerialNumber object_serial_number_counter; SerialNumber frame_serial_number_counter; SerialNumber gref_serial_number_counter; /* The methodID for the Object method. */ jmethodID object_init_method; /* Keeping track of the tracker class and it's methods */ volatile jint tracking_engaged; /* !=0 means it's on */ ClassIndex tracker_cnum; int tracker_method_count; struct { StringIndex name; /* String index for name */ StringIndex sig; /* String index for signature */ jmethodID method; /* Method ID */ } tracker_methods[12]; /* MAX 12 Tracker class methods */ /* Index to some common items */ LoaderIndex system_loader; SerialNumber unknown_thread_serial_num; TraceIndex system_trace_index; SiteIndex system_object_site_index; jint system_class_size; TraceIndex hprof_trace_index; SiteIndex hprof_site_index; /* Tables for strings, classes, sites, etc. */ struct LookupTable * string_table; struct LookupTable * ioname_table; struct LookupTable * class_table; struct LookupTable * site_table; struct LookupTable * object_table; struct LookupTable * reference_table; struct LookupTable * frame_table; struct LookupTable * trace_table; struct LookupTable * monitor_table; struct LookupTable * tls_table; struct LookupTable * loader_table; /* Handles to java_crw_demo library */ void * java_crw_demo_library; void * java_crw_demo_function; void * java_crw_demo_classname_function; /* Indication that the agent has been loaded */ jboolean isLoaded; } GlobalData; /* This should be the only 'extern' in the library (not exported). */ extern GlobalData * gdata; #endif