Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/jdi/SDE.java @ 18665:96861e3f8cc5
made CFGPrinterObserver reset (upon close) properly
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 11 Dec 2014 22:14:30 +0100 |
parents | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2002, 2003, 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:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
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:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.jdi; | |
26 | |
27 import com.sun.jdi.*; | |
28 | |
29 import java.util.*; | |
30 import java.io.File; | |
31 | |
32 class SDE { | |
33 private static final int INIT_SIZE_FILE = 3; | |
34 private static final int INIT_SIZE_LINE = 100; | |
35 private static final int INIT_SIZE_STRATUM = 3; | |
36 | |
37 static final String BASE_STRATUM_NAME = "Java"; | |
38 | |
39 /* for C capatibility */ | |
40 static final String NullString = null; | |
41 | |
42 private class FileTableRecord { | |
43 int fileId; | |
44 String sourceName; | |
45 String sourcePath; // do not read - use accessor | |
46 boolean isConverted = false; | |
47 | |
48 /** | |
49 * Return the sourcePath, computing it if not set. | |
50 * If set, convert '/' in the sourcePath to the | |
51 * local file separator. | |
52 */ | |
53 String getSourcePath(ReferenceTypeImpl refType) { | |
54 if (!isConverted) { | |
55 if (sourcePath == null) { | |
56 sourcePath = refType.baseSourceDir() + sourceName; | |
57 } else { | |
58 StringBuffer buf = new StringBuffer(); | |
59 for (int i = 0; i < sourcePath.length(); ++i) { | |
60 char ch = sourcePath.charAt(i); | |
61 if (ch == '/') { | |
62 buf.append(File.separatorChar); | |
63 } else { | |
64 buf.append(ch); | |
65 } | |
66 } | |
67 sourcePath = buf.toString(); | |
68 } | |
69 isConverted = true; | |
70 } | |
71 return sourcePath; | |
72 } | |
73 } | |
74 | |
75 private class LineTableRecord { | |
76 int jplsStart; | |
77 int jplsEnd; | |
78 int jplsLineInc; | |
79 int njplsStart; | |
80 int njplsEnd; | |
81 int fileId; | |
82 } | |
83 | |
84 private class StratumTableRecord { | |
85 String id; | |
86 int fileIndex; | |
87 int lineIndex; | |
88 } | |
89 | |
90 class Stratum { | |
91 private final int sti; /* stratum index */ | |
92 | |
93 private Stratum(int sti) { | |
94 this.sti = sti; | |
95 } | |
96 | |
97 String id() { | |
98 return stratumTable[sti].id; | |
99 } | |
100 | |
101 boolean isJava() { | |
102 return sti == baseStratumIndex; | |
103 } | |
104 | |
105 /** | |
106 * Return all the sourceNames for this stratum. | |
107 * Look from our starting fileIndex upto the starting | |
108 * fileIndex of next stratum - can do this since there | |
109 * is always a terminator stratum. | |
110 * Default sourceName (the first one) must be first. | |
111 */ | |
112 List sourceNames(ReferenceTypeImpl refType) { | |
113 int i; | |
114 int fileIndexStart = stratumTable[sti].fileIndex; | |
115 /* one past end */ | |
116 int fileIndexEnd = stratumTable[sti+1].fileIndex; | |
117 List result = new ArrayList(fileIndexEnd - fileIndexStart); | |
118 for (i = fileIndexStart; i < fileIndexEnd; ++i) { | |
119 result.add(fileTable[i].sourceName); | |
120 } | |
121 return result; | |
122 } | |
123 | |
124 /** | |
125 * Return all the sourcePaths for this stratum. | |
126 * Look from our starting fileIndex upto the starting | |
127 * fileIndex of next stratum - can do this since there | |
128 * is always a terminator stratum. | |
129 * Default sourcePath (the first one) must be first. | |
130 */ | |
131 List sourcePaths(ReferenceTypeImpl refType) { | |
132 int i; | |
133 int fileIndexStart = stratumTable[sti].fileIndex; | |
134 /* one past end */ | |
135 int fileIndexEnd = stratumTable[sti+1].fileIndex; | |
136 List result = new ArrayList(fileIndexEnd - fileIndexStart); | |
137 for (i = fileIndexStart; i < fileIndexEnd; ++i) { | |
138 result.add(fileTable[i].getSourcePath(refType)); | |
139 } | |
140 return result; | |
141 } | |
142 | |
143 LineStratum lineStratum(ReferenceTypeImpl refType, | |
144 int jplsLine) { | |
145 int lti = stiLineTableIndex(sti, jplsLine); | |
146 if (lti < 0) { | |
147 return null; | |
148 } else { | |
149 return new LineStratum(sti, lti, refType, | |
150 jplsLine); | |
151 } | |
152 } | |
153 } | |
154 | |
155 class LineStratum { | |
156 private final int sti; /* stratum index */ | |
157 private final int lti; /* line table index */ | |
158 private final ReferenceTypeImpl refType; | |
159 private final int jplsLine; | |
160 private String sourceName = null; | |
161 private String sourcePath = null; | |
162 | |
163 private LineStratum(int sti, int lti, | |
164 ReferenceTypeImpl refType, | |
165 int jplsLine) { | |
166 this.sti = sti; | |
167 this.lti = lti; | |
168 this.refType = refType; | |
169 this.jplsLine = jplsLine; | |
170 } | |
171 | |
172 public boolean equals(Object obj) { | |
173 if ((obj != null) && (obj instanceof LineStratum)) { | |
174 LineStratum other = (LineStratum)obj; | |
175 return (lti == other.lti) && | |
176 (sti == other.sti) && | |
177 (lineNumber() == other.lineNumber()) && | |
178 (refType.equals(other.refType)); | |
179 } else { | |
180 return false; | |
181 } | |
182 } | |
183 | |
184 int lineNumber() { | |
185 return stiLineNumber(sti, lti, jplsLine); | |
186 } | |
187 | |
188 /** | |
189 * Fetch the source name and source path for | |
190 * this line, converting or constructing | |
191 * the source path if needed. | |
192 */ | |
193 void getSourceInfo() { | |
194 if (sourceName != null) { | |
195 // already done | |
196 return; | |
197 } | |
198 int fti = stiFileTableIndex(sti, lti); | |
199 if (fti == -1) { | |
200 throw new InternalError( | |
201 "Bad SourceDebugExtension, no matching source id " + | |
202 lineTable[lti].fileId + " jplsLine: " + jplsLine); | |
203 } | |
204 FileTableRecord ftr = fileTable[fti]; | |
205 sourceName = ftr.sourceName; | |
206 sourcePath = ftr.getSourcePath(refType); | |
207 } | |
208 | |
209 String sourceName() { | |
210 getSourceInfo(); | |
211 return sourceName; | |
212 } | |
213 | |
214 String sourcePath() { | |
215 getSourceInfo(); | |
216 return sourcePath; | |
217 } | |
218 } | |
219 | |
220 private FileTableRecord[] fileTable = null; | |
221 private LineTableRecord[] lineTable = null; | |
222 private StratumTableRecord[] stratumTable = null; | |
223 | |
224 private int fileIndex = 0; | |
225 private int lineIndex = 0; | |
226 private int stratumIndex = 0; | |
227 private int currentFileId = 0; | |
228 | |
229 private int defaultStratumIndex = -1; | |
230 private int baseStratumIndex = -2; /* so as not to match -1 above */ | |
231 private int sdePos = 0; | |
232 | |
233 final String sourceDebugExtension; | |
234 String jplsFilename = null; | |
235 String defaultStratumId = null; | |
236 boolean isValid = false; | |
237 | |
238 SDE(String sourceDebugExtension) { | |
239 this.sourceDebugExtension = sourceDebugExtension; | |
240 decode(); | |
241 } | |
242 | |
243 SDE() { | |
244 this.sourceDebugExtension = null; | |
245 createProxyForAbsentSDE(); | |
246 } | |
247 | |
248 char sdePeek() { | |
249 if (sdePos >= sourceDebugExtension.length()) { | |
250 syntax(); | |
251 } | |
252 return sourceDebugExtension.charAt(sdePos); | |
253 } | |
254 | |
255 char sdeRead() { | |
256 if (sdePos >= sourceDebugExtension.length()) { | |
257 syntax(); | |
258 } | |
259 return sourceDebugExtension.charAt(sdePos++); | |
260 } | |
261 | |
262 void sdeAdvance() { | |
263 sdePos++; | |
264 } | |
265 | |
266 void syntax() { | |
267 throw new InternalError("bad SourceDebugExtension syntax - position " + | |
268 sdePos); | |
269 } | |
270 | |
271 void syntax(String msg) { | |
272 throw new InternalError("bad SourceDebugExtension syntax: " + msg); | |
273 } | |
274 | |
275 void assureLineTableSize() { | |
276 int len = lineTable == null? 0 : lineTable.length; | |
277 if (lineIndex >= len) { | |
278 int i; | |
279 int newLen = len == 0? INIT_SIZE_LINE : len * 2; | |
280 LineTableRecord[] newTable = new LineTableRecord[newLen]; | |
281 for (i = 0; i < len; ++i) { | |
282 newTable[i] = lineTable[i]; | |
283 } | |
284 for (; i < newLen; ++i) { | |
285 newTable[i] = new LineTableRecord(); | |
286 } | |
287 lineTable = newTable; | |
288 } | |
289 } | |
290 | |
291 void assureFileTableSize() { | |
292 int len = fileTable == null? 0 : fileTable.length; | |
293 if (fileIndex >= len) { | |
294 int i; | |
295 int newLen = len == 0? INIT_SIZE_FILE : len * 2; | |
296 FileTableRecord[] newTable = new FileTableRecord[newLen]; | |
297 for (i = 0; i < len; ++i) { | |
298 newTable[i] = fileTable[i]; | |
299 } | |
300 for (; i < newLen; ++i) { | |
301 newTable[i] = new FileTableRecord(); | |
302 } | |
303 fileTable = newTable; | |
304 } | |
305 } | |
306 | |
307 void assureStratumTableSize() { | |
308 int len = stratumTable == null? 0 : stratumTable.length; | |
309 if (stratumIndex >= len) { | |
310 int i; | |
311 int newLen = len == 0? INIT_SIZE_STRATUM : len * 2; | |
312 StratumTableRecord[] newTable = new StratumTableRecord[newLen]; | |
313 for (i = 0; i < len; ++i) { | |
314 newTable[i] = stratumTable[i]; | |
315 } | |
316 for (; i < newLen; ++i) { | |
317 newTable[i] = new StratumTableRecord(); | |
318 } | |
319 stratumTable = newTable; | |
320 } | |
321 } | |
322 | |
323 String readLine() { | |
324 StringBuffer sb = new StringBuffer(); | |
325 char ch; | |
326 | |
327 ignoreWhite(); | |
328 while (((ch = sdeRead()) != '\n') && (ch != '\r')) { | |
329 sb.append((char)ch); | |
330 } | |
331 // check for CR LF | |
332 if ((ch == '\r') && (sdePeek() == '\n')) { | |
333 sdeRead(); | |
334 } | |
335 ignoreWhite(); // leading white | |
336 return sb.toString(); | |
337 } | |
338 | |
339 private int defaultStratumTableIndex() { | |
340 if ((defaultStratumIndex == -1) && (defaultStratumId != null)) { | |
341 defaultStratumIndex = | |
342 stratumTableIndex(defaultStratumId); | |
343 } | |
344 return defaultStratumIndex; | |
345 } | |
346 | |
347 int stratumTableIndex(String stratumId) { | |
348 int i; | |
349 | |
350 if (stratumId == null) { | |
351 return defaultStratumTableIndex(); | |
352 } | |
353 for (i = 0; i < (stratumIndex-1); ++i) { | |
354 if (stratumTable[i].id.equals(stratumId)) { | |
355 return i; | |
356 } | |
357 } | |
358 return defaultStratumTableIndex(); | |
359 } | |
360 | |
361 Stratum stratum(String stratumID) { | |
362 int sti = stratumTableIndex(stratumID); | |
363 return new Stratum(sti); | |
364 } | |
365 | |
366 List availableStrata() { | |
367 List strata = new ArrayList(); | |
368 | |
369 for (int i = 0; i < (stratumIndex-1); ++i) { | |
370 StratumTableRecord rec = stratumTable[i]; | |
371 strata.add(rec.id); | |
372 } | |
373 return strata; | |
374 } | |
375 | |
376 /***************************** | |
377 * below functions/methods are written to compile under either Java or C | |
378 * | |
379 * Needed support functions: | |
380 * sdePeek() | |
381 * sdeRead() | |
382 * sdeAdvance() | |
383 * readLine() | |
384 * assureLineTableSize() | |
385 * assureFileTableSize() | |
386 * assureStratumTableSize() | |
387 * syntax() | |
388 * | |
389 * stratumTableIndex(String) | |
390 * | |
391 * Needed support variables: | |
392 * lineTable | |
393 * lineIndex | |
394 * fileTable | |
395 * fileIndex | |
396 * currentFileId | |
397 * | |
398 * Needed types: | |
399 * String | |
400 * | |
401 * Needed constants: | |
402 * NullString | |
403 */ | |
404 | |
405 void ignoreWhite() { | |
406 char ch; | |
407 | |
408 while (((ch = sdePeek()) == ' ') || (ch == '\t')) { | |
409 sdeAdvance(); | |
410 } | |
411 } | |
412 | |
413 void ignoreLine() { | |
414 char ch; | |
415 | |
416 while (((ch = sdeRead()) != '\n') && (ch != '\r')) { | |
417 } | |
418 /* check for CR LF */ | |
419 if ((ch == '\r') && (sdePeek() == '\n')) { | |
420 sdeAdvance(); | |
421 } | |
422 ignoreWhite(); /* leading white */ | |
423 } | |
424 | |
425 int readNumber() { | |
426 int value = 0; | |
427 char ch; | |
428 | |
429 ignoreWhite(); | |
430 while (((ch = sdePeek()) >= '0') && (ch <= '9')) { | |
431 sdeAdvance(); | |
432 value = (value * 10) + ch - '0'; | |
433 } | |
434 ignoreWhite(); | |
435 return value; | |
436 } | |
437 | |
438 void storeFile(int fileId, String sourceName, String sourcePath) { | |
439 assureFileTableSize(); | |
440 fileTable[fileIndex].fileId = fileId; | |
441 fileTable[fileIndex].sourceName = sourceName; | |
442 fileTable[fileIndex].sourcePath = sourcePath; | |
443 ++fileIndex; | |
444 } | |
445 | |
446 void fileLine() { | |
447 int hasAbsolute = 0; /* acts as boolean */ | |
448 int fileId; | |
449 String sourceName; | |
450 String sourcePath = null; | |
451 | |
452 /* is there an absolute filename? */ | |
453 if (sdePeek() == '+') { | |
454 sdeAdvance(); | |
455 hasAbsolute = 1; | |
456 } | |
457 fileId = readNumber(); | |
458 sourceName = readLine(); | |
459 if (hasAbsolute == 1) { | |
460 sourcePath = readLine(); | |
461 } | |
462 | |
463 storeFile(fileId, sourceName, sourcePath); | |
464 } | |
465 | |
466 void storeLine(int jplsStart, int jplsEnd, int jplsLineInc, | |
467 int njplsStart, int njplsEnd, int fileId) { | |
468 assureLineTableSize(); | |
469 lineTable[lineIndex].jplsStart = jplsStart; | |
470 lineTable[lineIndex].jplsEnd = jplsEnd; | |
471 lineTable[lineIndex].jplsLineInc = jplsLineInc; | |
472 lineTable[lineIndex].njplsStart = njplsStart; | |
473 lineTable[lineIndex].njplsEnd = njplsEnd; | |
474 lineTable[lineIndex].fileId = fileId; | |
475 ++lineIndex; | |
476 } | |
477 | |
478 /** | |
479 * Parse line translation info. Syntax is | |
480 * <NJ-start-line> [ # <file-id> ] [ , <line-count> ] : | |
481 * <J-start-line> [ , <line-increment> ] CR | |
482 */ | |
483 void lineLine() { | |
484 int lineCount = 1; | |
485 int lineIncrement = 1; | |
486 int njplsStart; | |
487 int jplsStart; | |
488 | |
489 njplsStart = readNumber(); | |
490 | |
491 /* is there a fileID? */ | |
492 if (sdePeek() == '#') { | |
493 sdeAdvance(); | |
494 currentFileId = readNumber(); | |
495 } | |
496 | |
497 /* is there a line count? */ | |
498 if (sdePeek() == ',') { | |
499 sdeAdvance(); | |
500 lineCount = readNumber(); | |
501 } | |
502 | |
503 if (sdeRead() != ':') { | |
504 syntax(); | |
505 } | |
506 jplsStart = readNumber(); | |
507 if (sdePeek() == ',') { | |
508 sdeAdvance(); | |
509 lineIncrement = readNumber(); | |
510 } | |
511 ignoreLine(); /* flush the rest */ | |
512 | |
513 storeLine(jplsStart, | |
514 jplsStart + (lineCount * lineIncrement) -1, | |
515 lineIncrement, | |
516 njplsStart, | |
517 njplsStart + lineCount -1, | |
518 currentFileId); | |
519 } | |
520 | |
521 /** | |
522 * Until the next stratum section, everything after this | |
523 * is in stratumId - so, store the current indicies. | |
524 */ | |
525 void storeStratum(String stratumId) { | |
526 /* remove redundant strata */ | |
527 if (stratumIndex > 0) { | |
528 if ((stratumTable[stratumIndex-1].fileIndex | |
529 == fileIndex) && | |
530 (stratumTable[stratumIndex-1].lineIndex | |
531 == lineIndex)) { | |
532 /* nothing changed overwrite it */ | |
533 --stratumIndex; | |
534 } | |
535 } | |
536 /* store the results */ | |
537 assureStratumTableSize(); | |
538 stratumTable[stratumIndex].id = stratumId; | |
539 stratumTable[stratumIndex].fileIndex = fileIndex; | |
540 stratumTable[stratumIndex].lineIndex = lineIndex; | |
541 ++stratumIndex; | |
542 currentFileId = 0; | |
543 } | |
544 | |
545 /** | |
546 * The beginning of a stratum's info | |
547 */ | |
548 void stratumSection() { | |
549 storeStratum(readLine()); | |
550 } | |
551 | |
552 void fileSection() { | |
553 ignoreLine(); | |
554 while (sdePeek() != '*') { | |
555 fileLine(); | |
556 } | |
557 } | |
558 | |
559 void lineSection() { | |
560 ignoreLine(); | |
561 while (sdePeek() != '*') { | |
562 lineLine(); | |
563 } | |
564 } | |
565 | |
566 /** | |
567 * Ignore a section we don't know about. | |
568 */ | |
569 void ignoreSection() { | |
570 ignoreLine(); | |
571 while (sdePeek() != '*') { | |
572 ignoreLine(); | |
573 } | |
574 } | |
575 | |
576 /** | |
577 * A base "Java" stratum is always available, though | |
578 * it is not in the SourceDebugExtension. | |
579 * Create the base stratum. | |
580 */ | |
581 void createJavaStratum() { | |
582 baseStratumIndex = stratumIndex; | |
583 storeStratum(BASE_STRATUM_NAME); | |
584 storeFile(1, jplsFilename, NullString); | |
585 /* JPL line numbers cannot exceed 65535 */ | |
586 storeLine(1, 65536, 1, 1, 65536, 1); | |
587 storeStratum("Aux"); /* in case they don't declare */ | |
588 } | |
589 | |
590 /** | |
591 * Decode a SourceDebugExtension which is in SourceMap format. | |
592 * This is the entry point into the recursive descent parser. | |
593 */ | |
594 void decode() { | |
595 /* check for "SMAP" - allow EOF if not ours */ | |
596 if ((sourceDebugExtension.length() < 4) || | |
597 (sdeRead() != 'S') || | |
598 (sdeRead() != 'M') || | |
599 (sdeRead() != 'A') || | |
600 (sdeRead() != 'P')) { | |
601 return; /* not our info */ | |
602 } | |
603 ignoreLine(); /* flush the rest */ | |
604 jplsFilename = readLine(); | |
605 defaultStratumId = readLine(); | |
606 createJavaStratum(); | |
607 while (true) { | |
608 if (sdeRead() != '*') { | |
609 syntax(); | |
610 } | |
611 switch (sdeRead()) { | |
612 case 'S': | |
613 stratumSection(); | |
614 break; | |
615 case 'F': | |
616 fileSection(); | |
617 break; | |
618 case 'L': | |
619 lineSection(); | |
620 break; | |
621 case 'E': | |
622 /* set end points */ | |
623 storeStratum("*terminator*"); | |
624 isValid = true; | |
625 return; | |
626 default: | |
627 ignoreSection(); | |
628 } | |
629 } | |
630 } | |
631 | |
632 void createProxyForAbsentSDE() { | |
633 jplsFilename = null; | |
634 defaultStratumId = BASE_STRATUM_NAME; | |
635 defaultStratumIndex = stratumIndex; | |
636 createJavaStratum(); | |
637 storeStratum("*terminator*"); | |
638 } | |
639 | |
640 /***************** query functions ***********************/ | |
641 | |
642 private int stiLineTableIndex(int sti, int jplsLine) { | |
643 int i; | |
644 int lineIndexStart; | |
645 int lineIndexEnd; | |
646 | |
647 lineIndexStart = stratumTable[sti].lineIndex; | |
648 /* one past end */ | |
649 lineIndexEnd = stratumTable[sti+1].lineIndex; | |
650 for (i = lineIndexStart; i < lineIndexEnd; ++i) { | |
651 if ((jplsLine >= lineTable[i].jplsStart) && | |
652 (jplsLine <= lineTable[i].jplsEnd)) { | |
653 return i; | |
654 } | |
655 } | |
656 return -1; | |
657 } | |
658 | |
659 private int stiLineNumber(int sti, int lti, int jplsLine) { | |
660 return lineTable[lti].njplsStart + | |
661 (((jplsLine - lineTable[lti].jplsStart) / | |
662 lineTable[lti].jplsLineInc)); | |
663 } | |
664 | |
665 private int fileTableIndex(int sti, int fileId) { | |
666 int i; | |
667 int fileIndexStart = stratumTable[sti].fileIndex; | |
668 /* one past end */ | |
669 int fileIndexEnd = stratumTable[sti+1].fileIndex; | |
670 for (i = fileIndexStart; i < fileIndexEnd; ++i) { | |
671 if (fileTable[i].fileId == fileId) { | |
672 return i; | |
673 } | |
674 } | |
675 return -1; | |
676 } | |
677 | |
678 private int stiFileTableIndex(int sti, int lti) { | |
679 return fileTableIndex(sti, lineTable[lti].fileId); | |
680 } | |
681 | |
682 boolean isValid() { | |
683 return isValid; | |
684 } | |
685 } |