Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/src/share/vm/services/heapDumper.cpp
48773 views
/*1* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/symbolTable.hpp"26#include "classfile/systemDictionary.hpp"27#include "classfile/vmSymbols.hpp"28#include "gc_implementation/shared/vmGCOperations.hpp"29#include "memory/gcLocker.inline.hpp"30#include "memory/genCollectedHeap.hpp"31#include "memory/universe.hpp"32#include "oops/objArrayKlass.hpp"33#include "runtime/javaCalls.hpp"34#include "runtime/jniHandles.hpp"35#include "runtime/reflectionUtils.hpp"36#include "runtime/vframe.hpp"37#include "runtime/vmThread.hpp"38#include "runtime/vm_operations.hpp"39#include "services/heapDumper.hpp"40#include "services/threadService.hpp"41#include "utilities/ostream.hpp"42#include "utilities/macros.hpp"43#if INCLUDE_ALL_GCS44#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"45#endif // INCLUDE_ALL_GCS4647/*48* HPROF binary format - description copied from:49* src/share/demo/jvmti/hprof/hprof_io.c50*51*52* header "JAVA PROFILE 1.0.2" (0-terminated)53*54* u4 size of identifiers. Identifiers are used to represent55* UTF8 strings, objects, stack traces, etc. They usually56* have the same size as host pointers. For example, on57* Solaris and Win32, the size is 4.58* u4 high word59* u4 low word number of milliseconds since 0:00 GMT, 1/1/7060* [record]* a sequence of records.61*62*63* Record format:64*65* u1 a TAG denoting the type of the record66* u4 number of *microseconds* since the time stamp in the67* header. (wraps around in a little more than an hour)68* u4 number of bytes *remaining* in the record. Note that69* this number excludes the tag and the length field itself.70* [u1]* BODY of the record (a sequence of bytes)71*72*73* The following TAGs are supported:74*75* TAG BODY notes76*----------------------------------------------------------77* HPROF_UTF8 a UTF8-encoded name78*79* id name ID80* [u1]* UTF8 characters (no trailing zero)81*82* HPROF_LOAD_CLASS a newly loaded class83*84* u4 class serial number (> 0)85* id class object ID86* u4 stack trace serial number87* id class name ID88*89* HPROF_UNLOAD_CLASS an unloading class90*91* u4 class serial_number92*93* HPROF_FRAME a Java stack frame94*95* id stack frame ID96* id method name ID97* id method signature ID98* id source file name ID99* u4 class serial number100* i4 line number. >0: normal101* -1: unknown102* -2: compiled method103* -3: native method104*105* HPROF_TRACE a Java stack trace106*107* u4 stack trace serial number108* u4 thread serial number109* u4 number of frames110* [id]* stack frame IDs111*112*113* HPROF_ALLOC_SITES a set of heap allocation sites, obtained after GC114*115* u2 flags 0x0001: incremental vs. complete116* 0x0002: sorted by allocation vs. live117* 0x0004: whether to force a GC118* u4 cutoff ratio119* u4 total live bytes120* u4 total live instances121* u8 total bytes allocated122* u8 total instances allocated123* u4 number of sites that follow124* [u1 is_array: 0: normal object125* 2: object array126* 4: boolean array127* 5: char array128* 6: float array129* 7: double array130* 8: byte array131* 9: short array132* 10: int array133* 11: long array134* u4 class serial number (may be zero during startup)135* u4 stack trace serial number136* u4 number of bytes alive137* u4 number of instances alive138* u4 number of bytes allocated139* u4]* number of instance allocated140*141* HPROF_START_THREAD a newly started thread.142*143* u4 thread serial number (> 0)144* id thread object ID145* u4 stack trace serial number146* id thread name ID147* id thread group name ID148* id thread group parent name ID149*150* HPROF_END_THREAD a terminating thread.151*152* u4 thread serial number153*154* HPROF_HEAP_SUMMARY heap summary155*156* u4 total live bytes157* u4 total live instances158* u8 total bytes allocated159* u8 total instances allocated160*161* HPROF_HEAP_DUMP denote a heap dump162*163* [heap dump sub-records]*164*165* There are four kinds of heap dump sub-records:166*167* u1 sub-record type168*169* HPROF_GC_ROOT_UNKNOWN unknown root170*171* id object ID172*173* HPROF_GC_ROOT_THREAD_OBJ thread object174*175* id thread object ID (may be 0 for a176* thread newly attached through JNI)177* u4 thread sequence number178* u4 stack trace sequence number179*180* HPROF_GC_ROOT_JNI_GLOBAL JNI global ref root181*182* id object ID183* id JNI global ref ID184*185* HPROF_GC_ROOT_JNI_LOCAL JNI local ref186*187* id object ID188* u4 thread serial number189* u4 frame # in stack trace (-1 for empty)190*191* HPROF_GC_ROOT_JAVA_FRAME Java stack frame192*193* id object ID194* u4 thread serial number195* u4 frame # in stack trace (-1 for empty)196*197* HPROF_GC_ROOT_NATIVE_STACK Native stack198*199* id object ID200* u4 thread serial number201*202* HPROF_GC_ROOT_STICKY_CLASS System class203*204* id object ID205*206* HPROF_GC_ROOT_THREAD_BLOCK Reference from thread block207*208* id object ID209* u4 thread serial number210*211* HPROF_GC_ROOT_MONITOR_USED Busy monitor212*213* id object ID214*215* HPROF_GC_CLASS_DUMP dump of a class object216*217* id class object ID218* u4 stack trace serial number219* id super class object ID220* id class loader object ID221* id signers object ID222* id protection domain object ID223* id reserved224* id reserved225*226* u4 instance size (in bytes)227*228* u2 size of constant pool229* [u2, constant pool index,230* ty, type231* 2: object232* 4: boolean233* 5: char234* 6: float235* 7: double236* 8: byte237* 9: short238* 10: int239* 11: long240* vl]* and value241*242* u2 number of static fields243* [id, static field name,244* ty, type,245* vl]* and value246*247* u2 number of inst. fields (not inc. super)248* [id, instance field name,249* ty]* type250*251* HPROF_GC_INSTANCE_DUMP dump of a normal object252*253* id object ID254* u4 stack trace serial number255* id class object ID256* u4 number of bytes that follow257* [vl]* instance field values (class, followed258* by super, super's super ...)259*260* HPROF_GC_OBJ_ARRAY_DUMP dump of an object array261*262* id array object ID263* u4 stack trace serial number264* u4 number of elements265* id array class ID266* [id]* elements267*268* HPROF_GC_PRIM_ARRAY_DUMP dump of a primitive array269*270* id array object ID271* u4 stack trace serial number272* u4 number of elements273* u1 element type274* 4: boolean array275* 5: char array276* 6: float array277* 7: double array278* 8: byte array279* 9: short array280* 10: int array281* 11: long array282* [u1]* elements283*284* HPROF_CPU_SAMPLES a set of sample traces of running threads285*286* u4 total number of samples287* u4 # of traces288* [u4 # of samples289* u4]* stack trace serial number290*291* HPROF_CONTROL_SETTINGS the settings of on/off switches292*293* u4 0x00000001: alloc traces on/off294* 0x00000002: cpu sampling on/off295* u2 stack trace depth296*297*298* When the header is "JAVA PROFILE 1.0.2" a heap dump can optionally299* be generated as a sequence of heap dump segments. This sequence is300* terminated by an end record. The additional tags allowed by format301* "JAVA PROFILE 1.0.2" are:302*303* HPROF_HEAP_DUMP_SEGMENT denote a heap dump segment304*305* [heap dump sub-records]*306* The same sub-record types allowed by HPROF_HEAP_DUMP307*308* HPROF_HEAP_DUMP_END denotes the end of a heap dump309*310*/311312313// HPROF tags314315typedef enum {316// top-level records317HPROF_UTF8 = 0x01,318HPROF_LOAD_CLASS = 0x02,319HPROF_UNLOAD_CLASS = 0x03,320HPROF_FRAME = 0x04,321HPROF_TRACE = 0x05,322HPROF_ALLOC_SITES = 0x06,323HPROF_HEAP_SUMMARY = 0x07,324HPROF_START_THREAD = 0x0A,325HPROF_END_THREAD = 0x0B,326HPROF_HEAP_DUMP = 0x0C,327HPROF_CPU_SAMPLES = 0x0D,328HPROF_CONTROL_SETTINGS = 0x0E,329330// 1.0.2 record types331HPROF_HEAP_DUMP_SEGMENT = 0x1C,332HPROF_HEAP_DUMP_END = 0x2C,333334// field types335HPROF_ARRAY_OBJECT = 0x01,336HPROF_NORMAL_OBJECT = 0x02,337HPROF_BOOLEAN = 0x04,338HPROF_CHAR = 0x05,339HPROF_FLOAT = 0x06,340HPROF_DOUBLE = 0x07,341HPROF_BYTE = 0x08,342HPROF_SHORT = 0x09,343HPROF_INT = 0x0A,344HPROF_LONG = 0x0B,345346// data-dump sub-records347HPROF_GC_ROOT_UNKNOWN = 0xFF,348HPROF_GC_ROOT_JNI_GLOBAL = 0x01,349HPROF_GC_ROOT_JNI_LOCAL = 0x02,350HPROF_GC_ROOT_JAVA_FRAME = 0x03,351HPROF_GC_ROOT_NATIVE_STACK = 0x04,352HPROF_GC_ROOT_STICKY_CLASS = 0x05,353HPROF_GC_ROOT_THREAD_BLOCK = 0x06,354HPROF_GC_ROOT_MONITOR_USED = 0x07,355HPROF_GC_ROOT_THREAD_OBJ = 0x08,356HPROF_GC_CLASS_DUMP = 0x20,357HPROF_GC_INSTANCE_DUMP = 0x21,358HPROF_GC_OBJ_ARRAY_DUMP = 0x22,359HPROF_GC_PRIM_ARRAY_DUMP = 0x23360} hprofTag;361362// Default stack trace ID (used for dummy HPROF_TRACE record)363enum {364STACK_TRACE_ID = 1,365INITIAL_CLASS_COUNT = 200366};367368// Supports I/O operations on a dump file369370class DumpWriter : public StackObj {371private:372enum {373io_buffer_size = 8*M374};375376int _fd; // file descriptor (-1 if dump file not open)377julong _bytes_written; // number of byte written to dump file378379char* _buffer; // internal buffer380size_t _size;381size_t _pos;382383jlong _dump_start;384385char* _error; // error message when I/O fails386387void set_file_descriptor(int fd) { _fd = fd; }388int file_descriptor() const { return _fd; }389390char* buffer() const { return _buffer; }391size_t buffer_size() const { return _size; }392size_t position() const { return _pos; }393void set_position(size_t pos) { _pos = pos; }394395void set_error(const char* error) { _error = (char*)os::strdup(error); }396397// all I/O go through this function398void write_internal(void* s, size_t len);399400public:401DumpWriter(const char* path);402~DumpWriter();403404void close();405bool is_open() const { return file_descriptor() >= 0; }406void flush();407408jlong dump_start() const { return _dump_start; }409void set_dump_start(jlong pos);410julong current_record_length();411412// total number of bytes written to the disk413julong bytes_written() const { return _bytes_written; }414415// adjust the number of bytes written to disk (used to keep the count416// of the number of bytes written in case of rewrites)417void adjust_bytes_written(jlong n) { _bytes_written += n; }418419// number of (buffered) bytes as yet unwritten to the dump file420size_t bytes_unwritten() const { return position(); }421422char* error() const { return _error; }423424jlong current_offset();425void seek_to_offset(jlong pos);426427// writer functions428void write_raw(void* s, size_t len);429void write_u1(u1 x) { write_raw((void*)&x, 1); }430void write_u2(u2 x);431void write_u4(u4 x);432void write_u8(u8 x);433void write_objectID(oop o);434void write_symbolID(Symbol* o);435void write_classID(Klass* k);436void write_id(u4 x);437};438439DumpWriter::DumpWriter(const char* path) {440// try to allocate an I/O buffer of io_buffer_size. If there isn't441// sufficient memory then reduce size until we can allocate something.442_size = io_buffer_size;443do {444_buffer = (char*)os::malloc(_size, mtInternal);445if (_buffer == NULL) {446_size = _size >> 1;447}448} while (_buffer == NULL && _size > 0);449assert((_size > 0 && _buffer != NULL) || (_size == 0 && _buffer == NULL), "sanity check");450_pos = 0;451_error = NULL;452_bytes_written = 0L;453_dump_start = (jlong)-1;454_fd = os::create_binary_file(path, false); // don't replace existing file455456// if the open failed we record the error457if (_fd < 0) {458_error = (char*)os::strdup(strerror(errno));459}460}461462DumpWriter::~DumpWriter() {463// flush and close dump file464if (is_open()) {465close();466}467if (_buffer != NULL) os::free(_buffer);468if (_error != NULL) os::free(_error);469}470471// closes dump file (if open)472void DumpWriter::close() {473// flush and close dump file474if (is_open()) {475flush();476::close(file_descriptor());477set_file_descriptor(-1);478}479}480481// sets the dump starting position482void DumpWriter::set_dump_start(jlong pos) {483_dump_start = pos;484}485486julong DumpWriter::current_record_length() {487if (is_open()) {488// calculate the size of the dump record489julong dump_end = bytes_written() + bytes_unwritten();490assert(dump_end == (size_t)current_offset(), "checking");491julong dump_len = dump_end - dump_start() - 4;492return dump_len;493}494return 0;495}496497// write directly to the file498void DumpWriter::write_internal(void* s, size_t len) {499if (is_open()) {500const char* pos = (char*)s;501ssize_t n = 0;502while (len > 0) {503uint tmp = (uint)MIN2(len, (size_t)UINT_MAX);504n = ::write(file_descriptor(), pos, tmp);505506if (n < 0) {507set_error(strerror(errno));508::close(file_descriptor());509set_file_descriptor(-1);510return;511}512513_bytes_written += n;514pos += n;515len -= n;516}517}518}519520// write raw bytes521void DumpWriter::write_raw(void* s, size_t len) {522if (is_open()) {523// flush buffer to make room524if ((position() + len) >= buffer_size()) {525flush();526}527528// buffer not available or too big to buffer it529if ((buffer() == NULL) || (len >= buffer_size())) {530write_internal(s, len);531} else {532// Should optimize this for u1/u2/u4/u8 sizes.533memcpy(buffer() + position(), s, len);534set_position(position() + len);535}536}537}538539// flush any buffered bytes to the file540void DumpWriter::flush() {541if (is_open() && position() > 0) {542write_internal(buffer(), position());543set_position(0);544}545}546547jlong DumpWriter::current_offset() {548if (is_open()) {549// the offset is the file offset plus whatever we have buffered550jlong offset = os::current_file_offset(file_descriptor());551assert(offset >= 0, "lseek failed");552return offset + position();553} else {554return (jlong)-1;555}556}557558void DumpWriter::seek_to_offset(jlong off) {559assert(off >= 0, "bad offset");560561// need to flush before seeking562flush();563564// may be closed due to I/O error565if (is_open()) {566jlong n = os::seek_to_file_offset(file_descriptor(), off);567assert(n >= 0, "lseek failed");568}569}570571void DumpWriter::write_u2(u2 x) {572u2 v;573Bytes::put_Java_u2((address)&v, x);574write_raw((void*)&v, 2);575}576577void DumpWriter::write_u4(u4 x) {578u4 v;579Bytes::put_Java_u4((address)&v, x);580write_raw((void*)&v, 4);581}582583void DumpWriter::write_u8(u8 x) {584u8 v;585Bytes::put_Java_u8((address)&v, x);586write_raw((void*)&v, 8);587}588589void DumpWriter::write_objectID(oop o) {590address a = (address)o;591#ifdef _LP64592write_u8((u8)a);593#else594write_u4((u4)a);595#endif596}597598void DumpWriter::write_symbolID(Symbol* s) {599address a = (address)((uintptr_t)s);600#ifdef _LP64601write_u8((u8)a);602#else603write_u4((u4)a);604#endif605}606607void DumpWriter::write_id(u4 x) {608#ifdef _LP64609write_u8((u8) x);610#else611write_u4(x);612#endif613}614615// We use java mirror as the class ID616void DumpWriter::write_classID(Klass* k) {617write_objectID(k->java_mirror());618}619620621622// Support class with a collection of functions used when dumping the heap623624class DumperSupport : AllStatic {625public:626627// write a header of the given type628static void write_header(DumpWriter* writer, hprofTag tag, u4 len);629630// returns hprof tag for the given type signature631static hprofTag sig2tag(Symbol* sig);632// returns hprof tag for the given basic type633static hprofTag type2tag(BasicType type);634635// returns the size of the instance of the given class636static u4 instance_size(Klass* k);637638// dump a jfloat639static void dump_float(DumpWriter* writer, jfloat f);640// dump a jdouble641static void dump_double(DumpWriter* writer, jdouble d);642// dumps the raw value of the given field643static void dump_field_value(DumpWriter* writer, char type, address addr);644// dumps static fields of the given class645static void dump_static_fields(DumpWriter* writer, Klass* k);646// dump the raw values of the instance fields of the given object647static void dump_instance_fields(DumpWriter* writer, oop o);648// dumps the definition of the instance fields for a given class649static void dump_instance_field_descriptors(DumpWriter* writer, Klass* k);650// creates HPROF_GC_INSTANCE_DUMP record for the given object651static void dump_instance(DumpWriter* writer, oop o);652// creates HPROF_GC_CLASS_DUMP record for the given class and each of its653// array classes654static void dump_class_and_array_classes(DumpWriter* writer, Klass* k);655// creates HPROF_GC_CLASS_DUMP record for a given primitive array656// class (and each multi-dimensional array class too)657static void dump_basic_type_array_class(DumpWriter* writer, Klass* k);658659// creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array660static void dump_object_array(DumpWriter* writer, objArrayOop array);661// creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array662static void dump_prim_array(DumpWriter* writer, typeArrayOop array);663// create HPROF_FRAME record for the given method and bci664static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci);665666// check if we need to truncate an array667static int calculate_array_max_length(DumpWriter* writer, arrayOop array, short header_size);668669// writes a HPROF_HEAP_DUMP_SEGMENT record670static void write_dump_header(DumpWriter* writer);671672// fixes up the length of the current dump record673static void write_current_dump_record_length(DumpWriter* writer);674675// fixes up the current dump record and writes HPROF_HEAP_DUMP_END record676static void end_of_dump(DumpWriter* writer);677};678679// write a header of the given type680void DumperSupport:: write_header(DumpWriter* writer, hprofTag tag, u4 len) {681writer->write_u1((u1)tag);682writer->write_u4(0); // current ticks683writer->write_u4(len);684}685686// returns hprof tag for the given type signature687hprofTag DumperSupport::sig2tag(Symbol* sig) {688switch (sig->byte_at(0)) {689case JVM_SIGNATURE_CLASS : return HPROF_NORMAL_OBJECT;690case JVM_SIGNATURE_ARRAY : return HPROF_NORMAL_OBJECT;691case JVM_SIGNATURE_BYTE : return HPROF_BYTE;692case JVM_SIGNATURE_CHAR : return HPROF_CHAR;693case JVM_SIGNATURE_FLOAT : return HPROF_FLOAT;694case JVM_SIGNATURE_DOUBLE : return HPROF_DOUBLE;695case JVM_SIGNATURE_INT : return HPROF_INT;696case JVM_SIGNATURE_LONG : return HPROF_LONG;697case JVM_SIGNATURE_SHORT : return HPROF_SHORT;698case JVM_SIGNATURE_BOOLEAN : return HPROF_BOOLEAN;699default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;700}701}702703hprofTag DumperSupport::type2tag(BasicType type) {704switch (type) {705case T_BYTE : return HPROF_BYTE;706case T_CHAR : return HPROF_CHAR;707case T_FLOAT : return HPROF_FLOAT;708case T_DOUBLE : return HPROF_DOUBLE;709case T_INT : return HPROF_INT;710case T_LONG : return HPROF_LONG;711case T_SHORT : return HPROF_SHORT;712case T_BOOLEAN : return HPROF_BOOLEAN;713default : ShouldNotReachHere(); /* to shut up compiler */ return HPROF_BYTE;714}715}716717// dump a jfloat718void DumperSupport::dump_float(DumpWriter* writer, jfloat f) {719if (g_isnan(f)) {720writer->write_u4(0x7fc00000); // collapsing NaNs721} else {722union {723int i;724float f;725} u;726u.f = (float)f;727writer->write_u4((u4)u.i);728}729}730731// dump a jdouble732void DumperSupport::dump_double(DumpWriter* writer, jdouble d) {733union {734jlong l;735double d;736} u;737if (g_isnan(d)) { // collapsing NaNs738u.l = (jlong)(0x7ff80000);739u.l = (u.l << 32);740} else {741u.d = (double)d;742}743writer->write_u8((u8)u.l);744}745746// dumps the raw value of the given field747void DumperSupport::dump_field_value(DumpWriter* writer, char type, address addr) {748switch (type) {749case JVM_SIGNATURE_CLASS :750case JVM_SIGNATURE_ARRAY : {751oop o;752if (UseCompressedOops) {753o = oopDesc::load_decode_heap_oop((narrowOop*)addr);754} else {755o = oopDesc::load_decode_heap_oop((oop*)addr);756}757758// reflection and sun.misc.Unsafe classes may have a reference to a759// Klass* so filter it out.760assert(o->is_oop_or_null(), "should always be an oop");761writer->write_objectID(o);762break;763}764case JVM_SIGNATURE_BYTE : {765jbyte* b = (jbyte*)addr;766writer->write_u1((u1)*b);767break;768}769case JVM_SIGNATURE_CHAR : {770jchar* c = (jchar*)addr;771writer->write_u2((u2)*c);772break;773}774case JVM_SIGNATURE_SHORT : {775jshort* s = (jshort*)addr;776writer->write_u2((u2)*s);777break;778}779case JVM_SIGNATURE_FLOAT : {780jfloat* f = (jfloat*)addr;781dump_float(writer, *f);782break;783}784case JVM_SIGNATURE_DOUBLE : {785jdouble* f = (jdouble*)addr;786dump_double(writer, *f);787break;788}789case JVM_SIGNATURE_INT : {790jint* i = (jint*)addr;791writer->write_u4((u4)*i);792break;793}794case JVM_SIGNATURE_LONG : {795jlong* l = (jlong*)addr;796writer->write_u8((u8)*l);797break;798}799case JVM_SIGNATURE_BOOLEAN : {800jboolean* b = (jboolean*)addr;801writer->write_u1((u1)*b);802break;803}804default : ShouldNotReachHere();805}806}807808// returns the size of the instance of the given class809u4 DumperSupport::instance_size(Klass* k) {810HandleMark hm;811instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);812813u4 size = 0;814815for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {816if (!fld.access_flags().is_static()) {817Symbol* sig = fld.signature();818switch (sig->byte_at(0)) {819case JVM_SIGNATURE_CLASS :820case JVM_SIGNATURE_ARRAY : size += oopSize; break;821822case JVM_SIGNATURE_BYTE :823case JVM_SIGNATURE_BOOLEAN : size += 1; break;824825case JVM_SIGNATURE_CHAR :826case JVM_SIGNATURE_SHORT : size += 2; break;827828case JVM_SIGNATURE_INT :829case JVM_SIGNATURE_FLOAT : size += 4; break;830831case JVM_SIGNATURE_LONG :832case JVM_SIGNATURE_DOUBLE : size += 8; break;833834default : ShouldNotReachHere();835}836}837}838return size;839}840841// dumps static fields of the given class842void DumperSupport::dump_static_fields(DumpWriter* writer, Klass* k) {843HandleMark hm;844instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);845846// pass 1 - count the static fields847u2 field_count = 0;848for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {849if (fldc.access_flags().is_static()) field_count++;850}851// Add in resolved_references which is referenced by the cpCache852// The resolved_references is an array per InstanceKlass holding the853// strings and other oops resolved from the constant pool.854oop resolved_references = ikh->constants()->resolved_references_or_null();855if (resolved_references != NULL) {856field_count++;857858// Add in the resolved_references of the used previous versions of the class859// in the case of RedefineClasses860InstanceKlass* prev = ikh->previous_versions();861while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {862field_count++;863prev = prev->previous_versions();864}865}866867// Also provide a pointer to the init_lock if present, so there aren't unreferenced int[0]868// arrays.869oop init_lock = ikh->init_lock();870if (init_lock != NULL) {871field_count++;872}873874writer->write_u2(field_count);875876// pass 2 - dump the field descriptors and raw values877for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {878if (fld.access_flags().is_static()) {879Symbol* sig = fld.signature();880881writer->write_symbolID(fld.name()); // name882writer->write_u1(sig2tag(sig)); // type883884// value885int offset = fld.offset();886address addr = (address)ikh->java_mirror() + offset;887888dump_field_value(writer, sig->byte_at(0), addr);889}890}891892// Add resolved_references for each class that has them893if (resolved_references != NULL) {894writer->write_symbolID(vmSymbols::resolved_references_name()); // name895writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type896writer->write_objectID(resolved_references);897898// Also write any previous versions899InstanceKlass* prev = ikh->previous_versions();900while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {901writer->write_symbolID(vmSymbols::resolved_references_name()); // name902writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type903writer->write_objectID(prev->constants()->resolved_references());904prev = prev->previous_versions();905}906}907908// Add init lock to the end if the class is not yet initialized909if (init_lock != NULL) {910writer->write_symbolID(vmSymbols::init_lock_name()); // name911writer->write_u1(sig2tag(vmSymbols::int_array_signature())); // type912writer->write_objectID(init_lock);913}914}915916// dump the raw values of the instance fields of the given object917void DumperSupport::dump_instance_fields(DumpWriter* writer, oop o) {918HandleMark hm;919instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), o->klass());920921for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {922if (!fld.access_flags().is_static()) {923Symbol* sig = fld.signature();924address addr = (address)o + fld.offset();925926dump_field_value(writer, sig->byte_at(0), addr);927}928}929}930931// dumps the definition of the instance fields for a given class932void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, Klass* k) {933HandleMark hm;934instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);935936// pass 1 - count the instance fields937u2 field_count = 0;938for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {939if (!fldc.access_flags().is_static()) field_count++;940}941942writer->write_u2(field_count);943944// pass 2 - dump the field descriptors945for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {946if (!fld.access_flags().is_static()) {947Symbol* sig = fld.signature();948949writer->write_symbolID(fld.name()); // name950writer->write_u1(sig2tag(sig)); // type951}952}953}954955// creates HPROF_GC_INSTANCE_DUMP record for the given object956void DumperSupport::dump_instance(DumpWriter* writer, oop o) {957Klass* k = o->klass();958959writer->write_u1(HPROF_GC_INSTANCE_DUMP);960writer->write_objectID(o);961writer->write_u4(STACK_TRACE_ID);962963// class ID964writer->write_classID(k);965966// number of bytes that follow967writer->write_u4(instance_size(k) );968969// field values970dump_instance_fields(writer, o);971}972973// creates HPROF_GC_CLASS_DUMP record for the given class and each of974// its array classes975void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, Klass* k) {976Klass* klass = k;977InstanceKlass* ik = InstanceKlass::cast(k);978979// We can safepoint and do a heap dump at a point where we have a Klass,980// but no java mirror class has been setup for it. So we need to check981// that the class is at least loaded, to avoid crash from a null mirror.982if (!ik->is_loaded()) {983return;984}985986writer->write_u1(HPROF_GC_CLASS_DUMP);987988// class ID989writer->write_classID(ik);990writer->write_u4(STACK_TRACE_ID);991992// super class ID993Klass* java_super = ik->java_super();994if (java_super == NULL) {995writer->write_objectID(oop(NULL));996} else {997writer->write_classID(java_super);998}9991000writer->write_objectID(ik->class_loader());1001writer->write_objectID(ik->signers());1002writer->write_objectID(ik->protection_domain());10031004// reserved1005writer->write_objectID(oop(NULL));1006writer->write_objectID(oop(NULL));10071008// instance size1009writer->write_u4(DumperSupport::instance_size(k));10101011// size of constant pool - ignored by HAT 1.11012writer->write_u2(0);10131014// number of static fields1015dump_static_fields(writer, k);10161017// description of instance fields1018dump_instance_field_descriptors(writer, k);10191020// array classes1021k = klass->array_klass_or_null();1022while (k != NULL) {1023Klass* klass = k;1024assert(klass->oop_is_objArray(), "not an ObjArrayKlass");10251026writer->write_u1(HPROF_GC_CLASS_DUMP);1027writer->write_classID(klass);1028writer->write_u4(STACK_TRACE_ID);10291030// super class of array classes is java.lang.Object1031java_super = klass->java_super();1032assert(java_super != NULL, "checking");1033writer->write_classID(java_super);10341035writer->write_objectID(ik->class_loader());1036writer->write_objectID(ik->signers());1037writer->write_objectID(ik->protection_domain());10381039writer->write_objectID(oop(NULL)); // reserved1040writer->write_objectID(oop(NULL));1041writer->write_u4(0); // instance size1042writer->write_u2(0); // constant pool1043writer->write_u2(0); // static fields1044writer->write_u2(0); // instance fields10451046// get the array class for the next rank1047k = klass->array_klass_or_null();1048}1049}10501051// creates HPROF_GC_CLASS_DUMP record for a given primitive array1052// class (and each multi-dimensional array class too)1053void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, Klass* k) {1054// array classes1055while (k != NULL) {1056Klass* klass = k;10571058writer->write_u1(HPROF_GC_CLASS_DUMP);1059writer->write_classID(klass);1060writer->write_u4(STACK_TRACE_ID);10611062// super class of array classes is java.lang.Object1063Klass* java_super = klass->java_super();1064assert(java_super != NULL, "checking");1065writer->write_classID(java_super);10661067writer->write_objectID(oop(NULL)); // loader1068writer->write_objectID(oop(NULL)); // signers1069writer->write_objectID(oop(NULL)); // protection domain10701071writer->write_objectID(oop(NULL)); // reserved1072writer->write_objectID(oop(NULL));1073writer->write_u4(0); // instance size1074writer->write_u2(0); // constant pool1075writer->write_u2(0); // static fields1076writer->write_u2(0); // instance fields10771078// get the array class for the next rank1079k = klass->array_klass_or_null();1080}1081}10821083// Hprof uses an u4 as record length field,1084// which means we need to truncate arrays that are too long.1085int DumperSupport::calculate_array_max_length(DumpWriter* writer, arrayOop array, short header_size) {1086BasicType type = ArrayKlass::cast(array->klass())->element_type();1087assert(type >= T_BOOLEAN && type <= T_OBJECT, "invalid array element type");10881089int length = array->length();10901091int type_size;1092if (type == T_OBJECT) {1093type_size = sizeof(address);1094} else {1095type_size = type2aelembytes(type);1096}10971098size_t length_in_bytes = (size_t)length * type_size;10991100// Create a new record if the current record is non-empty and the array can't fit.1101julong current_record_length = writer->current_record_length();1102if (current_record_length > 0 &&1103(current_record_length + header_size + length_in_bytes) > max_juint) {1104write_current_dump_record_length(writer);1105write_dump_header(writer);11061107// We now have an empty record.1108current_record_length = 0;1109}11101111// Calculate max bytes we can use.1112uint max_bytes = max_juint - (header_size + current_record_length);11131114// Array too long for the record?1115// Calculate max length and return it.1116if (length_in_bytes > max_bytes) {1117length = max_bytes / type_size;1118length_in_bytes = (size_t)length * type_size;11191120warning("cannot dump array of type %s[] with length %d; truncating to length %d",1121type2name_tab[type], array->length(), length);1122}1123return length;1124}11251126// creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array1127void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) {1128// sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID) + sizeof(classID)1129short header_size = 1 + 2 * 4 + 2 * sizeof(address);11301131int length = calculate_array_max_length(writer, array, header_size);11321133writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP);1134writer->write_objectID(array);1135writer->write_u4(STACK_TRACE_ID);1136writer->write_u4(length);113711381139// array class ID1140writer->write_classID(array->klass());11411142// [id]* elements1143for (int index = 0; index < length; index++) {1144oop o = array->obj_at(index);1145writer->write_objectID(o);1146}1147}11481149#define WRITE_ARRAY(Array, Type, Size, Length) \1150for (int i = 0; i < Length; i++) { writer->write_##Size((Size)array->Type##_at(i)); }11511152// creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array1153void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {1154BasicType type = TypeArrayKlass::cast(array->klass())->element_type();11551156// 2 * sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID)1157short header_size = 2 * 1 + 2 * 4 + sizeof(address);11581159int length = calculate_array_max_length(writer, array, header_size);1160int type_size = type2aelembytes(type);1161u4 length_in_bytes = (u4)length * type_size;11621163writer->write_u1(HPROF_GC_PRIM_ARRAY_DUMP);1164writer->write_objectID(array);1165writer->write_u4(STACK_TRACE_ID);1166writer->write_u4(length);1167writer->write_u1(type2tag(type));11681169// nothing to copy1170if (length == 0) {1171return;1172}11731174// If the byte ordering is big endian then we can copy most types directly11751176switch (type) {1177case T_INT : {1178if (Bytes::is_Java_byte_ordering_different()) {1179WRITE_ARRAY(array, int, u4, length);1180} else {1181writer->write_raw((void*)(array->int_at_addr(0)), length_in_bytes);1182}1183break;1184}1185case T_BYTE : {1186writer->write_raw((void*)(array->byte_at_addr(0)), length_in_bytes);1187break;1188}1189case T_CHAR : {1190if (Bytes::is_Java_byte_ordering_different()) {1191WRITE_ARRAY(array, char, u2, length);1192} else {1193writer->write_raw((void*)(array->char_at_addr(0)), length_in_bytes);1194}1195break;1196}1197case T_SHORT : {1198if (Bytes::is_Java_byte_ordering_different()) {1199WRITE_ARRAY(array, short, u2, length);1200} else {1201writer->write_raw((void*)(array->short_at_addr(0)), length_in_bytes);1202}1203break;1204}1205case T_BOOLEAN : {1206if (Bytes::is_Java_byte_ordering_different()) {1207WRITE_ARRAY(array, bool, u1, length);1208} else {1209writer->write_raw((void*)(array->bool_at_addr(0)), length_in_bytes);1210}1211break;1212}1213case T_LONG : {1214if (Bytes::is_Java_byte_ordering_different()) {1215WRITE_ARRAY(array, long, u8, length);1216} else {1217writer->write_raw((void*)(array->long_at_addr(0)), length_in_bytes);1218}1219break;1220}12211222// handle float/doubles in a special value to ensure than NaNs are1223// written correctly. TO DO: Check if we can avoid this on processors that1224// use IEEE 754.12251226case T_FLOAT : {1227for (int i = 0; i < length; i++) {1228dump_float(writer, array->float_at(i));1229}1230break;1231}1232case T_DOUBLE : {1233for (int i = 0; i < length; i++) {1234dump_double(writer, array->double_at(i));1235}1236break;1237}1238default : ShouldNotReachHere();1239}1240}12411242// create a HPROF_FRAME record of the given Method* and bci1243void DumperSupport::dump_stack_frame(DumpWriter* writer,1244int frame_serial_num,1245int class_serial_num,1246Method* m,1247int bci) {1248int line_number;1249if (m->is_native()) {1250line_number = -3; // native frame1251} else {1252line_number = m->line_number_from_bci(bci);1253}12541255write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4));1256writer->write_id(frame_serial_num); // frame serial number1257writer->write_symbolID(m->name()); // method's name1258writer->write_symbolID(m->signature()); // method's signature12591260assert(m->method_holder()->oop_is_instance(), "not InstanceKlass");1261writer->write_symbolID(m->method_holder()->source_file_name()); // source file name1262writer->write_u4(class_serial_num); // class serial number1263writer->write_u4((u4) line_number); // line number1264}126512661267// Support class used to generate HPROF_UTF8 records from the entries in the1268// SymbolTable.12691270class SymbolTableDumper : public SymbolClosure {1271private:1272DumpWriter* _writer;1273DumpWriter* writer() const { return _writer; }1274public:1275SymbolTableDumper(DumpWriter* writer) { _writer = writer; }1276void do_symbol(Symbol** p);1277};12781279void SymbolTableDumper::do_symbol(Symbol** p) {1280ResourceMark rm;1281Symbol* sym = load_symbol(p);1282int len = sym->utf8_length();1283if (len > 0) {1284char* s = sym->as_utf8();1285DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len);1286writer()->write_symbolID(sym);1287writer()->write_raw(s, len);1288}1289}12901291// Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records12921293class JNILocalsDumper : public OopClosure {1294private:1295DumpWriter* _writer;1296u4 _thread_serial_num;1297int _frame_num;1298DumpWriter* writer() const { return _writer; }1299public:1300JNILocalsDumper(DumpWriter* writer, u4 thread_serial_num) {1301_writer = writer;1302_thread_serial_num = thread_serial_num;1303_frame_num = -1; // default - empty stack1304}1305void set_frame_number(int n) { _frame_num = n; }1306void do_oop(oop* obj_p);1307void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }1308};130913101311void JNILocalsDumper::do_oop(oop* obj_p) {1312// ignore null or deleted handles1313oop o = *obj_p;1314if (o != NULL && o != JNIHandles::deleted_handle()) {1315writer()->write_u1(HPROF_GC_ROOT_JNI_LOCAL);1316writer()->write_objectID(o);1317writer()->write_u4(_thread_serial_num);1318writer()->write_u4((u4)_frame_num);1319}1320}132113221323// Support class used to generate HPROF_GC_ROOT_JNI_GLOBAL records13241325class JNIGlobalsDumper : public OopClosure {1326private:1327DumpWriter* _writer;1328DumpWriter* writer() const { return _writer; }13291330public:1331JNIGlobalsDumper(DumpWriter* writer) {1332_writer = writer;1333}1334void do_oop(oop* obj_p);1335void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }1336};13371338void JNIGlobalsDumper::do_oop(oop* obj_p) {1339oop o = *obj_p;13401341// ignore these1342if (o == NULL || o == JNIHandles::deleted_handle()) return;13431344// we ignore global ref to symbols and other internal objects1345if (o->is_instance() || o->is_objArray() || o->is_typeArray()) {1346writer()->write_u1(HPROF_GC_ROOT_JNI_GLOBAL);1347writer()->write_objectID(o);1348writer()->write_objectID((oopDesc*)obj_p); // global ref ID1349}1350};135113521353// Support class used to generate HPROF_GC_ROOT_MONITOR_USED records13541355class MonitorUsedDumper : public OopClosure {1356private:1357DumpWriter* _writer;1358DumpWriter* writer() const { return _writer; }1359public:1360MonitorUsedDumper(DumpWriter* writer) {1361_writer = writer;1362}1363void do_oop(oop* obj_p) {1364writer()->write_u1(HPROF_GC_ROOT_MONITOR_USED);1365writer()->write_objectID(*obj_p);1366}1367void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }1368};136913701371// Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records13721373class StickyClassDumper : public KlassClosure {1374private:1375DumpWriter* _writer;1376DumpWriter* writer() const { return _writer; }1377public:1378StickyClassDumper(DumpWriter* writer) {1379_writer = writer;1380}1381void do_klass(Klass* k) {1382if (k->oop_is_instance()) {1383InstanceKlass* ik = InstanceKlass::cast(k);1384writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS);1385writer()->write_classID(ik);1386}1387}1388};138913901391class VM_HeapDumper;13921393// Support class using when iterating over the heap.13941395class HeapObjectDumper : public ObjectClosure {1396private:1397VM_HeapDumper* _dumper;1398DumpWriter* _writer;13991400VM_HeapDumper* dumper() { return _dumper; }1401DumpWriter* writer() { return _writer; }14021403// used to indicate that a record has been writen1404void mark_end_of_record();14051406public:1407HeapObjectDumper(VM_HeapDumper* dumper, DumpWriter* writer) {1408_dumper = dumper;1409_writer = writer;1410}14111412// called for each object in the heap1413void do_object(oop o);1414};14151416void HeapObjectDumper::do_object(oop o) {1417// hide the sentinel for deleted handles1418if (o == JNIHandles::deleted_handle()) return;14191420// skip classes as these emitted as HPROF_GC_CLASS_DUMP records1421if (o->klass() == SystemDictionary::Class_klass()) {1422if (!java_lang_Class::is_primitive(o)) {1423return;1424}1425}14261427if (o->is_instance()) {1428// create a HPROF_GC_INSTANCE record for each object1429DumperSupport::dump_instance(writer(), o);1430mark_end_of_record();1431} else if (o->is_objArray()) {1432// create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array1433DumperSupport::dump_object_array(writer(), objArrayOop(o));1434mark_end_of_record();1435} else if (o->is_typeArray()) {1436// create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array1437DumperSupport::dump_prim_array(writer(), typeArrayOop(o));1438mark_end_of_record();1439}1440}14411442// The VM operation that performs the heap dump1443class VM_HeapDumper : public VM_GC_Operation {1444private:1445static VM_HeapDumper* _global_dumper;1446static DumpWriter* _global_writer;1447DumpWriter* _local_writer;1448JavaThread* _oome_thread;1449Method* _oome_constructor;1450bool _gc_before_heap_dump;1451GrowableArray<Klass*>* _klass_map;1452ThreadStackTrace** _stack_traces;1453int _num_threads;14541455// accessors and setters1456static VM_HeapDumper* dumper() { assert(_global_dumper != NULL, "Error"); return _global_dumper; }1457static DumpWriter* writer() { assert(_global_writer != NULL, "Error"); return _global_writer; }1458void set_global_dumper() {1459assert(_global_dumper == NULL, "Error");1460_global_dumper = this;1461}1462void set_global_writer() {1463assert(_global_writer == NULL, "Error");1464_global_writer = _local_writer;1465}1466void clear_global_dumper() { _global_dumper = NULL; }1467void clear_global_writer() { _global_writer = NULL; }14681469bool skip_operation() const;14701471// writes a HPROF_LOAD_CLASS record1472static void do_load_class(Klass* k);14731474// writes a HPROF_GC_CLASS_DUMP record for the given class1475// (and each array class too)1476static void do_class_dump(Klass* k);14771478// writes a HPROF_GC_CLASS_DUMP records for a given basic type1479// array (and each multi-dimensional array too)1480static void do_basic_type_array_class_dump(Klass* k);14811482// HPROF_GC_ROOT_THREAD_OBJ records1483int do_thread(JavaThread* thread, u4 thread_serial_num);1484void do_threads();14851486void add_class_serial_number(Klass* k, int serial_num) {1487_klass_map->at_put_grow(serial_num, k);1488}14891490// HPROF_TRACE and HPROF_FRAME records1491void dump_stack_traces();14921493public:1494VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome) :1495VM_GC_Operation(0 /* total collections, dummy, ignored */,1496GCCause::_heap_dump /* GC Cause */,14970 /* total full collections, dummy, ignored */,1498gc_before_heap_dump) {1499_local_writer = writer;1500_gc_before_heap_dump = gc_before_heap_dump;1501_klass_map = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);1502_stack_traces = NULL;1503_num_threads = 0;1504if (oome) {1505assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread");1506// get OutOfMemoryError zero-parameter constructor1507InstanceKlass* oome_ik = InstanceKlass::cast(SystemDictionary::OutOfMemoryError_klass());1508_oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(),1509vmSymbols::void_method_signature());1510// get thread throwing OOME when generating the heap dump at OOME1511_oome_thread = JavaThread::current();1512} else {1513_oome_thread = NULL;1514_oome_constructor = NULL;1515}1516}1517~VM_HeapDumper() {1518if (_stack_traces != NULL) {1519for (int i=0; i < _num_threads; i++) {1520delete _stack_traces[i];1521}1522FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces, mtInternal);1523}1524delete _klass_map;1525}15261527VMOp_Type type() const { return VMOp_HeapDumper; }1528// used to mark sub-record boundary1529void check_segment_length();1530void doit();1531};15321533VM_HeapDumper* VM_HeapDumper::_global_dumper = NULL;1534DumpWriter* VM_HeapDumper::_global_writer = NULL;15351536bool VM_HeapDumper::skip_operation() const {1537return false;1538}15391540// writes a HPROF_HEAP_DUMP_SEGMENT record1541void DumperSupport::write_dump_header(DumpWriter* writer) {1542if (writer->is_open()) {1543writer->write_u1(HPROF_HEAP_DUMP_SEGMENT);1544writer->write_u4(0); // current ticks15451546// record the starting position for the dump (its length will be fixed up later)1547writer->set_dump_start(writer->current_offset());1548writer->write_u4(0);1549}1550}15511552// fixes up the length of the current dump record1553void DumperSupport::write_current_dump_record_length(DumpWriter* writer) {1554if (writer->is_open()) {1555julong dump_end = writer->bytes_written() + writer->bytes_unwritten();1556julong dump_len = writer->current_record_length();15571558// record length must fit in a u41559if (dump_len > max_juint) {1560warning("record is too large");1561}15621563// seek to the dump start and fix-up the length1564assert(writer->dump_start() >= 0, "no dump start recorded");1565writer->seek_to_offset(writer->dump_start());1566writer->write_u4((u4)dump_len);15671568// adjust the total size written to keep the bytes written correct.1569writer->adjust_bytes_written(-((jlong) sizeof(u4)));15701571// seek to dump end so we can continue1572writer->seek_to_offset(dump_end);15731574// no current dump record1575writer->set_dump_start((jlong)-1);1576}1577}15781579// used on a sub-record boundary to check if we need to start a1580// new segment.1581void VM_HeapDumper::check_segment_length() {1582if (writer()->is_open()) {1583julong dump_len = writer()->current_record_length();15841585if (dump_len > 2UL*G) {1586DumperSupport::write_current_dump_record_length(writer());1587DumperSupport::write_dump_header(writer());1588}1589}1590}15911592// fixes up the current dump record and writes HPROF_HEAP_DUMP_END record1593void DumperSupport::end_of_dump(DumpWriter* writer) {1594if (writer->is_open()) {1595write_current_dump_record_length(writer);15961597writer->write_u1(HPROF_HEAP_DUMP_END);1598writer->write_u4(0);1599writer->write_u4(0);1600}1601}16021603// marks sub-record boundary1604void HeapObjectDumper::mark_end_of_record() {1605dumper()->check_segment_length();1606}16071608// writes a HPROF_LOAD_CLASS record for the class (and each of its1609// array classes)1610void VM_HeapDumper::do_load_class(Klass* k) {1611static u4 class_serial_num = 0;16121613// len of HPROF_LOAD_CLASS record1614u4 remaining = 2*oopSize + 2*sizeof(u4);16151616// write a HPROF_LOAD_CLASS for the class and each array class1617do {1618DumperSupport::write_header(writer(), HPROF_LOAD_CLASS, remaining);16191620// class serial number is just a number1621writer()->write_u4(++class_serial_num);16221623// class ID1624Klass* klass = k;1625writer()->write_classID(klass);16261627// add the Klass* and class serial number pair1628dumper()->add_class_serial_number(klass, class_serial_num);16291630writer()->write_u4(STACK_TRACE_ID);16311632// class name ID1633Symbol* name = klass->name();1634writer()->write_symbolID(name);16351636// write a LOAD_CLASS record for the array type (if it exists)1637k = klass->array_klass_or_null();1638} while (k != NULL);1639}16401641// writes a HPROF_GC_CLASS_DUMP record for the given class1642void VM_HeapDumper::do_class_dump(Klass* k) {1643if (k->oop_is_instance()) {1644DumperSupport::dump_class_and_array_classes(writer(), k);1645}1646}16471648// writes a HPROF_GC_CLASS_DUMP records for a given basic type1649// array (and each multi-dimensional array too)1650void VM_HeapDumper::do_basic_type_array_class_dump(Klass* k) {1651DumperSupport::dump_basic_type_array_class(writer(), k);1652}16531654// Walk the stack of the given thread.1655// Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local1656// Dumps a HPROF_GC_ROOT_JNI_LOCAL record for each JNI local1657//1658// It returns the number of Java frames in this thread stack1659int VM_HeapDumper::do_thread(JavaThread* java_thread, u4 thread_serial_num) {1660JNILocalsDumper blk(writer(), thread_serial_num);16611662oop threadObj = java_thread->threadObj();1663assert(threadObj != NULL, "sanity check");16641665int stack_depth = 0;1666if (java_thread->has_last_Java_frame()) {16671668// vframes are resource allocated1669Thread* current_thread = Thread::current();1670ResourceMark rm(current_thread);1671HandleMark hm(current_thread);16721673RegisterMap reg_map(java_thread);1674frame f = java_thread->last_frame();1675vframe* vf = vframe::new_vframe(&f, ®_map, java_thread);1676frame* last_entry_frame = NULL;1677int extra_frames = 0;16781679if (java_thread == _oome_thread && _oome_constructor != NULL) {1680extra_frames++;1681}1682while (vf != NULL) {1683blk.set_frame_number(stack_depth);1684if (vf->is_java_frame()) {16851686// java frame (interpreted, compiled, ...)1687javaVFrame *jvf = javaVFrame::cast(vf);1688if (!(jvf->method()->is_native())) {1689StackValueCollection* locals = jvf->locals();1690for (int slot=0; slot<locals->size(); slot++) {1691if (locals->at(slot)->type() == T_OBJECT) {1692oop o = locals->obj_at(slot)();16931694if (o != NULL) {1695writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME);1696writer()->write_objectID(o);1697writer()->write_u4(thread_serial_num);1698writer()->write_u4((u4) (stack_depth + extra_frames));1699}1700}1701}1702} else {1703// native frame1704if (stack_depth == 0) {1705// JNI locals for the top frame.1706java_thread->active_handles()->oops_do(&blk);1707} else {1708if (last_entry_frame != NULL) {1709// JNI locals for the entry frame1710assert(last_entry_frame->is_entry_frame(), "checking");1711last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(&blk);1712}1713}1714}1715// increment only for Java frames1716stack_depth++;1717last_entry_frame = NULL;17181719} else {1720// externalVFrame - if it's an entry frame then report any JNI locals1721// as roots when we find the corresponding native javaVFrame1722frame* fr = vf->frame_pointer();1723assert(fr != NULL, "sanity check");1724if (fr->is_entry_frame()) {1725last_entry_frame = fr;1726}1727}1728vf = vf->sender();1729}1730} else {1731// no last java frame but there may be JNI locals1732java_thread->active_handles()->oops_do(&blk);1733}1734return stack_depth;1735}173617371738// write a HPROF_GC_ROOT_THREAD_OBJ record for each java thread. Then walk1739// the stack so that locals and JNI locals are dumped.1740void VM_HeapDumper::do_threads() {1741for (int i=0; i < _num_threads; i++) {1742JavaThread* thread = _stack_traces[i]->thread();1743oop threadObj = thread->threadObj();1744u4 thread_serial_num = i+1;1745u4 stack_serial_num = thread_serial_num + STACK_TRACE_ID;1746writer()->write_u1(HPROF_GC_ROOT_THREAD_OBJ);1747writer()->write_objectID(threadObj);1748writer()->write_u4(thread_serial_num); // thread number1749writer()->write_u4(stack_serial_num); // stack trace serial number1750int num_frames = do_thread(thread, thread_serial_num);1751assert(num_frames == _stack_traces[i]->get_stack_depth(),1752"total number of Java frames not matched");1753}1754}175517561757// The VM operation that dumps the heap. The dump consists of the following1758// records:1759//1760// HPROF_HEADER1761// [HPROF_UTF8]*1762// [HPROF_LOAD_CLASS]*1763// [[HPROF_FRAME]*|HPROF_TRACE]*1764// [HPROF_GC_CLASS_DUMP]*1765// [HPROF_HEAP_DUMP_SEGMENT]*1766// HPROF_HEAP_DUMP_END1767//1768// The HPROF_TRACE records represent the stack traces where the heap dump1769// is generated and a "dummy trace" record which does not include1770// any frames. The dummy trace record is used to be referenced as the1771// unknown object alloc site.1772//1773// Each HPROF_HEAP_DUMP_SEGMENT record has a length followed by sub-records.1774// To allow the heap dump be generated in a single pass we remember the position1775// of the dump length and fix it up after all sub-records have been written.1776// To generate the sub-records we iterate over the heap, writing1777// HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP1778// records as we go. Once that is done we write records for some of the GC1779// roots.17801781void VM_HeapDumper::doit() {17821783HandleMark hm;1784CollectedHeap* ch = Universe::heap();17851786ch->ensure_parsability(false); // must happen, even if collection does1787// not happen (e.g. due to GC_locker)17881789if (_gc_before_heap_dump) {1790if (GC_locker::is_active()) {1791warning("GC locker is held; pre-heapdump GC was skipped");1792} else {1793ch->collect_as_vm_thread(GCCause::_heap_dump);1794}1795}17961797// At this point we should be the only dumper active, so1798// the following should be safe.1799set_global_dumper();1800set_global_writer();18011802// Write the file header - we always use 1.0.21803size_t used = ch->used();1804const char* header = "JAVA PROFILE 1.0.2";18051806// header is few bytes long - no chance to overflow int1807writer()->write_raw((void*)header, (int)strlen(header));1808writer()->write_u1(0); // terminator1809writer()->write_u4(oopSize);1810writer()->write_u8(os::javaTimeMillis());18111812// HPROF_UTF8 records1813SymbolTableDumper sym_dumper(writer());1814SymbolTable::symbols_do(&sym_dumper);18151816// write HPROF_LOAD_CLASS records1817ClassLoaderDataGraph::classes_do(&do_load_class);1818Universe::basic_type_classes_do(&do_load_class);18191820// write HPROF_FRAME and HPROF_TRACE records1821// this must be called after _klass_map is built when iterating the classes above.1822dump_stack_traces();18231824// write HPROF_HEAP_DUMP_SEGMENT1825DumperSupport::write_dump_header(writer());18261827// Writes HPROF_GC_CLASS_DUMP records1828ClassLoaderDataGraph::classes_do(&do_class_dump);1829Universe::basic_type_classes_do(&do_basic_type_array_class_dump);1830check_segment_length();18311832// writes HPROF_GC_INSTANCE_DUMP records.1833// After each sub-record is written check_segment_length will be invoked1834// to check if the current segment exceeds a threshold. If so, a new1835// segment is started.1836// The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk1837// of the heap dump.1838HeapObjectDumper obj_dumper(this, writer());1839Universe::heap()->safe_object_iterate(&obj_dumper);18401841// HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals1842do_threads();1843check_segment_length();18441845// HPROF_GC_ROOT_MONITOR_USED1846MonitorUsedDumper mon_dumper(writer());1847ObjectSynchronizer::oops_do(&mon_dumper);1848check_segment_length();18491850// HPROF_GC_ROOT_JNI_GLOBAL1851JNIGlobalsDumper jni_dumper(writer());1852JNIHandles::oops_do(&jni_dumper);1853Universe::oops_do(&jni_dumper); // technically not jni roots, but global roots1854// for things like preallocated throwable backtraces1855check_segment_length();18561857// HPROF_GC_ROOT_STICKY_CLASS1858StickyClassDumper class_dumper(writer());1859SystemDictionary::always_strong_classes_do(&class_dumper);18601861// fixes up the length of the dump record and writes the HPROF_HEAP_DUMP_END record.1862DumperSupport::end_of_dump(writer());18631864// Now we clear the global variables, so that a future dumper might run.1865clear_global_dumper();1866clear_global_writer();1867}18681869void VM_HeapDumper::dump_stack_traces() {1870// write a HPROF_TRACE record without any frames to be referenced as object alloc sites1871DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));1872writer()->write_u4((u4) STACK_TRACE_ID);1873writer()->write_u4(0); // thread number1874writer()->write_u4(0); // frame count18751876_stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads(), mtInternal);1877int frame_serial_num = 0;1878for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {1879oop threadObj = thread->threadObj();1880if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {1881// dump thread stack trace1882ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false);1883stack_trace->dump_stack_at_safepoint(-1);1884_stack_traces[_num_threads++] = stack_trace;18851886// write HPROF_FRAME records for this thread's stack trace1887int depth = stack_trace->get_stack_depth();1888int thread_frame_start = frame_serial_num;1889int extra_frames = 0;1890// write fake frame that makes it look like the thread, which caused OOME,1891// is in the OutOfMemoryError zero-parameter constructor1892if (thread == _oome_thread && _oome_constructor != NULL) {1893int oome_serial_num = _klass_map->find(_oome_constructor->method_holder());1894// the class serial number starts from 11895assert(oome_serial_num > 0, "OutOfMemoryError class not found");1896DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, oome_serial_num,1897_oome_constructor, 0);1898extra_frames++;1899}1900for (int j=0; j < depth; j++) {1901StackFrameInfo* frame = stack_trace->stack_frame_at(j);1902Method* m = frame->method();1903int class_serial_num = _klass_map->find(m->method_holder());1904// the class serial number starts from 11905assert(class_serial_num > 0, "class not found");1906DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci());1907}1908depth += extra_frames;19091910// write HPROF_TRACE record for one thread1911DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4) + depth*oopSize);1912int stack_serial_num = _num_threads + STACK_TRACE_ID;1913writer()->write_u4(stack_serial_num); // stack trace serial number1914writer()->write_u4((u4) _num_threads); // thread serial number1915writer()->write_u4(depth); // frame count1916for (int j=1; j <= depth; j++) {1917writer()->write_id(thread_frame_start + j);1918}1919}1920}1921}19221923// dump the heap to given path.1924PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL1925int HeapDumper::dump(const char* path) {1926assert(path != NULL && strlen(path) > 0, "path missing");19271928// print message in interactive case1929if (print_to_tty()) {1930tty->print_cr("Dumping heap to %s ...", path);1931timer()->start();1932}19331934// create the dump writer. If the file can be opened then bail1935DumpWriter writer(path);1936if (!writer.is_open()) {1937set_error(writer.error());1938if (print_to_tty()) {1939tty->print_cr("Unable to create %s: %s", path,1940(error() != NULL) ? error() : "reason unknown");1941}1942return -1;1943}19441945// generate the dump1946VM_HeapDumper dumper(&writer, _gc_before_heap_dump, _oome);1947if (Thread::current()->is_VM_thread()) {1948assert(SafepointSynchronize::is_at_safepoint(), "Expected to be called at a safepoint");1949dumper.doit();1950} else {1951VMThread::execute(&dumper);1952}19531954// close dump file and record any error that the writer may have encountered1955writer.close();1956set_error(writer.error());19571958// print message in interactive case1959if (print_to_tty()) {1960timer()->stop();1961if (error() == NULL) {1962tty->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",1963writer.bytes_written(), timer()->seconds());1964} else {1965tty->print_cr("Dump file is incomplete: %s", writer.error());1966}1967}19681969return (writer.error() == NULL) ? 0 : -1;1970}19711972// stop timer (if still active), and free any error string we might be holding1973HeapDumper::~HeapDumper() {1974if (timer()->is_active()) {1975timer()->stop();1976}1977set_error(NULL);1978}197919801981// returns the error string (resource allocated), or NULL1982char* HeapDumper::error_as_C_string() const {1983if (error() != NULL) {1984char* str = NEW_RESOURCE_ARRAY(char, strlen(error())+1);1985strcpy(str, error());1986return str;1987} else {1988return NULL;1989}1990}19911992// set the error string1993void HeapDumper::set_error(char* error) {1994if (_error != NULL) {1995os::free(_error);1996}1997if (error == NULL) {1998_error = NULL;1999} else {2000_error = os::strdup(error);2001assert(_error != NULL, "allocation failure");2002}2003}20042005// Called by out-of-memory error reporting by a single Java thread2006// outside of a JVM safepoint2007void HeapDumper::dump_heap_from_oome() {2008HeapDumper::dump_heap(true);2009}20102011// Called by error reporting by a single Java thread outside of a JVM safepoint,2012// or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various2013// callers are strictly serialized and guaranteed not to interfere below. For more2014// general use, however, this method will need modification to prevent2015// inteference when updating the static variables base_path and dump_file_seq below.2016void HeapDumper::dump_heap() {2017HeapDumper::dump_heap(false);2018}20192020void HeapDumper::dump_heap(bool oome) {2021static char base_path[JVM_MAXPATHLEN] = {'\0'};2022static uint dump_file_seq = 0;2023char* my_path;2024const int max_digit_chars = 20;20252026const char* dump_file_name = "java_pid";2027const char* dump_file_ext = ".hprof";20282029// The dump file defaults to java_pid<pid>.hprof in the current working2030// directory. HeapDumpPath=<file> can be used to specify an alternative2031// dump file name or a directory where dump file is created.2032if (dump_file_seq == 0) { // first time in, we initialize base_path2033// Calculate potentially longest base path and check if we have enough2034// allocated statically.2035const size_t total_length =2036(HeapDumpPath == NULL ? 0 : strlen(HeapDumpPath)) +2037strlen(os::file_separator()) + max_digit_chars +2038strlen(dump_file_name) + strlen(dump_file_ext) + 1;2039if (total_length > sizeof(base_path)) {2040warning("Cannot create heap dump file. HeapDumpPath is too long.");2041return;2042}20432044bool use_default_filename = true;2045if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {2046// HeapDumpPath=<file> not specified2047} else {2048strncpy(base_path, HeapDumpPath, sizeof(base_path));2049// check if the path is a directory (must exist)2050DIR* dir = os::opendir(base_path);2051if (dir == NULL) {2052use_default_filename = false;2053} else {2054// HeapDumpPath specified a directory. We append a file separator2055// (if needed).2056os::closedir(dir);2057size_t fs_len = strlen(os::file_separator());2058if (strlen(base_path) >= fs_len) {2059char* end = base_path;2060end += (strlen(base_path) - fs_len);2061if (strcmp(end, os::file_separator()) != 0) {2062strcat(base_path, os::file_separator());2063}2064}2065}2066}2067// If HeapDumpPath wasn't a file name then we append the default name2068if (use_default_filename) {2069const size_t dlen = strlen(base_path); // if heap dump dir specified2070jio_snprintf(&base_path[dlen], sizeof(base_path)-dlen, "%s%d%s",2071dump_file_name, os::current_process_id(), dump_file_ext);2072}2073const size_t len = strlen(base_path) + 1;2074my_path = (char*)os::malloc(len, mtInternal);2075if (my_path == NULL) {2076warning("Cannot create heap dump file. Out of system memory.");2077return;2078}2079strncpy(my_path, base_path, len);2080} else {2081// Append a sequence number id for dumps following the first2082const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \02083my_path = (char*)os::malloc(len, mtInternal);2084if (my_path == NULL) {2085warning("Cannot create heap dump file. Out of system memory.");2086return;2087}2088jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq);2089}2090dump_file_seq++; // increment seq number for next time we dump20912092HeapDumper dumper(false /* no GC before heap dump */,2093true /* send to tty */,2094oome /* pass along out-of-memory-error flag */);2095dumper.dump(my_path);2096os::free(my_path);2097}209820992100