Mon, 27 Jan 2020 05:10:29 +0000
Merge
.hgtags | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Fri Jan 17 19:08:14 2020 +0000 1.2 +++ b/.hgtags Mon Jan 27 05:10:29 2020 +0000 1.3 @@ -1294,3 +1294,5 @@ 1.4 8b80409d5840142a27e274d33948f483a6406a50 jdk8u242-b07 1.5 7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-b08 1.6 7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-ga 1.7 +8c0733543544bbcd32c4404630d764d280299056 jdk8u252-b00 1.8 +a67e9c6edcdd73cb860a16990f0905e102c282d7 jdk8u252-b01
2.1 --- a/agent/src/os/linux/ps_core.c Fri Jan 17 19:08:14 2020 +0000 2.2 +++ b/agent/src/os/linux/ps_core.c Mon Jan 27 05:10:29 2020 +0000 2.3 @@ -868,6 +868,9 @@ 2.4 #define LINK_MAP_LD_OFFSET offsetof(struct link_map, l_ld) 2.5 #define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next) 2.6 2.7 +#define INVALID_LOAD_ADDRESS -1L 2.8 +#define ZERO_LOAD_ADDRESS 0x0L 2.9 + 2.10 // Calculate the load address of shared library 2.11 // on prelink-enabled environment. 2.12 // 2.13 @@ -884,7 +887,7 @@ 2.14 phbuf = read_program_header_table(lib_fd, elf_ehdr); 2.15 if (phbuf == NULL) { 2.16 print_debug("can't read program header of shared object\n"); 2.17 - return 0L; 2.18 + return INVALID_LOAD_ADDRESS; 2.19 } 2.20 2.21 // Get the address of .dynamic section from shared library. 2.22 @@ -900,7 +903,7 @@ 2.23 if (ps_pdread(ph, (psaddr_t)link_map_addr + LINK_MAP_LD_OFFSET, 2.24 &lib_ld, sizeof(uintptr_t)) != PS_OK) { 2.25 print_debug("can't read address of dynamic section in shared object\n"); 2.26 - return 0L; 2.27 + return INVALID_LOAD_ADDRESS; 2.28 } 2.29 2.30 // Return the load address which is calculated by the address of .dynamic 2.31 @@ -1011,9 +1014,9 @@ 2.32 // continue with other libraries... 2.33 } else { 2.34 if (read_elf_header(lib_fd, &elf_ehdr)) { 2.35 - if (lib_base_diff == 0x0L) { 2.36 + if (lib_base_diff == ZERO_LOAD_ADDRESS) { 2.37 lib_base_diff = calc_prelinked_load_address(ph, lib_fd, &elf_ehdr, link_map_addr); 2.38 - if (lib_base_diff == 0x0L) { 2.39 + if (lib_base_diff == INVALID_LOAD_ADDRESS) { 2.40 close(lib_fd); 2.41 return false; 2.42 }
3.1 --- a/make/aix/makefiles/vm.make Fri Jan 17 19:08:14 2020 +0000 3.2 +++ b/make/aix/makefiles/vm.make Mon Jan 27 05:10:29 2020 +0000 3.3 @@ -119,6 +119,7 @@ 3.4 # Extra flags from gnumake's invocation or environment 3.5 CFLAGS += $(EXTRA_CFLAGS) 3.6 LFLAGS += $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS) 3.7 +ASFLAGS += $(EXTRA_ASFLAGS) 3.8 3.9 # Don't set excutable bit on stack segment 3.10 # the same could be done by separate execstack command
4.1 --- a/make/bsd/makefiles/vm.make Fri Jan 17 19:08:14 2020 +0000 4.2 +++ b/make/bsd/makefiles/vm.make Mon Jan 27 05:10:29 2020 +0000 4.3 @@ -121,6 +121,7 @@ 4.4 # Extra flags from gnumake's invocation or environment 4.5 CFLAGS += $(EXTRA_CFLAGS) 4.6 LFLAGS += $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS) 4.7 +ASFLAGS += $(EXTRA_ASFLAGS) 4.8 4.9 # Don't set excutable bit on stack segment 4.10 # the same could be done by separate execstack command
5.1 --- a/make/linux/makefiles/vm.make Fri Jan 17 19:08:14 2020 +0000 5.2 +++ b/make/linux/makefiles/vm.make Mon Jan 27 05:10:29 2020 +0000 5.3 @@ -124,6 +124,7 @@ 5.4 # Extra flags from gnumake's invocation or environment 5.5 CFLAGS += $(EXTRA_CFLAGS) 5.6 LFLAGS += $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS) 5.7 +ASFLAGS += $(EXTRA_ASFLAGS) 5.8 5.9 # Don't set excutable bit on stack segment 5.10 # the same could be done by separate execstack command
6.1 --- a/make/solaris/makefiles/vm.make Fri Jan 17 19:08:14 2020 +0000 6.2 +++ b/make/solaris/makefiles/vm.make Mon Jan 27 05:10:29 2020 +0000 6.3 @@ -109,6 +109,7 @@ 6.4 6.5 # Extra flags from gnumake's invocation or environment 6.6 CFLAGS += $(EXTRA_CFLAGS) 6.7 +ASFLAGS += $(EXTRA_ASFLAGS) 6.8 6.9 # Math Library (libm.so), do not use -lm. 6.10 # There might be two versions of libm.so on the build system:
7.1 --- a/src/share/vm/adlc/filebuff.cpp Fri Jan 17 19:08:14 2020 +0000 7.2 +++ b/src/share/vm/adlc/filebuff.cpp Mon Jan 27 05:10:29 2020 +0000 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -89,200 +89,6 @@ 7.11 return retval; 7.12 } 7.13 7.14 -//------------------------------FileBuffRegion--------------------------------- 7.15 -// Create a new region in a FileBuff. 7.16 -FileBuffRegion::FileBuffRegion( FileBuff* bufr, int soln, int ln, 7.17 - int off, int len) 7.18 -: _bfr(bufr), _sol(soln), _line(ln), _offset(off), _length(len) { 7.19 - _next = NULL; // No chained regions 7.20 -} 7.21 - 7.22 -//------------------------------~FileBuffRegion-------------------------------- 7.23 -// Delete the entire linked list of buffer regions. 7.24 -FileBuffRegion::~FileBuffRegion() { 7.25 - if( _next ) delete _next; 7.26 -} 7.27 - 7.28 -//------------------------------copy------------------------------------------- 7.29 -// Deep copy a FileBuffRegion 7.30 -FileBuffRegion *FileBuffRegion::copy() { 7.31 - if( !this ) return NULL; // The empty buffer region 7.32 - FileBuffRegion *br = new FileBuffRegion(_bfr,_sol,_line,_offset,_length); 7.33 - if( _next ) br->_next = _next->copy(); 7.34 - return br; 7.35 -} 7.36 - 7.37 -//------------------------------merge------------------------------------------ 7.38 -// Merge another buffer region into this buffer region. Make overlapping areas 7.39 -// become a single region. Remove (delete) the input FileBuffRegion. 7.40 -// Since the buffer regions are sorted by file offset, this is a varient of a 7.41 -// "sorted-merge" running in linear time. 7.42 -FileBuffRegion *FileBuffRegion::merge( FileBuffRegion *br ) { 7.43 - if( !br ) return this; // Merging nothing 7.44 - if( !this ) return br; // Merging into nothing 7.45 - 7.46 - assert( _bfr == br->_bfr, "" ); // Check for pointer-equivalent buffers 7.47 - 7.48 - if( _offset < br->_offset ) { // "this" starts before "br" 7.49 - if( _offset+_length < br->_offset ) { // "this" ends before "br" 7.50 - if( _next ) _next->merge( br ); // Merge with remainder of list 7.51 - else _next = br; // No more in this list; just append. 7.52 - } else { // Regions overlap. 7.53 - int l = br->_offset + br->_length - _offset; 7.54 - if( l > _length ) _length = l; // Pick larger region 7.55 - FileBuffRegion *nr = br->_next; // Get rest of region 7.56 - br->_next = NULL; // Remove indication of rest of region 7.57 - delete br; // Delete this region (it's been subsumed). 7.58 - if( nr ) merge( nr ); // Merge with rest of region 7.59 - } // End of if regions overlap or not. 7.60 - } else { // "this" starts after "br" 7.61 - if( br->_offset+br->_length < _offset ) { // "br" ends before "this" 7.62 - FileBuffRegion *nr = new FileBuffRegion(_bfr,_sol,_line,_offset,_length); 7.63 - nr->_next = _next; // Structure copy "this" guy to "nr" 7.64 - *this = *br; // Structure copy "br" over "this". 7.65 - br->_next = NULL; // Remove indication of rest of region 7.66 - delete br; // Delete this region (it's been copied) 7.67 - merge( nr ); // Finish merging 7.68 - } else { // Regions overlap. 7.69 - int l = _offset + _length - br->_offset; 7.70 - if( l > _length ) _length = l; // Pick larger region 7.71 - _offset = br->_offset; // Start with earlier region 7.72 - _sol = br->_sol; // Also use earlier line start 7.73 - _line = br->_line; // Also use earlier line 7.74 - FileBuffRegion *nr = br->_next; // Get rest of region 7.75 - br->_next = NULL; // Remove indication of rest of region 7.76 - delete br; // Delete this region (it's been subsumed). 7.77 - if( nr ) merge( nr ); // Merge with rest of region 7.78 - } // End of if regions overlap or not. 7.79 - } 7.80 - return this; 7.81 -} 7.82 - 7.83 -//------------------------------expandtab-------------------------------------- 7.84 -static int expandtab( ostream &os, int off, char c, char fill1, char fill2 ) { 7.85 - if( c == '\t' ) { // Tab? 7.86 - do os << fill1; // Expand the tab; Output space 7.87 - while( (++off) & 7 ); // Expand to tab stop 7.88 - } else { // Normal character 7.89 - os << fill2; // Display normal character 7.90 - off++; // Increment "cursor" offset 7.91 - } 7.92 - return off; 7.93 -} 7.94 - 7.95 -//------------------------------printline-------------------------------------- 7.96 -// Print and highlite a region of a line. Return the amount of highliting left 7.97 -// to do (i.e. highlite length minus length of line). 7.98 -static int printline( ostream& os, const char *fname, int line, 7.99 - const char *_sol, int skip, int len ) { 7.100 - 7.101 - // Display the entire tab-expanded line 7.102 - os << fname << ":" << line << ": "; 7.103 - const char *t = strchr(_sol,'\n')+1; // End of line 7.104 - int off = 0; // Cursor offset for tab expansion 7.105 - const char *s = _sol; // Nice string pointer 7.106 - while( t-s ) { // Display whole line 7.107 - char c = *s++; // Get next character to display 7.108 - off = expandtab(os,off,c,' ',c); 7.109 - } 7.110 - 7.111 - // Display the tab-expanded skippings before underlining. 7.112 - os << fname << ":" << line << ": "; 7.113 - off = 0; // Cursor offset for tab expansion 7.114 - s = _sol; // Restart string pointer 7.115 - 7.116 - // Start underlining. 7.117 - if( skip != -1 ) { // The no-start-indicating flag 7.118 - const char *u = _sol+skip; // Amount to skip 7.119 - while( u-s ) // Display skipped part 7.120 - off = expandtab(os,off,*s++,' ',' '); 7.121 - os << '^'; // Start region 7.122 - off++; // Moved cursor 7.123 - len--; // 1 less char to do 7.124 - if( *s++ == '\t' ) // Starting character is a tab? 7.125 - off = expandtab(os,off,'\t','-','^'); 7.126 - } 7.127 - 7.128 - // Long region doesn't end on this line 7.129 - int llen = (int)(t-s); // Length of line, minus what's already done 7.130 - if( len > llen ) { // Doing entire rest of line? 7.131 - while( t-s ) // Display rest of line 7.132 - off = expandtab(os,off,*s++,'-','-'); 7.133 - os << '\n'; // EOL 7.134 - return len-llen; // Return what's not yet done. 7.135 - } 7.136 - 7.137 - // Region does end on this line. This code fails subtly if the region ends 7.138 - // in a tab character. 7.139 - int i; 7.140 - for( i=1; i<len; i++ ) // Underline just what's needed 7.141 - off = expandtab(os,off,*s++,'-','-'); 7.142 - if( i == len ) os << '^'; // Mark end of region 7.143 - os << '\n'; // End of marked line 7.144 - return 0; // All done 7.145 -} 7.146 - 7.147 -//------------------------------print------------------------------------------ 7.148 -//std::ostream& operator<< ( std::ostream& os, FileBuffRegion &br ) { 7.149 -ostream& operator<< ( ostream& os, FileBuffRegion &br ) { 7.150 - if( &br == NULL ) return os; // The empty buffer region 7.151 - FileBuffRegion *brp = &br; // Pointer to region 7.152 - while( brp ) { // While have chained regions 7.153 - brp->print(os); // Print region 7.154 - brp = brp->_next; // Chain to next 7.155 - } 7.156 - return os; // Return final stream 7.157 -} 7.158 - 7.159 -//------------------------------print------------------------------------------ 7.160 -// Print the FileBuffRegion to a stream. FileBuffRegions are printed with the 7.161 -// filename and line number to the left, and complete text lines to the right. 7.162 -// Selected portions (portions of a line actually in the FileBuffRegion are 7.163 -// underlined. Ellipses are used for long multi-line regions. 7.164 -//void FileBuffRegion::print( std::ostream& os ) { 7.165 -void FileBuffRegion::print( ostream& os ) { 7.166 - if( !this ) return; // Nothing to print 7.167 - char *s = _bfr->get_line(); 7.168 - int skip = (int)(_offset - _sol); // Amount to skip to start of data 7.169 - int len = printline( os, _bfr->_fp->_name, _line, s, skip, _length ); 7.170 - 7.171 - if( !len ) return; // All done; exit 7.172 - 7.173 - // Here we require at least 2 lines 7.174 - int off1 = _length - len + skip; // Length of line 1 7.175 - int off2 = off1 + _sol; // Offset to start of line 2 7.176 - char *s2 = _bfr->get_line(); // Start of line 2 7.177 - char *s3 = strchr( s2, '\n' )+1; // Start of line 3 (unread) 7.178 - if( len <= (s3-s2) ) { // It all fits on the next line 7.179 - printline( os, _bfr->_fp->_name, _line+1, s2, -1, len ); // Print&underline 7.180 - return; 7.181 - } 7.182 - 7.183 - // Here we require at least 3 lines 7.184 - int off3 = off2 + (int)(s3-s2); // Offset to start of line 3 7.185 - s3 = _bfr->get_line(); // Start of line 3 (read) 7.186 - const char *s4 = strchr( s3, '\n' )+1;// Start of line 4 (unread) 7.187 - if( len < (s4-s3) ) { // It all fits on the next 2 lines 7.188 - s2 = _bfr->get_line(); 7.189 - len = printline( os, _bfr->_fp->_name, _line+1, s2, -1, len ); // Line 2 7.190 - s3 = _bfr->get_line(); 7.191 - printline( os, _bfr->_fp->_name, _line+2, s3, -1, len ); // Line 3 7.192 - return; 7.193 - } 7.194 - 7.195 - // Here we require at least 4 lines. 7.196 - // Print only the 1st and last line, with ellipses in middle. 7.197 - os << "...\n"; // The ellipses 7.198 - int cline = _line+1; // Skipped 2 lines 7.199 - do { // Do until find last line 7.200 - len -= (int)(s3-s2); // Remove length of line 7.201 - cline++; // Next line 7.202 - s2 = _bfr->get_line(); // Get next line from end of this line 7.203 - s3 = strchr( s2, '\n' ) + 1;// Get end of next line 7.204 - } while( len > (s3-s2) ); // Repeat until last line 7.205 - printline( os, _bfr->_fp->_name, cline, s2, -1, len ); // Print & underline 7.206 -} 7.207 - 7.208 //------------------------------file_error------------------------------------- 7.209 void FileBuff::file_error(int flag, int linenum, const char *fmt, ...) 7.210 {
8.1 --- a/src/share/vm/adlc/filebuff.hpp Fri Jan 17 19:08:14 2020 +0000 8.2 +++ b/src/share/vm/adlc/filebuff.hpp Mon Jan 27 05:10:29 2020 +0000 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -46,7 +46,6 @@ 8.11 // This class defines a nicely behaved buffer of text. Entire file of text 8.12 // is read into buffer at creation, with sentinels at start and end. 8.13 class FileBuff { 8.14 - friend class FileBuffRegion; 8.15 private: 8.16 long _bufferSize; // Size of text holding buffer. 8.17 long _offset; // Expected filepointer offset. 8.18 @@ -82,29 +81,4 @@ 8.19 // when the pointer is valid (i.e. just obtained from getline()). 8.20 long getoff(const char* s) { return _bufoff + (long)(s - _buf); } 8.21 }; 8.22 - 8.23 -//------------------------------FileBuffRegion--------------------------------- 8.24 -// A buffer region is really a region of some file, specified as a linked list 8.25 -// of offsets and lengths. These regions can be merged; overlapping regions 8.26 -// will coalesce. 8.27 -class FileBuffRegion { 8.28 - public: // Workaround dev-studio friend/private bug 8.29 - FileBuffRegion *_next; // Linked list of regions sorted by offset. 8.30 - private: 8.31 - FileBuff *_bfr; // The Buffer of the file 8.32 - int _offset, _length; // The file area 8.33 - int _sol; // Start of line where the file area starts 8.34 - int _line; // First line of region 8.35 - 8.36 - public: 8.37 - FileBuffRegion(FileBuff*, int sol, int line, int offset, int len); 8.38 - ~FileBuffRegion(); 8.39 - 8.40 - FileBuffRegion *copy(); // Deep copy 8.41 - FileBuffRegion *merge(FileBuffRegion*); // Merge 2 regions; delete input 8.42 - 8.43 - void print(ostream&); 8.44 - friend ostream& operator<< (ostream&, FileBuffRegion&); 8.45 -}; 8.46 - 8.47 #endif // SHARE_VM_ADLC_FILEBUFF_HPP
9.1 --- a/src/share/vm/opto/c2_globals.hpp Fri Jan 17 19:08:14 2020 +0000 9.2 +++ b/src/share/vm/opto/c2_globals.hpp Mon Jan 27 05:10:29 2020 +0000 9.3 @@ -360,9 +360,6 @@ 9.4 "File to dump ideal graph to. If set overrides the " \ 9.5 "use of the network") \ 9.6 \ 9.7 - product(bool, UseOldInlining, true, \ 9.8 - "Enable the 1.3 inlining strategy") \ 9.9 - \ 9.10 product(bool, UseBimorphicInlining, true, \ 9.11 "Profiling based inlining for two receivers") \ 9.12 \
10.1 --- a/src/share/vm/opto/memnode.cpp Fri Jan 17 19:08:14 2020 +0000 10.2 +++ b/src/share/vm/opto/memnode.cpp Mon Jan 27 05:10:29 2020 +0000 10.3 @@ -2485,7 +2485,8 @@ 10.4 assert(mem != mem->in(MemNode::Memory), "dead loop in StoreNode::Ideal"); 10.5 10.6 assert(Opcode() == mem->Opcode() || 10.7 - phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw, 10.8 + phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw || 10.9 + (is_mismatched_access() || mem->as_Store()->is_mismatched_access()), 10.10 "no mismatched stores, except on raw memory"); 10.11 10.12 if (mem->outcnt() == 1 && // check for intervening uses
11.1 --- a/src/share/vm/runtime/arguments.cpp Fri Jan 17 19:08:14 2020 +0000 11.2 +++ b/src/share/vm/runtime/arguments.cpp Mon Jan 27 05:10:29 2020 +0000 11.3 @@ -302,9 +302,10 @@ 11.4 { "UsePermISM", JDK_Version::jdk(8), JDK_Version::jdk(9) }, 11.5 { "UseMPSS", JDK_Version::jdk(8), JDK_Version::jdk(9) }, 11.6 { "UseStringCache", JDK_Version::jdk(8), JDK_Version::jdk(9) }, 11.7 - { "UseOldInlining", JDK_Version::jdk(9), JDK_Version::jdk(10) }, 11.8 - { "AutoShutdownNMT", JDK_Version::jdk(9), JDK_Version::jdk(10) }, 11.9 + { "UseOldInlining", JDK_Version::jdk_update(8, 20), JDK_Version::jdk(10) }, 11.10 + { "AutoShutdownNMT", JDK_Version::jdk_update(8, 40), JDK_Version::jdk(10) }, 11.11 { "CompilationRepeat", JDK_Version::jdk(8), JDK_Version::jdk(9) }, 11.12 + { "SegmentedHeapDumpThreshold", JDK_Version::jdk_update(8, 252), JDK_Version::jdk(10) }, 11.13 #ifdef PRODUCT 11.14 { "DesiredMethodLimit", 11.15 JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
12.1 --- a/src/share/vm/runtime/vmThread.cpp Fri Jan 17 19:08:14 2020 +0000 12.2 +++ b/src/share/vm/runtime/vmThread.cpp Mon Jan 27 05:10:29 2020 +0000 12.3 @@ -507,6 +507,7 @@ 12.4 _cur_vm_operation = safepoint_ops; 12.5 if (_cur_vm_operation != NULL) { 12.6 do { 12.7 + EventMark em("Executing coalesced safepoint VM operation: %s", _cur_vm_operation->name()); 12.8 // evaluate_operation deletes the op object so we have 12.9 // to grab the next op now 12.10 VM_Operation* next = _cur_vm_operation->next();
13.1 --- a/src/share/vm/services/heapDumper.cpp Fri Jan 17 19:08:14 2020 +0000 13.2 +++ b/src/share/vm/services/heapDumper.cpp Mon Jan 27 05:10:29 2020 +0000 13.3 @@ -50,8 +50,7 @@ 13.4 * src/share/demo/jvmti/hprof/hprof_io.c 13.5 * 13.6 * 13.7 - * header "JAVA PROFILE 1.0.1" or "JAVA PROFILE 1.0.2" 13.8 - * (0-terminated) 13.9 + * header "JAVA PROFILE 1.0.2" (0-terminated) 13.10 * 13.11 * u4 size of identifiers. Identifiers are used to represent 13.12 * UTF8 strings, objects, stack traces, etc. They usually 13.13 @@ -382,6 +381,8 @@ 13.14 size_t _size; 13.15 size_t _pos; 13.16 13.17 + jlong _dump_start; 13.18 + 13.19 char* _error; // error message when I/O fails 13.20 13.21 void set_file_descriptor(int fd) { _fd = fd; } 13.22 @@ -405,6 +406,10 @@ 13.23 bool is_open() const { return file_descriptor() >= 0; } 13.24 void flush(); 13.25 13.26 + jlong dump_start() const { return _dump_start; } 13.27 + void set_dump_start(jlong pos); 13.28 + julong current_record_length(); 13.29 + 13.30 // total number of bytes written to the disk 13.31 julong bytes_written() const { return _bytes_written; } 13.32 13.33 @@ -446,6 +451,7 @@ 13.34 _pos = 0; 13.35 _error = NULL; 13.36 _bytes_written = 0L; 13.37 + _dump_start = (jlong)-1; 13.38 _fd = os::create_binary_file(path, false); // don't replace existing file 13.39 13.40 // if the open failed we record the error 13.41 @@ -473,6 +479,22 @@ 13.42 } 13.43 } 13.44 13.45 +// sets the dump starting position 13.46 +void DumpWriter::set_dump_start(jlong pos) { 13.47 + _dump_start = pos; 13.48 +} 13.49 + 13.50 +julong DumpWriter::current_record_length() { 13.51 + if (is_open()) { 13.52 + // calculate the size of the dump record 13.53 + julong dump_end = bytes_written() + bytes_unwritten(); 13.54 + assert(dump_end == (size_t)current_offset(), "checking"); 13.55 + julong dump_len = dump_end - dump_start() - 4; 13.56 + return dump_len; 13.57 + } 13.58 + return 0; 13.59 +} 13.60 + 13.61 // write directly to the file 13.62 void DumpWriter::write_internal(void* s, size_t len) { 13.63 if (is_open()) { 13.64 @@ -641,6 +663,18 @@ 13.65 static void dump_prim_array(DumpWriter* writer, typeArrayOop array); 13.66 // create HPROF_FRAME record for the given method and bci 13.67 static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci); 13.68 + 13.69 + // check if we need to truncate an array 13.70 + static int calculate_array_max_length(DumpWriter* writer, arrayOop array, short header_size); 13.71 + 13.72 + // writes a HPROF_HEAP_DUMP_SEGMENT record 13.73 + static void write_dump_header(DumpWriter* writer); 13.74 + 13.75 + // fixes up the length of the current dump record 13.76 + static void write_current_dump_record_length(DumpWriter* writer); 13.77 + 13.78 + // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record 13.79 + static void end_of_dump(DumpWriter* writer); 13.80 }; 13.81 13.82 // write a header of the given type 13.83 @@ -1047,50 +1081,103 @@ 13.84 } 13.85 } 13.86 13.87 +// Hprof uses an u4 as record length field, 13.88 +// which means we need to truncate arrays that are too long. 13.89 +int DumperSupport::calculate_array_max_length(DumpWriter* writer, arrayOop array, short header_size) { 13.90 + BasicType type = ArrayKlass::cast(array->klass())->element_type(); 13.91 + assert(type >= T_BOOLEAN && type <= T_OBJECT, "invalid array element type"); 13.92 + 13.93 + int length = array->length(); 13.94 + 13.95 + int type_size; 13.96 + if (type == T_OBJECT) { 13.97 + type_size = sizeof(address); 13.98 + } else { 13.99 + type_size = type2aelembytes(type); 13.100 + } 13.101 + 13.102 + size_t length_in_bytes = (size_t)length * type_size; 13.103 + 13.104 + // Create a new record if the current record is non-empty and the array can't fit. 13.105 + julong current_record_length = writer->current_record_length(); 13.106 + if (current_record_length > 0 && 13.107 + (current_record_length + header_size + length_in_bytes) > max_juint) { 13.108 + write_current_dump_record_length(writer); 13.109 + write_dump_header(writer); 13.110 + 13.111 + // We now have an empty record. 13.112 + current_record_length = 0; 13.113 + } 13.114 + 13.115 + // Calculate max bytes we can use. 13.116 + uint max_bytes = max_juint - (header_size + current_record_length); 13.117 + 13.118 + // Array too long for the record? 13.119 + // Calculate max length and return it. 13.120 + if (length_in_bytes > max_bytes) { 13.121 + length = max_bytes / type_size; 13.122 + length_in_bytes = (size_t)length * type_size; 13.123 + 13.124 + warning("cannot dump array of type %s[] with length %d; truncating to length %d", 13.125 + type2name_tab[type], array->length(), length); 13.126 + } 13.127 + return length; 13.128 +} 13.129 + 13.130 // creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array 13.131 void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) { 13.132 + // sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID) + sizeof(classID) 13.133 + short header_size = 1 + 2 * 4 + 2 * sizeof(address); 13.134 + 13.135 + int length = calculate_array_max_length(writer, array, header_size); 13.136 13.137 writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP); 13.138 writer->write_objectID(array); 13.139 writer->write_u4(STACK_TRACE_ID); 13.140 - writer->write_u4((u4)array->length()); 13.141 + writer->write_u4(length); 13.142 + 13.143 13.144 // array class ID 13.145 writer->write_classID(array->klass()); 13.146 13.147 // [id]* elements 13.148 - for (int index=0; index<array->length(); index++) { 13.149 + for (int index = 0; index < length; index++) { 13.150 oop o = array->obj_at(index); 13.151 writer->write_objectID(o); 13.152 } 13.153 } 13.154 13.155 -#define WRITE_ARRAY(Array, Type, Size) \ 13.156 - for (int i=0; i<Array->length(); i++) { writer->write_##Size((Size)array->Type##_at(i)); } 13.157 - 13.158 +#define WRITE_ARRAY(Array, Type, Size, Length) \ 13.159 + for (int i = 0; i < Length; i++) { writer->write_##Size((Size)array->Type##_at(i)); } 13.160 13.161 // creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array 13.162 void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) { 13.163 BasicType type = TypeArrayKlass::cast(array->klass())->element_type(); 13.164 13.165 + // 2 * sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID) 13.166 + short header_size = 2 * 1 + 2 * 4 + sizeof(address); 13.167 + 13.168 + int length = calculate_array_max_length(writer, array, header_size); 13.169 + int type_size = type2aelembytes(type); 13.170 + u4 length_in_bytes = (u4)length * type_size; 13.171 + 13.172 writer->write_u1(HPROF_GC_PRIM_ARRAY_DUMP); 13.173 writer->write_objectID(array); 13.174 writer->write_u4(STACK_TRACE_ID); 13.175 - writer->write_u4((u4)array->length()); 13.176 + writer->write_u4(length); 13.177 writer->write_u1(type2tag(type)); 13.178 13.179 // nothing to copy 13.180 - if (array->length() == 0) { 13.181 + if (length == 0) { 13.182 return; 13.183 } 13.184 13.185 // If the byte ordering is big endian then we can copy most types directly 13.186 - u4 length_in_bytes = (u4)array->length() * type2aelembytes(type); 13.187 13.188 switch (type) { 13.189 case T_INT : { 13.190 if (Bytes::is_Java_byte_ordering_different()) { 13.191 - WRITE_ARRAY(array, int, u4); 13.192 + WRITE_ARRAY(array, int, u4, length); 13.193 } else { 13.194 writer->write_raw((void*)(array->int_at_addr(0)), length_in_bytes); 13.195 } 13.196 @@ -1102,7 +1189,7 @@ 13.197 } 13.198 case T_CHAR : { 13.199 if (Bytes::is_Java_byte_ordering_different()) { 13.200 - WRITE_ARRAY(array, char, u2); 13.201 + WRITE_ARRAY(array, char, u2, length); 13.202 } else { 13.203 writer->write_raw((void*)(array->char_at_addr(0)), length_in_bytes); 13.204 } 13.205 @@ -1110,7 +1197,7 @@ 13.206 } 13.207 case T_SHORT : { 13.208 if (Bytes::is_Java_byte_ordering_different()) { 13.209 - WRITE_ARRAY(array, short, u2); 13.210 + WRITE_ARRAY(array, short, u2, length); 13.211 } else { 13.212 writer->write_raw((void*)(array->short_at_addr(0)), length_in_bytes); 13.213 } 13.214 @@ -1118,7 +1205,7 @@ 13.215 } 13.216 case T_BOOLEAN : { 13.217 if (Bytes::is_Java_byte_ordering_different()) { 13.218 - WRITE_ARRAY(array, bool, u1); 13.219 + WRITE_ARRAY(array, bool, u1, length); 13.220 } else { 13.221 writer->write_raw((void*)(array->bool_at_addr(0)), length_in_bytes); 13.222 } 13.223 @@ -1126,7 +1213,7 @@ 13.224 } 13.225 case T_LONG : { 13.226 if (Bytes::is_Java_byte_ordering_different()) { 13.227 - WRITE_ARRAY(array, long, u8); 13.228 + WRITE_ARRAY(array, long, u8, length); 13.229 } else { 13.230 writer->write_raw((void*)(array->long_at_addr(0)), length_in_bytes); 13.231 } 13.232 @@ -1138,14 +1225,14 @@ 13.233 // use IEEE 754. 13.234 13.235 case T_FLOAT : { 13.236 - for (int i=0; i<array->length(); i++) { 13.237 - dump_float( writer, array->float_at(i) ); 13.238 + for (int i = 0; i < length; i++) { 13.239 + dump_float(writer, array->float_at(i)); 13.240 } 13.241 break; 13.242 } 13.243 case T_DOUBLE : { 13.244 - for (int i=0; i<array->length(); i++) { 13.245 - dump_double( writer, array->double_at(i) ); 13.246 + for (int i = 0; i < length; i++) { 13.247 + dump_double(writer, array->double_at(i)); 13.248 } 13.249 break; 13.250 } 13.251 @@ -1362,8 +1449,6 @@ 13.252 JavaThread* _oome_thread; 13.253 Method* _oome_constructor; 13.254 bool _gc_before_heap_dump; 13.255 - bool _is_segmented_dump; 13.256 - jlong _dump_start; 13.257 GrowableArray<Klass*>* _klass_map; 13.258 ThreadStackTrace** _stack_traces; 13.259 int _num_threads; 13.260 @@ -1382,11 +1467,6 @@ 13.261 void clear_global_dumper() { _global_dumper = NULL; } 13.262 void clear_global_writer() { _global_writer = NULL; } 13.263 13.264 - bool is_segmented_dump() const { return _is_segmented_dump; } 13.265 - void set_segmented_dump() { _is_segmented_dump = true; } 13.266 - jlong dump_start() const { return _dump_start; } 13.267 - void set_dump_start(jlong pos); 13.268 - 13.269 bool skip_operation() const; 13.270 13.271 // writes a HPROF_LOAD_CLASS record 13.272 @@ -1411,16 +1491,6 @@ 13.273 // HPROF_TRACE and HPROF_FRAME records 13.274 void dump_stack_traces(); 13.275 13.276 - // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record 13.277 - void write_dump_header(); 13.278 - 13.279 - // fixes up the length of the current dump record 13.280 - void write_current_dump_record_length(); 13.281 - 13.282 - // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END 13.283 - // record in the case of a segmented heap dump) 13.284 - void end_of_dump(); 13.285 - 13.286 public: 13.287 VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome) : 13.288 VM_GC_Operation(0 /* total collections, dummy, ignored */, 13.289 @@ -1429,8 +1499,6 @@ 13.290 gc_before_heap_dump) { 13.291 _local_writer = writer; 13.292 _gc_before_heap_dump = gc_before_heap_dump; 13.293 - _is_segmented_dump = false; 13.294 - _dump_start = (jlong)-1; 13.295 _klass_map = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true); 13.296 _stack_traces = NULL; 13.297 _num_threads = 0; 13.298 @@ -1470,35 +1538,23 @@ 13.299 return false; 13.300 } 13.301 13.302 -// sets the dump starting position 13.303 -void VM_HeapDumper::set_dump_start(jlong pos) { 13.304 - _dump_start = pos; 13.305 -} 13.306 - 13.307 - // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record 13.308 -void VM_HeapDumper::write_dump_header() { 13.309 - if (writer()->is_open()) { 13.310 - if (is_segmented_dump()) { 13.311 - writer()->write_u1(HPROF_HEAP_DUMP_SEGMENT); 13.312 - } else { 13.313 - writer()->write_u1(HPROF_HEAP_DUMP); 13.314 - } 13.315 - writer()->write_u4(0); // current ticks 13.316 + // writes a HPROF_HEAP_DUMP_SEGMENT record 13.317 +void DumperSupport::write_dump_header(DumpWriter* writer) { 13.318 + if (writer->is_open()) { 13.319 + writer->write_u1(HPROF_HEAP_DUMP_SEGMENT); 13.320 + writer->write_u4(0); // current ticks 13.321 13.322 // record the starting position for the dump (its length will be fixed up later) 13.323 - set_dump_start(writer()->current_offset()); 13.324 - writer()->write_u4(0); 13.325 + writer->set_dump_start(writer->current_offset()); 13.326 + writer->write_u4(0); 13.327 } 13.328 } 13.329 13.330 // fixes up the length of the current dump record 13.331 -void VM_HeapDumper::write_current_dump_record_length() { 13.332 - if (writer()->is_open()) { 13.333 - assert(dump_start() >= 0, "no dump start recorded"); 13.334 - 13.335 - // calculate the size of the dump record 13.336 - julong dump_end = writer()->current_offset(); 13.337 - julong dump_len = (dump_end - dump_start() - 4); 13.338 +void DumperSupport::write_current_dump_record_length(DumpWriter* writer) { 13.339 + if (writer->is_open()) { 13.340 + julong dump_end = writer->bytes_written() + writer->bytes_unwritten(); 13.341 + julong dump_len = writer->current_record_length(); 13.342 13.343 // record length must fit in a u4 13.344 if (dump_len > max_juint) { 13.345 @@ -1506,17 +1562,18 @@ 13.346 } 13.347 13.348 // seek to the dump start and fix-up the length 13.349 - writer()->seek_to_offset(dump_start()); 13.350 - writer()->write_u4((u4)dump_len); 13.351 + assert(writer->dump_start() >= 0, "no dump start recorded"); 13.352 + writer->seek_to_offset(writer->dump_start()); 13.353 + writer->write_u4((u4)dump_len); 13.354 13.355 // adjust the total size written to keep the bytes written correct. 13.356 - writer()->adjust_bytes_written(-((jlong) sizeof(u4))); 13.357 + writer->adjust_bytes_written(-((jlong) sizeof(u4))); 13.358 13.359 // seek to dump end so we can continue 13.360 - writer()->seek_to_offset(dump_end); 13.361 + writer->seek_to_offset(dump_end); 13.362 13.363 // no current dump record 13.364 - set_dump_start((jlong)-1); 13.365 + writer->set_dump_start((jlong)-1); 13.366 } 13.367 } 13.368 13.369 @@ -1524,33 +1581,23 @@ 13.370 // new segment. 13.371 void VM_HeapDumper::check_segment_length() { 13.372 if (writer()->is_open()) { 13.373 - if (is_segmented_dump()) { 13.374 - // don't use current_offset that would be too expensive on a per record basis 13.375 - julong dump_end = writer()->bytes_written() + writer()->bytes_unwritten(); 13.376 - assert(dump_end == (julong)writer()->current_offset(), "checking"); 13.377 - julong dump_len = (dump_end - dump_start() - 4); 13.378 - assert(dump_len <= max_juint, "bad dump length"); 13.379 + julong dump_len = writer()->current_record_length(); 13.380 13.381 - if (dump_len > HeapDumpSegmentSize) { 13.382 - write_current_dump_record_length(); 13.383 - write_dump_header(); 13.384 - } 13.385 + if (dump_len > 2UL*G) { 13.386 + DumperSupport::write_current_dump_record_length(writer()); 13.387 + DumperSupport::write_dump_header(writer()); 13.388 } 13.389 } 13.390 } 13.391 13.392 -// fixes up the current dump record )and writes HPROF_HEAP_DUMP_END 13.393 -// record in the case of a segmented heap dump) 13.394 -void VM_HeapDumper::end_of_dump() { 13.395 - if (writer()->is_open()) { 13.396 - write_current_dump_record_length(); 13.397 +// fixes up the current dump record and writes HPROF_HEAP_DUMP_END record 13.398 +void DumperSupport::end_of_dump(DumpWriter* writer) { 13.399 + if (writer->is_open()) { 13.400 + write_current_dump_record_length(writer); 13.401 13.402 - // for segmented dump we write the end record 13.403 - if (is_segmented_dump()) { 13.404 - writer()->write_u1(HPROF_HEAP_DUMP_END); 13.405 - writer()->write_u4(0); 13.406 - writer()->write_u4(0); 13.407 - } 13.408 + writer->write_u1(HPROF_HEAP_DUMP_END); 13.409 + writer->write_u4(0); 13.410 + writer->write_u4(0); 13.411 } 13.412 } 13.413 13.414 @@ -1716,16 +1763,17 @@ 13.415 // [HPROF_LOAD_CLASS]* 13.416 // [[HPROF_FRAME]*|HPROF_TRACE]* 13.417 // [HPROF_GC_CLASS_DUMP]* 13.418 -// HPROF_HEAP_DUMP 13.419 +// [HPROF_HEAP_DUMP_SEGMENT]* 13.420 +// HPROF_HEAP_DUMP_END 13.421 // 13.422 // The HPROF_TRACE records represent the stack traces where the heap dump 13.423 // is generated and a "dummy trace" record which does not include 13.424 // any frames. The dummy trace record is used to be referenced as the 13.425 // unknown object alloc site. 13.426 // 13.427 -// The HPROF_HEAP_DUMP record has a length following by sub-records. To allow 13.428 -// the heap dump be generated in a single pass we remember the position of 13.429 -// the dump length and fix it up after all sub-records have been written. 13.430 +// Each HPROF_HEAP_DUMP_SEGMENT record has a length followed by sub-records. 13.431 +// To allow the heap dump be generated in a single pass we remember the position 13.432 +// of the dump length and fix it up after all sub-records have been written. 13.433 // To generate the sub-records we iterate over the heap, writing 13.434 // HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP 13.435 // records as we go. Once that is done we write records for some of the GC 13.436 @@ -1752,15 +1800,9 @@ 13.437 set_global_dumper(); 13.438 set_global_writer(); 13.439 13.440 - // Write the file header - use 1.0.2 for large heaps, otherwise 1.0.1 13.441 + // Write the file header - we always use 1.0.2 13.442 size_t used = ch->used(); 13.443 - const char* header; 13.444 - if (used > (size_t)SegmentedHeapDumpThreshold) { 13.445 - set_segmented_dump(); 13.446 - header = "JAVA PROFILE 1.0.2"; 13.447 - } else { 13.448 - header = "JAVA PROFILE 1.0.1"; 13.449 - } 13.450 + const char* header = "JAVA PROFILE 1.0.2"; 13.451 13.452 // header is few bytes long - no chance to overflow int 13.453 writer()->write_raw((void*)header, (int)strlen(header)); 13.454 @@ -1780,8 +1822,8 @@ 13.455 // this must be called after _klass_map is built when iterating the classes above. 13.456 dump_stack_traces(); 13.457 13.458 - // write HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT 13.459 - write_dump_header(); 13.460 + // write HPROF_HEAP_DUMP_SEGMENT 13.461 + DumperSupport::write_dump_header(writer()); 13.462 13.463 // Writes HPROF_GC_CLASS_DUMP records 13.464 ClassLoaderDataGraph::classes_do(&do_class_dump); 13.465 @@ -1789,9 +1831,9 @@ 13.466 check_segment_length(); 13.467 13.468 // writes HPROF_GC_INSTANCE_DUMP records. 13.469 - // After each sub-record is written check_segment_length will be invoked. When 13.470 - // generated a segmented heap dump this allows us to check if the current 13.471 - // segment exceeds a threshold and if so, then a new segment is started. 13.472 + // After each sub-record is written check_segment_length will be invoked 13.473 + // to check if the current segment exceeds a threshold. If so, a new 13.474 + // segment is started. 13.475 // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk 13.476 // of the heap dump. 13.477 HeapObjectDumper obj_dumper(this, writer()); 13.478 @@ -1817,9 +1859,8 @@ 13.479 StickyClassDumper class_dumper(writer()); 13.480 SystemDictionary::always_strong_classes_do(&class_dumper); 13.481 13.482 - // fixes up the length of the dump record. In the case of a segmented 13.483 - // heap then the HPROF_HEAP_DUMP_END record is also written. 13.484 - end_of_dump(); 13.485 + // fixes up the length of the dump record and writes the HPROF_HEAP_DUMP_END record. 13.486 + DumperSupport::end_of_dump(writer()); 13.487 13.488 // Now we clear the global variables, so that a future dumper might run. 13.489 clear_global_dumper();
14.1 --- a/src/share/vm/utilities/vmError.cpp Fri Jan 17 19:08:14 2020 +0000 14.2 +++ b/src/share/vm/utilities/vmError.cpp Mon Jan 27 05:10:29 2020 +0000 14.3 @@ -1060,7 +1060,7 @@ 14.4 out.print_raw (cmd); 14.5 out.print_raw_cr("\" ..."); 14.6 14.7 - if (os::fork_and_exec(cmd, true) < 0) { 14.8 + if (os::fork_and_exec(cmd) < 0) { 14.9 out.print_cr("os::fork_and_exec failed: %s (%d)", strerror(errno), errno); 14.10 } 14.11 } 14.12 @@ -1147,7 +1147,7 @@ 14.13 #endif 14.14 tty->print_cr("\"%s\"...", cmd); 14.15 14.16 - if (os::fork_and_exec(cmd) < 0) { 14.17 + if (os::fork_and_exec(cmd, true) < 0) { 14.18 tty->print_cr("os::fork_and_exec failed: %s (%d)", strerror(errno), errno); 14.19 } 14.20 }