Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/services/heapDumper.cpp
32285 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#if INCLUDE_ALL_GCS759if (UseShenandoahGC) {760o = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(o);761}762#endif763764// reflection and sun.misc.Unsafe classes may have a reference to a765// Klass* so filter it out.766assert(o->is_oop_or_null(), "should always be an oop");767writer->write_objectID(o);768break;769}770case JVM_SIGNATURE_BYTE : {771jbyte* b = (jbyte*)addr;772writer->write_u1((u1)*b);773break;774}775case JVM_SIGNATURE_CHAR : {776jchar* c = (jchar*)addr;777writer->write_u2((u2)*c);778break;779}780case JVM_SIGNATURE_SHORT : {781jshort* s = (jshort*)addr;782writer->write_u2((u2)*s);783break;784}785case JVM_SIGNATURE_FLOAT : {786jfloat* f = (jfloat*)addr;787dump_float(writer, *f);788break;789}790case JVM_SIGNATURE_DOUBLE : {791jdouble* f = (jdouble*)addr;792dump_double(writer, *f);793break;794}795case JVM_SIGNATURE_INT : {796jint* i = (jint*)addr;797writer->write_u4((u4)*i);798break;799}800case JVM_SIGNATURE_LONG : {801jlong* l = (jlong*)addr;802writer->write_u8((u8)*l);803break;804}805case JVM_SIGNATURE_BOOLEAN : {806jboolean* b = (jboolean*)addr;807writer->write_u1((u1)*b);808break;809}810default : ShouldNotReachHere();811}812}813814// returns the size of the instance of the given class815u4 DumperSupport::instance_size(Klass* k) {816HandleMark hm;817instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);818819u4 size = 0;820821for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {822if (!fld.access_flags().is_static()) {823Symbol* sig = fld.signature();824switch (sig->byte_at(0)) {825case JVM_SIGNATURE_CLASS :826case JVM_SIGNATURE_ARRAY : size += oopSize; break;827828case JVM_SIGNATURE_BYTE :829case JVM_SIGNATURE_BOOLEAN : size += 1; break;830831case JVM_SIGNATURE_CHAR :832case JVM_SIGNATURE_SHORT : size += 2; break;833834case JVM_SIGNATURE_INT :835case JVM_SIGNATURE_FLOAT : size += 4; break;836837case JVM_SIGNATURE_LONG :838case JVM_SIGNATURE_DOUBLE : size += 8; break;839840default : ShouldNotReachHere();841}842}843}844return size;845}846847// dumps static fields of the given class848void DumperSupport::dump_static_fields(DumpWriter* writer, Klass* k) {849HandleMark hm;850instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);851852// pass 1 - count the static fields853u2 field_count = 0;854for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {855if (fldc.access_flags().is_static()) field_count++;856}857// Add in resolved_references which is referenced by the cpCache858// The resolved_references is an array per InstanceKlass holding the859// strings and other oops resolved from the constant pool.860oop resolved_references = ikh->constants()->resolved_references_or_null();861if (resolved_references != NULL) {862field_count++;863864// Add in the resolved_references of the used previous versions of the class865// in the case of RedefineClasses866InstanceKlass* prev = ikh->previous_versions();867while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {868field_count++;869prev = prev->previous_versions();870}871}872873// Also provide a pointer to the init_lock if present, so there aren't unreferenced int[0]874// arrays.875oop init_lock = ikh->init_lock();876if (init_lock != NULL) {877field_count++;878}879880writer->write_u2(field_count);881882// pass 2 - dump the field descriptors and raw values883for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {884if (fld.access_flags().is_static()) {885Symbol* sig = fld.signature();886887writer->write_symbolID(fld.name()); // name888writer->write_u1(sig2tag(sig)); // type889890// value891int offset = fld.offset();892address addr = (address)ikh->java_mirror() + offset;893894dump_field_value(writer, sig->byte_at(0), addr);895}896}897898// Add resolved_references for each class that has them899if (resolved_references != NULL) {900writer->write_symbolID(vmSymbols::resolved_references_name()); // name901writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type902writer->write_objectID(resolved_references);903904// Also write any previous versions905InstanceKlass* prev = ikh->previous_versions();906while (prev != NULL && prev->constants()->resolved_references_or_null() != NULL) {907writer->write_symbolID(vmSymbols::resolved_references_name()); // name908writer->write_u1(sig2tag(vmSymbols::object_array_signature())); // type909writer->write_objectID(prev->constants()->resolved_references());910prev = prev->previous_versions();911}912}913914// Add init lock to the end if the class is not yet initialized915if (init_lock != NULL) {916writer->write_symbolID(vmSymbols::init_lock_name()); // name917writer->write_u1(sig2tag(vmSymbols::int_array_signature())); // type918writer->write_objectID(init_lock);919}920}921922// dump the raw values of the instance fields of the given object923void DumperSupport::dump_instance_fields(DumpWriter* writer, oop o) {924HandleMark hm;925instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), o->klass());926927for (FieldStream fld(ikh, false, false); !fld.eos(); fld.next()) {928if (!fld.access_flags().is_static()) {929Symbol* sig = fld.signature();930address addr = (address)o + fld.offset();931932dump_field_value(writer, sig->byte_at(0), addr);933}934}935}936937// dumps the definition of the instance fields for a given class938void DumperSupport::dump_instance_field_descriptors(DumpWriter* writer, Klass* k) {939HandleMark hm;940instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);941942// pass 1 - count the instance fields943u2 field_count = 0;944for (FieldStream fldc(ikh, true, true); !fldc.eos(); fldc.next()) {945if (!fldc.access_flags().is_static()) field_count++;946}947948writer->write_u2(field_count);949950// pass 2 - dump the field descriptors951for (FieldStream fld(ikh, true, true); !fld.eos(); fld.next()) {952if (!fld.access_flags().is_static()) {953Symbol* sig = fld.signature();954955writer->write_symbolID(fld.name()); // name956writer->write_u1(sig2tag(sig)); // type957}958}959}960961// creates HPROF_GC_INSTANCE_DUMP record for the given object962void DumperSupport::dump_instance(DumpWriter* writer, oop o) {963Klass* k = o->klass();964965writer->write_u1(HPROF_GC_INSTANCE_DUMP);966writer->write_objectID(o);967writer->write_u4(STACK_TRACE_ID);968969// class ID970writer->write_classID(k);971972// number of bytes that follow973writer->write_u4(instance_size(k) );974975// field values976dump_instance_fields(writer, o);977}978979// creates HPROF_GC_CLASS_DUMP record for the given class and each of980// its array classes981void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, Klass* k) {982Klass* klass = k;983InstanceKlass* ik = InstanceKlass::cast(k);984985// We can safepoint and do a heap dump at a point where we have a Klass,986// but no java mirror class has been setup for it. So we need to check987// that the class is at least loaded, to avoid crash from a null mirror.988if (!ik->is_loaded()) {989return;990}991992writer->write_u1(HPROF_GC_CLASS_DUMP);993994// class ID995writer->write_classID(ik);996writer->write_u4(STACK_TRACE_ID);997998// super class ID999Klass* java_super = ik->java_super();1000if (java_super == NULL) {1001writer->write_objectID(oop(NULL));1002} else {1003writer->write_classID(java_super);1004}10051006writer->write_objectID(ik->class_loader());1007writer->write_objectID(ik->signers());1008writer->write_objectID(ik->protection_domain());10091010// reserved1011writer->write_objectID(oop(NULL));1012writer->write_objectID(oop(NULL));10131014// instance size1015writer->write_u4(DumperSupport::instance_size(k));10161017// size of constant pool - ignored by HAT 1.11018writer->write_u2(0);10191020// number of static fields1021dump_static_fields(writer, k);10221023// description of instance fields1024dump_instance_field_descriptors(writer, k);10251026// array classes1027k = klass->array_klass_or_null();1028while (k != NULL) {1029Klass* klass = k;1030assert(klass->oop_is_objArray(), "not an ObjArrayKlass");10311032writer->write_u1(HPROF_GC_CLASS_DUMP);1033writer->write_classID(klass);1034writer->write_u4(STACK_TRACE_ID);10351036// super class of array classes is java.lang.Object1037java_super = klass->java_super();1038assert(java_super != NULL, "checking");1039writer->write_classID(java_super);10401041writer->write_objectID(ik->class_loader());1042writer->write_objectID(ik->signers());1043writer->write_objectID(ik->protection_domain());10441045writer->write_objectID(oop(NULL)); // reserved1046writer->write_objectID(oop(NULL));1047writer->write_u4(0); // instance size1048writer->write_u2(0); // constant pool1049writer->write_u2(0); // static fields1050writer->write_u2(0); // instance fields10511052// get the array class for the next rank1053k = klass->array_klass_or_null();1054}1055}10561057// creates HPROF_GC_CLASS_DUMP record for a given primitive array1058// class (and each multi-dimensional array class too)1059void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, Klass* k) {1060// array classes1061while (k != NULL) {1062Klass* klass = k;10631064writer->write_u1(HPROF_GC_CLASS_DUMP);1065writer->write_classID(klass);1066writer->write_u4(STACK_TRACE_ID);10671068// super class of array classes is java.lang.Object1069Klass* java_super = klass->java_super();1070assert(java_super != NULL, "checking");1071writer->write_classID(java_super);10721073writer->write_objectID(oop(NULL)); // loader1074writer->write_objectID(oop(NULL)); // signers1075writer->write_objectID(oop(NULL)); // protection domain10761077writer->write_objectID(oop(NULL)); // reserved1078writer->write_objectID(oop(NULL));1079writer->write_u4(0); // instance size1080writer->write_u2(0); // constant pool1081writer->write_u2(0); // static fields1082writer->write_u2(0); // instance fields10831084// get the array class for the next rank1085k = klass->array_klass_or_null();1086}1087}10881089// Hprof uses an u4 as record length field,1090// which means we need to truncate arrays that are too long.1091int DumperSupport::calculate_array_max_length(DumpWriter* writer, arrayOop array, short header_size) {1092BasicType type = ArrayKlass::cast(array->klass())->element_type();1093assert(type >= T_BOOLEAN && type <= T_OBJECT, "invalid array element type");10941095int length = array->length();10961097int type_size;1098if (type == T_OBJECT) {1099type_size = sizeof(address);1100} else {1101type_size = type2aelembytes(type);1102}11031104size_t length_in_bytes = (size_t)length * type_size;11051106// Create a new record if the current record is non-empty and the array can't fit.1107julong current_record_length = writer->current_record_length();1108if (current_record_length > 0 &&1109(current_record_length + header_size + length_in_bytes) > max_juint) {1110write_current_dump_record_length(writer);1111write_dump_header(writer);11121113// We now have an empty record.1114current_record_length = 0;1115}11161117// Calculate max bytes we can use.1118uint max_bytes = max_juint - (header_size + current_record_length);11191120// Array too long for the record?1121// Calculate max length and return it.1122if (length_in_bytes > max_bytes) {1123length = max_bytes / type_size;1124length_in_bytes = (size_t)length * type_size;11251126warning("cannot dump array of type %s[] with length %d; truncating to length %d",1127type2name_tab[type], array->length(), length);1128}1129return length;1130}11311132// creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array1133void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) {1134// sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID) + sizeof(classID)1135short header_size = 1 + 2 * 4 + 2 * sizeof(address);11361137int length = calculate_array_max_length(writer, array, header_size);11381139writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP);1140writer->write_objectID(array);1141writer->write_u4(STACK_TRACE_ID);1142writer->write_u4(length);114311441145// array class ID1146writer->write_classID(array->klass());11471148// [id]* elements1149for (int index = 0; index < length; index++) {1150oop o = array->obj_at(index);1151writer->write_objectID(o);1152}1153}11541155#define WRITE_ARRAY(Array, Type, Size, Length) \1156for (int i = 0; i < Length; i++) { writer->write_##Size((Size)array->Type##_at(i)); }11571158// creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array1159void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {1160BasicType type = TypeArrayKlass::cast(array->klass())->element_type();11611162// 2 * sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID)1163short header_size = 2 * 1 + 2 * 4 + sizeof(address);11641165int length = calculate_array_max_length(writer, array, header_size);1166int type_size = type2aelembytes(type);1167u4 length_in_bytes = (u4)length * type_size;11681169writer->write_u1(HPROF_GC_PRIM_ARRAY_DUMP);1170writer->write_objectID(array);1171writer->write_u4(STACK_TRACE_ID);1172writer->write_u4(length);1173writer->write_u1(type2tag(type));11741175// nothing to copy1176if (length == 0) {1177return;1178}11791180// If the byte ordering is big endian then we can copy most types directly11811182switch (type) {1183case T_INT : {1184if (Bytes::is_Java_byte_ordering_different()) {1185WRITE_ARRAY(array, int, u4, length);1186} else {1187writer->write_raw((void*)(array->int_at_addr(0)), length_in_bytes);1188}1189break;1190}1191case T_BYTE : {1192writer->write_raw((void*)(array->byte_at_addr(0)), length_in_bytes);1193break;1194}1195case T_CHAR : {1196if (Bytes::is_Java_byte_ordering_different()) {1197WRITE_ARRAY(array, char, u2, length);1198} else {1199writer->write_raw((void*)(array->char_at_addr(0)), length_in_bytes);1200}1201break;1202}1203case T_SHORT : {1204if (Bytes::is_Java_byte_ordering_different()) {1205WRITE_ARRAY(array, short, u2, length);1206} else {1207writer->write_raw((void*)(array->short_at_addr(0)), length_in_bytes);1208}1209break;1210}1211case T_BOOLEAN : {1212if (Bytes::is_Java_byte_ordering_different()) {1213WRITE_ARRAY(array, bool, u1, length);1214} else {1215writer->write_raw((void*)(array->bool_at_addr(0)), length_in_bytes);1216}1217break;1218}1219case T_LONG : {1220if (Bytes::is_Java_byte_ordering_different()) {1221WRITE_ARRAY(array, long, u8, length);1222} else {1223writer->write_raw((void*)(array->long_at_addr(0)), length_in_bytes);1224}1225break;1226}12271228// handle float/doubles in a special value to ensure than NaNs are1229// written correctly. TO DO: Check if we can avoid this on processors that1230// use IEEE 754.12311232case T_FLOAT : {1233for (int i = 0; i < length; i++) {1234dump_float(writer, array->float_at(i));1235}1236break;1237}1238case T_DOUBLE : {1239for (int i = 0; i < length; i++) {1240dump_double(writer, array->double_at(i));1241}1242break;1243}1244default : ShouldNotReachHere();1245}1246}12471248// create a HPROF_FRAME record of the given Method* and bci1249void DumperSupport::dump_stack_frame(DumpWriter* writer,1250int frame_serial_num,1251int class_serial_num,1252Method* m,1253int bci) {1254int line_number;1255if (m->is_native()) {1256line_number = -3; // native frame1257} else {1258line_number = m->line_number_from_bci(bci);1259}12601261write_header(writer, HPROF_FRAME, 4*oopSize + 2*sizeof(u4));1262writer->write_id(frame_serial_num); // frame serial number1263writer->write_symbolID(m->name()); // method's name1264writer->write_symbolID(m->signature()); // method's signature12651266assert(m->method_holder()->oop_is_instance(), "not InstanceKlass");1267writer->write_symbolID(m->method_holder()->source_file_name()); // source file name1268writer->write_u4(class_serial_num); // class serial number1269writer->write_u4((u4) line_number); // line number1270}127112721273// Support class used to generate HPROF_UTF8 records from the entries in the1274// SymbolTable.12751276class SymbolTableDumper : public SymbolClosure {1277private:1278DumpWriter* _writer;1279DumpWriter* writer() const { return _writer; }1280public:1281SymbolTableDumper(DumpWriter* writer) { _writer = writer; }1282void do_symbol(Symbol** p);1283};12841285void SymbolTableDumper::do_symbol(Symbol** p) {1286ResourceMark rm;1287Symbol* sym = load_symbol(p);1288int len = sym->utf8_length();1289if (len > 0) {1290char* s = sym->as_utf8();1291DumperSupport::write_header(writer(), HPROF_UTF8, oopSize + len);1292writer()->write_symbolID(sym);1293writer()->write_raw(s, len);1294}1295}12961297// Support class used to generate HPROF_GC_ROOT_JNI_LOCAL records12981299class JNILocalsDumper : public OopClosure {1300private:1301DumpWriter* _writer;1302u4 _thread_serial_num;1303int _frame_num;1304DumpWriter* writer() const { return _writer; }1305public:1306JNILocalsDumper(DumpWriter* writer, u4 thread_serial_num) {1307_writer = writer;1308_thread_serial_num = thread_serial_num;1309_frame_num = -1; // default - empty stack1310}1311void set_frame_number(int n) { _frame_num = n; }1312void do_oop(oop* obj_p);1313void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }1314};131513161317void JNILocalsDumper::do_oop(oop* obj_p) {1318// ignore null or deleted handles1319oop o = *obj_p;1320if (o != NULL && o != JNIHandles::deleted_handle()) {1321writer()->write_u1(HPROF_GC_ROOT_JNI_LOCAL);1322writer()->write_objectID(o);1323writer()->write_u4(_thread_serial_num);1324writer()->write_u4((u4)_frame_num);1325}1326}132713281329// Support class used to generate HPROF_GC_ROOT_JNI_GLOBAL records13301331class JNIGlobalsDumper : public OopClosure {1332private:1333DumpWriter* _writer;1334DumpWriter* writer() const { return _writer; }13351336public:1337JNIGlobalsDumper(DumpWriter* writer) {1338_writer = writer;1339}1340void do_oop(oop* obj_p);1341void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }1342};13431344void JNIGlobalsDumper::do_oop(oop* obj_p) {1345oop o = *obj_p;13461347// ignore these1348if (o == NULL || o == JNIHandles::deleted_handle()) return;13491350// we ignore global ref to symbols and other internal objects1351if (o->is_instance() || o->is_objArray() || o->is_typeArray()) {1352writer()->write_u1(HPROF_GC_ROOT_JNI_GLOBAL);1353writer()->write_objectID(o);1354writer()->write_objectID((oopDesc*)obj_p); // global ref ID1355}1356};135713581359// Support class used to generate HPROF_GC_ROOT_MONITOR_USED records13601361class MonitorUsedDumper : public OopClosure {1362private:1363DumpWriter* _writer;1364DumpWriter* writer() const { return _writer; }1365public:1366MonitorUsedDumper(DumpWriter* writer) {1367_writer = writer;1368}1369void do_oop(oop* obj_p) {1370writer()->write_u1(HPROF_GC_ROOT_MONITOR_USED);1371writer()->write_objectID(*obj_p);1372}1373void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }1374};137513761377// Support class used to generate HPROF_GC_ROOT_STICKY_CLASS records13781379class StickyClassDumper : public KlassClosure {1380private:1381DumpWriter* _writer;1382DumpWriter* writer() const { return _writer; }1383public:1384StickyClassDumper(DumpWriter* writer) {1385_writer = writer;1386}1387void do_klass(Klass* k) {1388if (k->oop_is_instance()) {1389InstanceKlass* ik = InstanceKlass::cast(k);1390writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS);1391writer()->write_classID(ik);1392}1393}1394};139513961397class VM_HeapDumper;13981399// Support class using when iterating over the heap.14001401class HeapObjectDumper : public ObjectClosure {1402private:1403VM_HeapDumper* _dumper;1404DumpWriter* _writer;14051406VM_HeapDumper* dumper() { return _dumper; }1407DumpWriter* writer() { return _writer; }14081409// used to indicate that a record has been writen1410void mark_end_of_record();14111412public:1413HeapObjectDumper(VM_HeapDumper* dumper, DumpWriter* writer) {1414_dumper = dumper;1415_writer = writer;1416}14171418// called for each object in the heap1419void do_object(oop o);1420};14211422void HeapObjectDumper::do_object(oop o) {1423// hide the sentinel for deleted handles1424if (o == JNIHandles::deleted_handle()) return;14251426// skip classes as these emitted as HPROF_GC_CLASS_DUMP records1427if (o->klass() == SystemDictionary::Class_klass()) {1428if (!java_lang_Class::is_primitive(o)) {1429return;1430}1431}14321433if (o->is_instance()) {1434// create a HPROF_GC_INSTANCE record for each object1435DumperSupport::dump_instance(writer(), o);1436mark_end_of_record();1437} else if (o->is_objArray()) {1438// create a HPROF_GC_OBJ_ARRAY_DUMP record for each object array1439DumperSupport::dump_object_array(writer(), objArrayOop(o));1440mark_end_of_record();1441} else if (o->is_typeArray()) {1442// create a HPROF_GC_PRIM_ARRAY_DUMP record for each type array1443DumperSupport::dump_prim_array(writer(), typeArrayOop(o));1444mark_end_of_record();1445}1446}14471448// The VM operation that performs the heap dump1449class VM_HeapDumper : public VM_GC_Operation {1450private:1451static VM_HeapDumper* _global_dumper;1452static DumpWriter* _global_writer;1453DumpWriter* _local_writer;1454JavaThread* _oome_thread;1455Method* _oome_constructor;1456bool _gc_before_heap_dump;1457GrowableArray<Klass*>* _klass_map;1458ThreadStackTrace** _stack_traces;1459int _num_threads;14601461// accessors and setters1462static VM_HeapDumper* dumper() { assert(_global_dumper != NULL, "Error"); return _global_dumper; }1463static DumpWriter* writer() { assert(_global_writer != NULL, "Error"); return _global_writer; }1464void set_global_dumper() {1465assert(_global_dumper == NULL, "Error");1466_global_dumper = this;1467}1468void set_global_writer() {1469assert(_global_writer == NULL, "Error");1470_global_writer = _local_writer;1471}1472void clear_global_dumper() { _global_dumper = NULL; }1473void clear_global_writer() { _global_writer = NULL; }14741475bool skip_operation() const;14761477// writes a HPROF_LOAD_CLASS record1478static void do_load_class(Klass* k);14791480// writes a HPROF_GC_CLASS_DUMP record for the given class1481// (and each array class too)1482static void do_class_dump(Klass* k);14831484// writes a HPROF_GC_CLASS_DUMP records for a given basic type1485// array (and each multi-dimensional array too)1486static void do_basic_type_array_class_dump(Klass* k);14871488// HPROF_GC_ROOT_THREAD_OBJ records1489int do_thread(JavaThread* thread, u4 thread_serial_num);1490void do_threads();14911492void add_class_serial_number(Klass* k, int serial_num) {1493_klass_map->at_put_grow(serial_num, k);1494}14951496// HPROF_TRACE and HPROF_FRAME records1497void dump_stack_traces();14981499public:1500VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome) :1501VM_GC_Operation(0 /* total collections, dummy, ignored */,1502GCCause::_heap_dump /* GC Cause */,15030 /* total full collections, dummy, ignored */,1504gc_before_heap_dump) {1505_local_writer = writer;1506_gc_before_heap_dump = gc_before_heap_dump;1507_klass_map = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);1508_stack_traces = NULL;1509_num_threads = 0;1510if (oome) {1511assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread");1512// get OutOfMemoryError zero-parameter constructor1513InstanceKlass* oome_ik = InstanceKlass::cast(SystemDictionary::OutOfMemoryError_klass());1514_oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(),1515vmSymbols::void_method_signature());1516// get thread throwing OOME when generating the heap dump at OOME1517_oome_thread = JavaThread::current();1518} else {1519_oome_thread = NULL;1520_oome_constructor = NULL;1521}1522}1523~VM_HeapDumper() {1524if (_stack_traces != NULL) {1525for (int i=0; i < _num_threads; i++) {1526delete _stack_traces[i];1527}1528FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces, mtInternal);1529}1530delete _klass_map;1531}15321533VMOp_Type type() const { return VMOp_HeapDumper; }1534// used to mark sub-record boundary1535void check_segment_length();1536void doit();1537};15381539VM_HeapDumper* VM_HeapDumper::_global_dumper = NULL;1540DumpWriter* VM_HeapDumper::_global_writer = NULL;15411542bool VM_HeapDumper::skip_operation() const {1543return false;1544}15451546// writes a HPROF_HEAP_DUMP_SEGMENT record1547void DumperSupport::write_dump_header(DumpWriter* writer) {1548if (writer->is_open()) {1549writer->write_u1(HPROF_HEAP_DUMP_SEGMENT);1550writer->write_u4(0); // current ticks15511552// record the starting position for the dump (its length will be fixed up later)1553writer->set_dump_start(writer->current_offset());1554writer->write_u4(0);1555}1556}15571558// fixes up the length of the current dump record1559void DumperSupport::write_current_dump_record_length(DumpWriter* writer) {1560if (writer->is_open()) {1561julong dump_end = writer->bytes_written() + writer->bytes_unwritten();1562julong dump_len = writer->current_record_length();15631564// record length must fit in a u41565if (dump_len > max_juint) {1566warning("record is too large");1567}15681569// seek to the dump start and fix-up the length1570assert(writer->dump_start() >= 0, "no dump start recorded");1571writer->seek_to_offset(writer->dump_start());1572writer->write_u4((u4)dump_len);15731574// adjust the total size written to keep the bytes written correct.1575writer->adjust_bytes_written(-((jlong) sizeof(u4)));15761577// seek to dump end so we can continue1578writer->seek_to_offset(dump_end);15791580// no current dump record1581writer->set_dump_start((jlong)-1);1582}1583}15841585// used on a sub-record boundary to check if we need to start a1586// new segment.1587void VM_HeapDumper::check_segment_length() {1588if (writer()->is_open()) {1589julong dump_len = writer()->current_record_length();15901591if (dump_len > 2UL*G) {1592DumperSupport::write_current_dump_record_length(writer());1593DumperSupport::write_dump_header(writer());1594}1595}1596}15971598// fixes up the current dump record and writes HPROF_HEAP_DUMP_END record1599void DumperSupport::end_of_dump(DumpWriter* writer) {1600if (writer->is_open()) {1601write_current_dump_record_length(writer);16021603writer->write_u1(HPROF_HEAP_DUMP_END);1604writer->write_u4(0);1605writer->write_u4(0);1606}1607}16081609// marks sub-record boundary1610void HeapObjectDumper::mark_end_of_record() {1611dumper()->check_segment_length();1612}16131614// writes a HPROF_LOAD_CLASS record for the class (and each of its1615// array classes)1616void VM_HeapDumper::do_load_class(Klass* k) {1617static u4 class_serial_num = 0;16181619// len of HPROF_LOAD_CLASS record1620u4 remaining = 2*oopSize + 2*sizeof(u4);16211622// write a HPROF_LOAD_CLASS for the class and each array class1623do {1624DumperSupport::write_header(writer(), HPROF_LOAD_CLASS, remaining);16251626// class serial number is just a number1627writer()->write_u4(++class_serial_num);16281629// class ID1630Klass* klass = k;1631writer()->write_classID(klass);16321633// add the Klass* and class serial number pair1634dumper()->add_class_serial_number(klass, class_serial_num);16351636writer()->write_u4(STACK_TRACE_ID);16371638// class name ID1639Symbol* name = klass->name();1640writer()->write_symbolID(name);16411642// write a LOAD_CLASS record for the array type (if it exists)1643k = klass->array_klass_or_null();1644} while (k != NULL);1645}16461647// writes a HPROF_GC_CLASS_DUMP record for the given class1648void VM_HeapDumper::do_class_dump(Klass* k) {1649if (k->oop_is_instance()) {1650DumperSupport::dump_class_and_array_classes(writer(), k);1651}1652}16531654// writes a HPROF_GC_CLASS_DUMP records for a given basic type1655// array (and each multi-dimensional array too)1656void VM_HeapDumper::do_basic_type_array_class_dump(Klass* k) {1657DumperSupport::dump_basic_type_array_class(writer(), k);1658}16591660// Walk the stack of the given thread.1661// Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local1662// Dumps a HPROF_GC_ROOT_JNI_LOCAL record for each JNI local1663//1664// It returns the number of Java frames in this thread stack1665int VM_HeapDumper::do_thread(JavaThread* java_thread, u4 thread_serial_num) {1666JNILocalsDumper blk(writer(), thread_serial_num);16671668oop threadObj = java_thread->threadObj();1669assert(threadObj != NULL, "sanity check");16701671int stack_depth = 0;1672if (java_thread->has_last_Java_frame()) {16731674// vframes are resource allocated1675Thread* current_thread = Thread::current();1676ResourceMark rm(current_thread);1677HandleMark hm(current_thread);16781679RegisterMap reg_map(java_thread);1680frame f = java_thread->last_frame();1681vframe* vf = vframe::new_vframe(&f, ®_map, java_thread);1682frame* last_entry_frame = NULL;1683int extra_frames = 0;16841685if (java_thread == _oome_thread && _oome_constructor != NULL) {1686extra_frames++;1687}1688while (vf != NULL) {1689blk.set_frame_number(stack_depth);1690if (vf->is_java_frame()) {16911692// java frame (interpreted, compiled, ...)1693javaVFrame *jvf = javaVFrame::cast(vf);1694if (!(jvf->method()->is_native())) {1695StackValueCollection* locals = jvf->locals();1696for (int slot=0; slot<locals->size(); slot++) {1697if (locals->at(slot)->type() == T_OBJECT) {1698oop o = locals->obj_at(slot)();16991700if (o != NULL) {1701writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME);1702writer()->write_objectID(o);1703writer()->write_u4(thread_serial_num);1704writer()->write_u4((u4) (stack_depth + extra_frames));1705}1706}1707}1708} else {1709// native frame1710if (stack_depth == 0) {1711// JNI locals for the top frame.1712java_thread->active_handles()->oops_do(&blk);1713} else {1714if (last_entry_frame != NULL) {1715// JNI locals for the entry frame1716assert(last_entry_frame->is_entry_frame(), "checking");1717last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(&blk);1718}1719}1720}1721// increment only for Java frames1722stack_depth++;1723last_entry_frame = NULL;17241725} else {1726// externalVFrame - if it's an entry frame then report any JNI locals1727// as roots when we find the corresponding native javaVFrame1728frame* fr = vf->frame_pointer();1729assert(fr != NULL, "sanity check");1730if (fr->is_entry_frame()) {1731last_entry_frame = fr;1732}1733}1734vf = vf->sender();1735}1736} else {1737// no last java frame but there may be JNI locals1738java_thread->active_handles()->oops_do(&blk);1739}1740return stack_depth;1741}174217431744// write a HPROF_GC_ROOT_THREAD_OBJ record for each java thread. Then walk1745// the stack so that locals and JNI locals are dumped.1746void VM_HeapDumper::do_threads() {1747for (int i=0; i < _num_threads; i++) {1748JavaThread* thread = _stack_traces[i]->thread();1749oop threadObj = thread->threadObj();1750u4 thread_serial_num = i+1;1751u4 stack_serial_num = thread_serial_num + STACK_TRACE_ID;1752writer()->write_u1(HPROF_GC_ROOT_THREAD_OBJ);1753writer()->write_objectID(threadObj);1754writer()->write_u4(thread_serial_num); // thread number1755writer()->write_u4(stack_serial_num); // stack trace serial number1756int num_frames = do_thread(thread, thread_serial_num);1757assert(num_frames == _stack_traces[i]->get_stack_depth(),1758"total number of Java frames not matched");1759}1760}176117621763// The VM operation that dumps the heap. The dump consists of the following1764// records:1765//1766// HPROF_HEADER1767// [HPROF_UTF8]*1768// [HPROF_LOAD_CLASS]*1769// [[HPROF_FRAME]*|HPROF_TRACE]*1770// [HPROF_GC_CLASS_DUMP]*1771// [HPROF_HEAP_DUMP_SEGMENT]*1772// HPROF_HEAP_DUMP_END1773//1774// The HPROF_TRACE records represent the stack traces where the heap dump1775// is generated and a "dummy trace" record which does not include1776// any frames. The dummy trace record is used to be referenced as the1777// unknown object alloc site.1778//1779// Each HPROF_HEAP_DUMP_SEGMENT record has a length followed by sub-records.1780// To allow the heap dump be generated in a single pass we remember the position1781// of the dump length and fix it up after all sub-records have been written.1782// To generate the sub-records we iterate over the heap, writing1783// HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP1784// records as we go. Once that is done we write records for some of the GC1785// roots.17861787void VM_HeapDumper::doit() {17881789HandleMark hm;1790CollectedHeap* ch = Universe::heap();17911792ch->ensure_parsability(false); // must happen, even if collection does1793// not happen (e.g. due to GC_locker)17941795if (_gc_before_heap_dump) {1796if (GC_locker::is_active()) {1797warning("GC locker is held; pre-heapdump GC was skipped");1798} else {1799ch->collect_as_vm_thread(GCCause::_heap_dump);1800}1801}18021803// At this point we should be the only dumper active, so1804// the following should be safe.1805set_global_dumper();1806set_global_writer();18071808// Write the file header - we always use 1.0.21809size_t used = ch->used();1810const char* header = "JAVA PROFILE 1.0.2";18111812// header is few bytes long - no chance to overflow int1813writer()->write_raw((void*)header, (int)strlen(header));1814writer()->write_u1(0); // terminator1815writer()->write_u4(oopSize);1816writer()->write_u8(os::javaTimeMillis());18171818// HPROF_UTF8 records1819SymbolTableDumper sym_dumper(writer());1820SymbolTable::symbols_do(&sym_dumper);18211822// write HPROF_LOAD_CLASS records1823ClassLoaderDataGraph::classes_do(&do_load_class);1824Universe::basic_type_classes_do(&do_load_class);18251826// write HPROF_FRAME and HPROF_TRACE records1827// this must be called after _klass_map is built when iterating the classes above.1828dump_stack_traces();18291830// write HPROF_HEAP_DUMP_SEGMENT1831DumperSupport::write_dump_header(writer());18321833// Writes HPROF_GC_CLASS_DUMP records1834ClassLoaderDataGraph::classes_do(&do_class_dump);1835Universe::basic_type_classes_do(&do_basic_type_array_class_dump);1836check_segment_length();18371838// writes HPROF_GC_INSTANCE_DUMP records.1839// After each sub-record is written check_segment_length will be invoked1840// to check if the current segment exceeds a threshold. If so, a new1841// segment is started.1842// The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk1843// of the heap dump.1844HeapObjectDumper obj_dumper(this, writer());1845Universe::heap()->safe_object_iterate(&obj_dumper);18461847// HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals1848do_threads();1849check_segment_length();18501851// HPROF_GC_ROOT_MONITOR_USED1852MonitorUsedDumper mon_dumper(writer());1853ObjectSynchronizer::oops_do(&mon_dumper);1854check_segment_length();18551856// HPROF_GC_ROOT_JNI_GLOBAL1857JNIGlobalsDumper jni_dumper(writer());1858JNIHandles::oops_do(&jni_dumper);1859Universe::oops_do(&jni_dumper); // technically not jni roots, but global roots1860// for things like preallocated throwable backtraces1861check_segment_length();18621863// HPROF_GC_ROOT_STICKY_CLASS1864StickyClassDumper class_dumper(writer());1865SystemDictionary::always_strong_classes_do(&class_dumper);18661867// fixes up the length of the dump record and writes the HPROF_HEAP_DUMP_END record.1868DumperSupport::end_of_dump(writer());18691870// Now we clear the global variables, so that a future dumper might run.1871clear_global_dumper();1872clear_global_writer();1873}18741875void VM_HeapDumper::dump_stack_traces() {1876// write a HPROF_TRACE record without any frames to be referenced as object alloc sites1877DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));1878writer()->write_u4((u4) STACK_TRACE_ID);1879writer()->write_u4(0); // thread number1880writer()->write_u4(0); // frame count18811882_stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads(), mtInternal);1883int frame_serial_num = 0;1884for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {1885oop threadObj = thread->threadObj();1886if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {1887// dump thread stack trace1888ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false);1889stack_trace->dump_stack_at_safepoint(-1);1890_stack_traces[_num_threads++] = stack_trace;18911892// write HPROF_FRAME records for this thread's stack trace1893int depth = stack_trace->get_stack_depth();1894int thread_frame_start = frame_serial_num;1895int extra_frames = 0;1896// write fake frame that makes it look like the thread, which caused OOME,1897// is in the OutOfMemoryError zero-parameter constructor1898if (thread == _oome_thread && _oome_constructor != NULL) {1899int oome_serial_num = _klass_map->find(_oome_constructor->method_holder());1900// the class serial number starts from 11901assert(oome_serial_num > 0, "OutOfMemoryError class not found");1902DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, oome_serial_num,1903_oome_constructor, 0);1904extra_frames++;1905}1906for (int j=0; j < depth; j++) {1907StackFrameInfo* frame = stack_trace->stack_frame_at(j);1908Method* m = frame->method();1909int class_serial_num = _klass_map->find(m->method_holder());1910// the class serial number starts from 11911assert(class_serial_num > 0, "class not found");1912DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci());1913}1914depth += extra_frames;19151916// write HPROF_TRACE record for one thread1917DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4) + depth*oopSize);1918int stack_serial_num = _num_threads + STACK_TRACE_ID;1919writer()->write_u4(stack_serial_num); // stack trace serial number1920writer()->write_u4((u4) _num_threads); // thread serial number1921writer()->write_u4(depth); // frame count1922for (int j=1; j <= depth; j++) {1923writer()->write_id(thread_frame_start + j);1924}1925}1926}1927}19281929// dump the heap to given path.1930PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL1931int HeapDumper::dump(const char* path) {1932assert(path != NULL && strlen(path) > 0, "path missing");19331934// print message in interactive case1935if (print_to_tty()) {1936tty->print_cr("Dumping heap to %s ...", path);1937timer()->start();1938}19391940// create the dump writer. If the file can be opened then bail1941DumpWriter writer(path);1942if (!writer.is_open()) {1943set_error(writer.error());1944if (print_to_tty()) {1945tty->print_cr("Unable to create %s: %s", path,1946(error() != NULL) ? error() : "reason unknown");1947}1948return -1;1949}19501951// generate the dump1952VM_HeapDumper dumper(&writer, _gc_before_heap_dump, _oome);1953if (Thread::current()->is_VM_thread()) {1954assert(SafepointSynchronize::is_at_safepoint(), "Expected to be called at a safepoint");1955dumper.doit();1956} else {1957VMThread::execute(&dumper);1958}19591960// close dump file and record any error that the writer may have encountered1961writer.close();1962set_error(writer.error());19631964// print message in interactive case1965if (print_to_tty()) {1966timer()->stop();1967if (error() == NULL) {1968tty->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",1969writer.bytes_written(), timer()->seconds());1970} else {1971tty->print_cr("Dump file is incomplete: %s", writer.error());1972}1973}19741975return (writer.error() == NULL) ? 0 : -1;1976}19771978// stop timer (if still active), and free any error string we might be holding1979HeapDumper::~HeapDumper() {1980if (timer()->is_active()) {1981timer()->stop();1982}1983set_error(NULL);1984}198519861987// returns the error string (resource allocated), or NULL1988char* HeapDumper::error_as_C_string() const {1989if (error() != NULL) {1990char* str = NEW_RESOURCE_ARRAY(char, strlen(error())+1);1991strcpy(str, error());1992return str;1993} else {1994return NULL;1995}1996}19971998// set the error string1999void HeapDumper::set_error(char* error) {2000if (_error != NULL) {2001os::free(_error);2002}2003if (error == NULL) {2004_error = NULL;2005} else {2006_error = os::strdup(error);2007assert(_error != NULL, "allocation failure");2008}2009}20102011// Called by out-of-memory error reporting by a single Java thread2012// outside of a JVM safepoint2013void HeapDumper::dump_heap_from_oome() {2014HeapDumper::dump_heap(true);2015}20162017// Called by error reporting by a single Java thread outside of a JVM safepoint,2018// or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various2019// callers are strictly serialized and guaranteed not to interfere below. For more2020// general use, however, this method will need modification to prevent2021// inteference when updating the static variables base_path and dump_file_seq below.2022void HeapDumper::dump_heap() {2023HeapDumper::dump_heap(false);2024}20252026void HeapDumper::dump_heap(bool oome) {2027static char base_path[JVM_MAXPATHLEN] = {'\0'};2028static uint dump_file_seq = 0;2029char* my_path;2030const int max_digit_chars = 20;20312032const char* dump_file_name = "java_pid";2033const char* dump_file_ext = ".hprof";20342035// The dump file defaults to java_pid<pid>.hprof in the current working2036// directory. HeapDumpPath=<file> can be used to specify an alternative2037// dump file name or a directory where dump file is created.2038if (dump_file_seq == 0) { // first time in, we initialize base_path2039// Calculate potentially longest base path and check if we have enough2040// allocated statically.2041const size_t total_length =2042(HeapDumpPath == NULL ? 0 : strlen(HeapDumpPath)) +2043strlen(os::file_separator()) + max_digit_chars +2044strlen(dump_file_name) + strlen(dump_file_ext) + 1;2045if (total_length > sizeof(base_path)) {2046warning("Cannot create heap dump file. HeapDumpPath is too long.");2047return;2048}20492050bool use_default_filename = true;2051if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {2052// HeapDumpPath=<file> not specified2053} else {2054strncpy(base_path, HeapDumpPath, sizeof(base_path));2055// check if the path is a directory (must exist)2056DIR* dir = os::opendir(base_path);2057if (dir == NULL) {2058use_default_filename = false;2059} else {2060// HeapDumpPath specified a directory. We append a file separator2061// (if needed).2062os::closedir(dir);2063size_t fs_len = strlen(os::file_separator());2064if (strlen(base_path) >= fs_len) {2065char* end = base_path;2066end += (strlen(base_path) - fs_len);2067if (strcmp(end, os::file_separator()) != 0) {2068strcat(base_path, os::file_separator());2069}2070}2071}2072}2073// If HeapDumpPath wasn't a file name then we append the default name2074if (use_default_filename) {2075const size_t dlen = strlen(base_path); // if heap dump dir specified2076jio_snprintf(&base_path[dlen], sizeof(base_path)-dlen, "%s%d%s",2077dump_file_name, os::current_process_id(), dump_file_ext);2078}2079const size_t len = strlen(base_path) + 1;2080my_path = (char*)os::malloc(len, mtInternal);2081if (my_path == NULL) {2082warning("Cannot create heap dump file. Out of system memory.");2083return;2084}2085strncpy(my_path, base_path, len);2086} else {2087// Append a sequence number id for dumps following the first2088const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \02089my_path = (char*)os::malloc(len, mtInternal);2090if (my_path == NULL) {2091warning("Cannot create heap dump file. Out of system memory.");2092return;2093}2094jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq);2095}2096dump_file_seq++; // increment seq number for next time we dump20972098HeapDumper dumper(false /* no GC before heap dump */,2099true /* send to tty */,2100oome /* pass along out-of-memory-error flag */);2101dumper.dump(my_path);2102os::free(my_path);2103}210421052106