001: /*
002: * Copyright 1998-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.jdi;
027:
028: import com.sun.jdi.*;
029:
030: import java.util.*;
031:
032: public class LocationImpl extends MirrorImpl implements Location {
033: private final ReferenceTypeImpl declaringType;
034: private Method method;
035: private long methodRef;
036: private long codeIndex;
037: private LineInfo baseLineInfo = null;
038: private LineInfo otherLineInfo = null;
039:
040: LocationImpl(VirtualMachine vm, Method method, long codeIndex) {
041: super (vm);
042:
043: this .method = method;
044: this .codeIndex = method.isNative() ? -1 : codeIndex;
045: this .declaringType = (ReferenceTypeImpl) method.declaringType();
046: }
047:
048: /*
049: * This constructor allows lazy creation of the method mirror. This
050: * can be a performance savings if the method mirror does not yet
051: * exist.
052: */
053: LocationImpl(VirtualMachine vm, ReferenceTypeImpl declaringType,
054: long methodRef, long codeIndex) {
055: super (vm);
056:
057: this .method = null;
058: this .codeIndex = codeIndex;
059: this .declaringType = declaringType;
060: this .methodRef = methodRef;
061: }
062:
063: public boolean equals(Object obj) {
064: if ((obj != null) && (obj instanceof Location)) {
065: Location other = (Location) obj;
066: return (method().equals(other.method()))
067: && (codeIndex() == other.codeIndex())
068: && super .equals(obj);
069: } else {
070: return false;
071: }
072: }
073:
074: public int hashCode() {
075: /*
076: * TO DO: better hash code?
077: */
078: return method().hashCode() + (int) codeIndex();
079: }
080:
081: public int compareTo(Location object) {
082: LocationImpl other = (LocationImpl) object;
083: int rc = method().compareTo(other.method());
084: if (rc == 0) {
085: long diff = codeIndex() - other.codeIndex();
086: if (diff < 0)
087: return -1;
088: else if (diff > 0)
089: return 1;
090: else
091: return 0;
092: }
093: return rc;
094: }
095:
096: public ReferenceType declaringType() {
097: return declaringType;
098: }
099:
100: public Method method() {
101: if (method == null) {
102: method = declaringType.getMethodMirror(methodRef);
103: if (method.isNative()) {
104: codeIndex = -1;
105: }
106: }
107: return method;
108: }
109:
110: public long codeIndex() {
111: method(); // be sure information is up-to-date
112: return codeIndex;
113: }
114:
115: LineInfo getBaseLineInfo(SDE.Stratum stratum) {
116: LineInfo lineInfo;
117:
118: /* check if there is cached info to use */
119: if (baseLineInfo != null) {
120: return baseLineInfo;
121: }
122:
123: /* compute the line info */
124: MethodImpl methodImpl = (MethodImpl) method();
125: lineInfo = methodImpl.codeIndexToLineInfo(stratum, codeIndex());
126:
127: /* cache it */
128: addBaseLineInfo(lineInfo);
129:
130: return lineInfo;
131: }
132:
133: LineInfo getLineInfo(SDE.Stratum stratum) {
134: LineInfo lineInfo;
135:
136: /* base stratum is done slighly differently */
137: if (stratum.isJava()) {
138: return getBaseLineInfo(stratum);
139: }
140:
141: /* check if there is cached info to use */
142: lineInfo = otherLineInfo; // copy because of concurrency
143: if (lineInfo != null
144: && stratum.id().equals(lineInfo.liStratum())) {
145: return lineInfo;
146: }
147:
148: int baseLineNumber = lineNumber(SDE.BASE_STRATUM_NAME);
149: SDE.LineStratum lineStratum = stratum.lineStratum(
150: declaringType, baseLineNumber);
151:
152: if (lineStratum != null && lineStratum.lineNumber() != -1) {
153: lineInfo = new StratumLineInfo(stratum.id(), lineStratum
154: .lineNumber(), lineStratum.sourceName(),
155: lineStratum.sourcePath());
156: } else {
157: /* find best match */
158: MethodImpl methodImpl = (MethodImpl) method();
159: lineInfo = methodImpl.codeIndexToLineInfo(stratum,
160: codeIndex());
161: }
162:
163: /* cache it */
164: addStratumLineInfo(lineInfo);
165:
166: return lineInfo;
167: }
168:
169: void addStratumLineInfo(LineInfo lineInfo) {
170: otherLineInfo = lineInfo;
171: }
172:
173: void addBaseLineInfo(LineInfo lineInfo) {
174: baseLineInfo = lineInfo;
175: }
176:
177: public String sourceName() throws AbsentInformationException {
178: return sourceName(vm.getDefaultStratum());
179: }
180:
181: public String sourceName(String stratumID)
182: throws AbsentInformationException {
183: return sourceName(declaringType.stratum(stratumID));
184: }
185:
186: String sourceName(SDE.Stratum stratum)
187: throws AbsentInformationException {
188: return getLineInfo(stratum).liSourceName();
189: }
190:
191: public String sourcePath() throws AbsentInformationException {
192: return sourcePath(vm.getDefaultStratum());
193: }
194:
195: public String sourcePath(String stratumID)
196: throws AbsentInformationException {
197: return sourcePath(declaringType.stratum(stratumID));
198: }
199:
200: String sourcePath(SDE.Stratum stratum)
201: throws AbsentInformationException {
202: return getLineInfo(stratum).liSourcePath();
203: }
204:
205: public int lineNumber() {
206: return lineNumber(vm.getDefaultStratum());
207: }
208:
209: public int lineNumber(String stratumID) {
210: return lineNumber(declaringType.stratum(stratumID));
211: }
212:
213: int lineNumber(SDE.Stratum stratum) {
214: return getLineInfo(stratum).liLineNumber();
215: }
216:
217: public String toString() {
218: if (lineNumber() == -1) {
219: return method().toString() + "+" + codeIndex();
220: } else {
221: return declaringType().name() + ":" + lineNumber();
222: }
223: }
224: }
|