| /* |
| * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.tools.jdi; |
| |
| import com.sun.jdi.*; |
| |
| import java.util.*; |
| |
| public class LocationImpl extends MirrorImpl implements Location { |
| private final ReferenceTypeImpl declaringType; |
| private Method method; |
| private long methodRef; |
| private long codeIndex; |
| private LineInfo baseLineInfo = null; |
| private LineInfo otherLineInfo = null; |
| |
| LocationImpl(VirtualMachine vm, |
| Method method, long codeIndex) { |
| super(vm); |
| |
| this.method = method; |
| this.codeIndex = method.isNative()? -1 : codeIndex; |
| this.declaringType = (ReferenceTypeImpl)method.declaringType(); |
| } |
| |
| /* |
| * This constructor allows lazy creation of the method mirror. This |
| * can be a performance savings if the method mirror does not yet |
| * exist. |
| */ |
| LocationImpl(VirtualMachine vm, ReferenceTypeImpl declaringType, |
| long methodRef, long codeIndex) { |
| super(vm); |
| |
| this.method = null; |
| this.codeIndex = codeIndex; |
| this.declaringType = declaringType; |
| this.methodRef = methodRef; |
| } |
| |
| public boolean equals(Object obj) { |
| if ((obj != null) && (obj instanceof Location)) { |
| Location other = (Location)obj; |
| return (method().equals(other.method())) && |
| (codeIndex() == other.codeIndex()) && |
| super.equals(obj); |
| } else { |
| return false; |
| } |
| } |
| |
| public int hashCode() { |
| /* |
| * TO DO: better hash code? |
| */ |
| return method().hashCode() + (int)codeIndex(); |
| } |
| |
| public int compareTo(Location object) { |
| LocationImpl other = (LocationImpl)object; |
| int rc = method().compareTo(other.method()); |
| if (rc == 0) { |
| long diff = codeIndex() - other.codeIndex(); |
| if (diff < 0) |
| return -1; |
| else if (diff > 0) |
| return 1; |
| else |
| return 0; |
| } |
| return rc; |
| } |
| |
| public ReferenceType declaringType() { |
| return declaringType; |
| } |
| |
| public Method method() { |
| if (method == null) { |
| method = declaringType.getMethodMirror(methodRef); |
| if (method.isNative()) { |
| codeIndex = -1; |
| } |
| } |
| return method; |
| } |
| |
| public long codeIndex() { |
| method(); // be sure information is up-to-date |
| return codeIndex; |
| } |
| |
| LineInfo getBaseLineInfo(SDE.Stratum stratum) { |
| LineInfo lineInfo; |
| |
| /* check if there is cached info to use */ |
| if (baseLineInfo != null) { |
| return baseLineInfo; |
| } |
| |
| /* compute the line info */ |
| MethodImpl methodImpl = (MethodImpl)method(); |
| lineInfo = methodImpl.codeIndexToLineInfo(stratum, |
| codeIndex()); |
| |
| /* cache it */ |
| addBaseLineInfo(lineInfo); |
| |
| return lineInfo; |
| } |
| |
| LineInfo getLineInfo(SDE.Stratum stratum) { |
| LineInfo lineInfo; |
| |
| /* base stratum is done slighly differently */ |
| if (stratum.isJava()) { |
| return getBaseLineInfo(stratum); |
| } |
| |
| /* check if there is cached info to use */ |
| lineInfo = otherLineInfo; // copy because of concurrency |
| if (lineInfo != null && |
| stratum.id().equals(lineInfo.liStratum())) { |
| return lineInfo; |
| } |
| |
| int baseLineNumber = lineNumber(SDE.BASE_STRATUM_NAME); |
| SDE.LineStratum lineStratum = |
| stratum.lineStratum(declaringType, baseLineNumber); |
| |
| if (lineStratum != null && lineStratum.lineNumber() != -1) { |
| lineInfo = new StratumLineInfo(stratum.id(), |
| lineStratum.lineNumber(), |
| lineStratum.sourceName(), |
| lineStratum.sourcePath()); |
| } else { |
| /* find best match */ |
| MethodImpl methodImpl = (MethodImpl)method(); |
| lineInfo = methodImpl.codeIndexToLineInfo(stratum, |
| codeIndex()); |
| } |
| |
| /* cache it */ |
| addStratumLineInfo(lineInfo); |
| |
| return lineInfo; |
| } |
| |
| void addStratumLineInfo(LineInfo lineInfo) { |
| otherLineInfo = lineInfo; |
| } |
| |
| void addBaseLineInfo(LineInfo lineInfo) { |
| baseLineInfo = lineInfo; |
| } |
| |
| public String sourceName() throws AbsentInformationException { |
| return sourceName(vm.getDefaultStratum()); |
| } |
| |
| public String sourceName(String stratumID) |
| throws AbsentInformationException { |
| return sourceName(declaringType.stratum(stratumID)); |
| } |
| |
| String sourceName(SDE.Stratum stratum) |
| throws AbsentInformationException { |
| return getLineInfo(stratum).liSourceName(); |
| } |
| |
| public String sourcePath() throws AbsentInformationException { |
| return sourcePath(vm.getDefaultStratum()); |
| } |
| |
| public String sourcePath(String stratumID) |
| throws AbsentInformationException { |
| return sourcePath(declaringType.stratum(stratumID)); |
| } |
| |
| String sourcePath(SDE.Stratum stratum) |
| throws AbsentInformationException { |
| return getLineInfo(stratum).liSourcePath(); |
| } |
| |
| public int lineNumber() { |
| return lineNumber(vm.getDefaultStratum()); |
| } |
| |
| public int lineNumber(String stratumID) { |
| return lineNumber(declaringType.stratum(stratumID)); |
| } |
| |
| int lineNumber(SDE.Stratum stratum) { |
| return getLineInfo(stratum).liLineNumber(); |
| } |
| |
| public String toString() { |
| if (lineNumber() == -1) { |
| return method().toString() + "+" + codeIndex(); |
| } else { |
| return declaringType().name() + ":" + lineNumber(); |
| } |
| } |
| } |