Mercurial > hg > truffle
annotate src/share/vm/adlc/filebuff.cpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | f95d63e2154a |
children |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
605
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
605
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
605
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 // FILEBUFF.CPP - Routines for handling a parser file buffer | |
26 #include "adlc.hpp" | |
27 | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
470
diff
changeset
|
28 using namespace std; |
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
470
diff
changeset
|
29 |
0 | 30 //------------------------------FileBuff--------------------------------------- |
31 // Create a new parsing buffer | |
32 FileBuff::FileBuff( BufferedFile *fptr, ArchDesc& archDesc) : _fp(fptr), _AD(archDesc) { | |
33 _err = fseek(_fp->_fp, 0, SEEK_END); // Seek to end of file | |
34 if (_err) { | |
35 file_error(SEMERR, 0, "File seek error reading input file"); | |
36 exit(1); // Exit on seek error | |
37 } | |
38 _filepos = ftell(_fp->_fp); // Find offset of end of file | |
39 _bufferSize = _filepos + 5; // Filepos points to last char, so add padding | |
40 _err = fseek(_fp->_fp, 0, SEEK_SET); // Reset to beginning of file | |
41 if (_err) { | |
42 file_error(SEMERR, 0, "File seek error reading input file\n"); | |
43 exit(1); // Exit on seek error | |
44 } | |
45 _filepos = ftell(_fp->_fp); // Reset current file position | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
0
diff
changeset
|
46 _linenum = 0; |
0 | 47 |
48 _bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser | |
49 if( !_bigbuf ) { | |
50 file_error(SEMERR, 0, "Buffer allocation failed\n"); | |
51 exit(1); // Exit on allocation failure | |
52 } | |
605 | 53 *_bigbuf = '\n'; // Lead with a sentinel newline |
54 _buf = _bigbuf+1; // Skip sentinel | |
0 | 55 _bufmax = _buf; // Buffer is empty |
605 | 56 _bufeol = _bigbuf; // _bufeol points at sentinel |
0 | 57 _filepos = -1; // filepos is in sync with _bufeol |
58 _bufoff = _offset = 0L; // Offset at file start | |
59 | |
60 _bufmax += fread(_buf, 1, _bufferSize-2, _fp->_fp); // Fill buffer & set end value | |
61 if (_bufmax == _buf) { | |
62 file_error(SEMERR, 0, "File read error, no input read\n"); | |
63 exit(1); // Exit on read error | |
64 } | |
605 | 65 *_bufmax = '\n'; // End with a sentinel new-line |
66 *(_bufmax+1) = '\0'; // Then end with a sentinel NULL | |
0 | 67 } |
68 | |
69 //------------------------------~FileBuff-------------------------------------- | |
70 // Nuke the FileBuff | |
71 FileBuff::~FileBuff() { | |
72 delete _bigbuf; | |
73 } | |
74 | |
75 //------------------------------get_line---------------------------------------- | |
76 char *FileBuff::get_line(void) { | |
77 char *retval; | |
78 | |
79 // Check for end of file & return NULL | |
80 if (_bufeol >= _bufmax) return NULL; | |
81 | |
415
4d9884b01ba6
6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents:
0
diff
changeset
|
82 _linenum++; |
0 | 83 retval = ++_bufeol; // return character following end of previous line |
605 | 84 if (*retval == '\0') return NULL; // Check for EOF sentinel |
0 | 85 // Search for newline character which must end each line |
86 for(_filepos++; *_bufeol != '\n'; _bufeol++) | |
87 _filepos++; // keep filepos in sync with _bufeol | |
88 // _bufeol & filepos point at end of current line, so return pointer to start | |
89 return retval; | |
90 } | |
91 | |
92 //------------------------------FileBuffRegion--------------------------------- | |
93 // Create a new region in a FileBuff. | |
94 FileBuffRegion::FileBuffRegion( FileBuff* bufr, int soln, int ln, | |
95 int off, int len) | |
96 : _bfr(bufr), _sol(soln), _line(ln), _offset(off), _length(len) { | |
97 _next = NULL; // No chained regions | |
98 } | |
99 | |
100 //------------------------------~FileBuffRegion-------------------------------- | |
101 // Delete the entire linked list of buffer regions. | |
102 FileBuffRegion::~FileBuffRegion() { | |
103 if( _next ) delete _next; | |
104 } | |
105 | |
106 //------------------------------copy------------------------------------------- | |
107 // Deep copy a FileBuffRegion | |
108 FileBuffRegion *FileBuffRegion::copy() { | |
109 if( !this ) return NULL; // The empty buffer region | |
110 FileBuffRegion *br = new FileBuffRegion(_bfr,_sol,_line,_offset,_length); | |
111 if( _next ) br->_next = _next->copy(); | |
112 return br; | |
113 } | |
114 | |
115 //------------------------------merge------------------------------------------ | |
116 // Merge another buffer region into this buffer region. Make overlapping areas | |
117 // become a single region. Remove (delete) the input FileBuffRegion. | |
118 // Since the buffer regions are sorted by file offset, this is a varient of a | |
119 // "sorted-merge" running in linear time. | |
120 FileBuffRegion *FileBuffRegion::merge( FileBuffRegion *br ) { | |
121 if( !br ) return this; // Merging nothing | |
122 if( !this ) return br; // Merging into nothing | |
123 | |
124 assert( _bfr == br->_bfr, "" ); // Check for pointer-equivalent buffers | |
125 | |
126 if( _offset < br->_offset ) { // "this" starts before "br" | |
127 if( _offset+_length < br->_offset ) { // "this" ends before "br" | |
128 if( _next ) _next->merge( br ); // Merge with remainder of list | |
129 else _next = br; // No more in this list; just append. | |
130 } else { // Regions overlap. | |
131 int l = br->_offset + br->_length - _offset; | |
132 if( l > _length ) _length = l; // Pick larger region | |
133 FileBuffRegion *nr = br->_next; // Get rest of region | |
134 br->_next = NULL; // Remove indication of rest of region | |
135 delete br; // Delete this region (it's been subsumed). | |
136 if( nr ) merge( nr ); // Merge with rest of region | |
137 } // End of if regions overlap or not. | |
138 } else { // "this" starts after "br" | |
139 if( br->_offset+br->_length < _offset ) { // "br" ends before "this" | |
140 FileBuffRegion *nr = new FileBuffRegion(_bfr,_sol,_line,_offset,_length); | |
141 nr->_next = _next; // Structure copy "this" guy to "nr" | |
142 *this = *br; // Structure copy "br" over "this". | |
143 br->_next = NULL; // Remove indication of rest of region | |
144 delete br; // Delete this region (it's been copied) | |
145 merge( nr ); // Finish merging | |
146 } else { // Regions overlap. | |
147 int l = _offset + _length - br->_offset; | |
148 if( l > _length ) _length = l; // Pick larger region | |
149 _offset = br->_offset; // Start with earlier region | |
150 _sol = br->_sol; // Also use earlier line start | |
151 _line = br->_line; // Also use earlier line | |
152 FileBuffRegion *nr = br->_next; // Get rest of region | |
153 br->_next = NULL; // Remove indication of rest of region | |
154 delete br; // Delete this region (it's been subsumed). | |
155 if( nr ) merge( nr ); // Merge with rest of region | |
156 } // End of if regions overlap or not. | |
157 } | |
158 return this; | |
159 } | |
160 | |
161 //------------------------------expandtab-------------------------------------- | |
162 static int expandtab( ostream &os, int off, char c, char fill1, char fill2 ) { | |
163 if( c == '\t' ) { // Tab? | |
164 do os << fill1; // Expand the tab; Output space | |
165 while( (++off) & 7 ); // Expand to tab stop | |
166 } else { // Normal character | |
167 os << fill2; // Display normal character | |
168 off++; // Increment "cursor" offset | |
169 } | |
170 return off; | |
171 } | |
172 | |
173 //------------------------------printline-------------------------------------- | |
174 // Print and highlite a region of a line. Return the amount of highliting left | |
175 // to do (i.e. highlite length minus length of line). | |
176 static int printline( ostream& os, const char *fname, int line, | |
177 const char *_sol, int skip, int len ) { | |
178 | |
179 // Display the entire tab-expanded line | |
180 os << fname << ":" << line << ": "; | |
181 const char *t = strchr(_sol,'\n')+1; // End of line | |
182 int off = 0; // Cursor offset for tab expansion | |
183 const char *s = _sol; // Nice string pointer | |
184 while( t-s ) { // Display whole line | |
185 char c = *s++; // Get next character to display | |
186 off = expandtab(os,off,c,' ',c); | |
187 } | |
188 | |
189 // Display the tab-expanded skippings before underlining. | |
190 os << fname << ":" << line << ": "; | |
191 off = 0; // Cursor offset for tab expansion | |
192 s = _sol; // Restart string pointer | |
193 | |
194 // Start underlining. | |
195 if( skip != -1 ) { // The no-start-indicating flag | |
196 const char *u = _sol+skip; // Amount to skip | |
197 while( u-s ) // Display skipped part | |
198 off = expandtab(os,off,*s++,' ',' '); | |
199 os << '^'; // Start region | |
200 off++; // Moved cursor | |
201 len--; // 1 less char to do | |
202 if( *s++ == '\t' ) // Starting character is a tab? | |
203 off = expandtab(os,off,'\t','-','^'); | |
204 } | |
205 | |
206 // Long region doesn't end on this line | |
207 int llen = (int)(t-s); // Length of line, minus what's already done | |
208 if( len > llen ) { // Doing entire rest of line? | |
209 while( t-s ) // Display rest of line | |
210 off = expandtab(os,off,*s++,'-','-'); | |
211 os << '\n'; // EOL | |
212 return len-llen; // Return what's not yet done. | |
213 } | |
214 | |
215 // Region does end on this line. This code fails subtly if the region ends | |
216 // in a tab character. | |
217 int i; | |
218 for( i=1; i<len; i++ ) // Underline just what's needed | |
219 off = expandtab(os,off,*s++,'-','-'); | |
220 if( i == len ) os << '^'; // Mark end of region | |
221 os << '\n'; // End of marked line | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
470
diff
changeset
|
222 return 0; // All done |
0 | 223 } |
224 | |
225 //------------------------------print------------------------------------------ | |
226 //std::ostream& operator<< ( std::ostream& os, FileBuffRegion &br ) { | |
227 ostream& operator<< ( ostream& os, FileBuffRegion &br ) { | |
228 if( &br == NULL ) return os; // The empty buffer region | |
229 FileBuffRegion *brp = &br; // Pointer to region | |
230 while( brp ) { // While have chained regions | |
231 brp->print(os); // Print region | |
232 brp = brp->_next; // Chain to next | |
233 } | |
234 return os; // Return final stream | |
235 } | |
236 | |
237 //------------------------------print------------------------------------------ | |
238 // Print the FileBuffRegion to a stream. FileBuffRegions are printed with the | |
239 // filename and line number to the left, and complete text lines to the right. | |
240 // Selected portions (portions of a line actually in the FileBuffRegion are | |
241 // underlined. Ellipses are used for long multi-line regions. | |
242 //void FileBuffRegion::print( std::ostream& os ) { | |
243 void FileBuffRegion::print( ostream& os ) { | |
244 if( !this ) return; // Nothing to print | |
245 char *s = _bfr->get_line(); | |
246 int skip = (int)(_offset - _sol); // Amount to skip to start of data | |
247 int len = printline( os, _bfr->_fp->_name, _line, s, skip, _length ); | |
248 | |
249 if( !len ) return; // All done; exit | |
250 | |
251 // Here we require at least 2 lines | |
252 int off1 = _length - len + skip; // Length of line 1 | |
253 int off2 = off1 + _sol; // Offset to start of line 2 | |
254 char *s2 = _bfr->get_line(); // Start of line 2 | |
255 char *s3 = strchr( s2, '\n' )+1; // Start of line 3 (unread) | |
256 if( len <= (s3-s2) ) { // It all fits on the next line | |
257 printline( os, _bfr->_fp->_name, _line+1, s2, -1, len ); // Print&underline | |
258 return; | |
259 } | |
260 | |
261 // Here we require at least 3 lines | |
262 int off3 = off2 + (int)(s3-s2); // Offset to start of line 3 | |
263 s3 = _bfr->get_line(); // Start of line 3 (read) | |
264 const char *s4 = strchr( s3, '\n' )+1;// Start of line 4 (unread) | |
265 if( len < (s4-s3) ) { // It all fits on the next 2 lines | |
266 s2 = _bfr->get_line(); | |
267 len = printline( os, _bfr->_fp->_name, _line+1, s2, -1, len ); // Line 2 | |
268 s3 = _bfr->get_line(); | |
269 printline( os, _bfr->_fp->_name, _line+2, s3, -1, len ); // Line 3 | |
270 return; | |
271 } | |
272 | |
273 // Here we require at least 4 lines. | |
274 // Print only the 1st and last line, with ellipses in middle. | |
275 os << "...\n"; // The ellipses | |
276 int cline = _line+1; // Skipped 2 lines | |
277 do { // Do until find last line | |
278 len -= (int)(s3-s2); // Remove length of line | |
279 cline++; // Next line | |
280 s2 = _bfr->get_line(); // Get next line from end of this line | |
281 s3 = strchr( s2, '\n' ) + 1;// Get end of next line | |
282 } while( len > (s3-s2) ); // Repeat until last line | |
283 printline( os, _bfr->_fp->_name, cline, s2, -1, len ); // Print & underline | |
284 } | |
285 | |
286 //------------------------------file_error------------------------------------- | |
287 void FileBuff::file_error(int flag, int linenum, const char *fmt, ...) | |
288 { | |
289 va_list args; | |
290 | |
291 va_start(args, fmt); | |
292 switch (flag) { | |
293 case 0: _AD._warnings += _AD.emit_msg(0, flag, linenum, fmt, args); | |
294 case 1: _AD._syntax_errs += _AD.emit_msg(0, flag, linenum, fmt, args); | |
295 case 2: _AD._semantic_errs += _AD.emit_msg(0, flag, linenum, fmt, args); | |
296 default: assert(0, ""); break; | |
297 } | |
298 va_end(args); | |
299 _AD._no_output = 1; | |
300 } |