comparison agent/src/share/classes/sun/jvm/hotspot/jdi/SDE.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
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 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
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 }