hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java
author fparain
Mon, 09 Jul 2012 01:28:37 -0700
changeset 13201 69f157caabcc
parent 10517 f92c9ff3a15f
child 13728 882756847a04
permissions -rw-r--r--
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K Reviewed-by: sspitsyn, dholmes, coleenp, kamg
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
13201
69f157caabcc 6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents: 10517
diff changeset
     2
 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
package sun.jvm.hotspot.jdi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
import java.io.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
import com.sun.jdi.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
10517
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    31
import sun.jvm.hotspot.memory.SystemDictionary;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
import sun.jvm.hotspot.oops.Instance;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
import sun.jvm.hotspot.oops.InstanceKlass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
import sun.jvm.hotspot.oops.ArrayKlass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
import sun.jvm.hotspot.oops.JVMDIClassStatus;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
import sun.jvm.hotspot.oops.Klass;
10517
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    37
import sun.jvm.hotspot.oops.ObjArray;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
import sun.jvm.hotspot.oops.Oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
import sun.jvm.hotspot.oops.Symbol;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
import sun.jvm.hotspot.oops.DefaultHeapVisitor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
import sun.jvm.hotspot.utilities.Assert;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
import java.util.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
import java.lang.ref.SoftReference;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
public abstract class ReferenceTypeImpl extends TypeImpl
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
implements ReferenceType {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
    protected Klass       saKlass;          // This can be an InstanceKlass or an ArrayKlass
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
    protected Symbol      typeNameSymbol;   // This is used in vm.classesByName to speedup search
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
    private int           modifiers = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
    private String        signature = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    private SoftReference sdeRef = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
    private SoftReference fieldsCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
    private SoftReference allFieldsCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
    private SoftReference methodsCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    private SoftReference allMethodsCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
    private SoftReference nestedTypesCache;
10517
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    58
    private SoftReference methodInvokesCache;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
    /* to mark when no info available */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
    static final SDE NO_SDE_INFO_MARK = new SDE();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    protected ReferenceTypeImpl(VirtualMachine aVm, sun.jvm.hotspot.oops.Klass klass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
        super(aVm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
        saKlass = klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
        typeNameSymbol = saKlass.getName();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
        if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
            Assert.that(typeNameSymbol != null, "null type name for a Klass");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    Symbol typeNameAsSymbol() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
        return typeNameSymbol;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    Method getMethodMirror(sun.jvm.hotspot.oops.Method ref) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
        // SA creates new Method objects when they are referenced which means
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
        // that the incoming object might not be the same object as on our
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
        // even though it is the same method. So do an address compare by
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
        // calling equals rather than just reference compare.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
        Iterator it = methods().iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
        while (it.hasNext()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
            MethodImpl method = (MethodImpl)it.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
            if (ref.equals(method.ref())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
                return method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
        }
10517
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    88
        if (ref.getMethodHolder().equals(SystemDictionary.getMethodHandleKlass())) {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    89
          // invoke methods are generated as needed, so make mirrors as needed
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    90
          List mis = null;
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    91
          if (methodInvokesCache == null) {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    92
            mis = new ArrayList();
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    93
            methodInvokesCache = new SoftReference(mis);
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    94
          } else {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    95
            mis = (List)methodInvokesCache.get();
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    96
          }
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    97
          it = mis.iterator();
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    98
          while (it.hasNext()) {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
    99
            MethodImpl method = (MethodImpl)it.next();
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
   100
            if (ref.equals(method.ref())) {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
   101
              return method;
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
   102
            }
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
   103
          }
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
   104
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
   105
          MethodImpl method = MethodImpl.createMethodImpl(vm, this, ref);
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
   106
          mis.add(method);
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
   107
          return method;
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 9127
diff changeset
   108
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
        throw new IllegalArgumentException("Invalid method id: " + ref);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    public boolean equals(Object obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
        if ((obj != null) && (obj instanceof ReferenceTypeImpl)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
            ReferenceTypeImpl other = (ReferenceTypeImpl)obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
            return (ref().equals(other.ref())) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
                (vm.equals(other.virtualMachine()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
            return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    public int hashCode() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
        return saKlass.hashCode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
9127
c3fc6f9ed68d 7010849: 5/5 Extraneous javac source/target options when building sa-jdi
andrew
parents: 5547
diff changeset
   126
    public int compareTo(ReferenceType refType) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
         * Note that it is critical that compareTo() == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
         * implies that equals() == true. Otherwise, TreeSet
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
         * will collapse classes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
         *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
         * (Classes of the same name loaded by different class loaders
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
         * or in different VMs must not return 0).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
         */
9127
c3fc6f9ed68d 7010849: 5/5 Extraneous javac source/target options when building sa-jdi
andrew
parents: 5547
diff changeset
   135
        ReferenceTypeImpl other = (ReferenceTypeImpl)refType;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
        int comp = name().compareTo(other.name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
        if (comp == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
            Oop rf1 = ref();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
            Oop rf2 = other.ref();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
            // optimize for typical case: refs equal and VMs equal
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
            if (rf1.equals(rf2)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
                // sequenceNumbers are always positive
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
                comp = vm.sequenceNumber -
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
                 ((VirtualMachineImpl)(other.virtualMachine())).sequenceNumber;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
                comp = rf1.getHandle().minus(rf2.getHandle()) < 0? -1 : 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
        return comp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    public String signature() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
        if (signature == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
            signature = saKlass.signature();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
        return signature;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    // refer to JvmtiEnv::GetClassSignature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    // null is returned for array klasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    public String genericSignature() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
        if (saKlass instanceof ArrayKlass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
            return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
            Symbol genSig = ((InstanceKlass)saKlass).getGenericSignature();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
            return (genSig != null)? genSig.asString() : null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    public ClassLoaderReference classLoader() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
      Instance xx = (Instance)(((InstanceKlass)saKlass).getClassLoader());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
      return (ClassLoaderReferenceImpl)vm.classLoaderMirror(xx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    public boolean isPublic() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
        return((modifiers() & VMModifiers.PUBLIC) != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    public boolean isProtected() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
        return((modifiers() & VMModifiers.PROTECTED) != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    public boolean isPrivate() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
        return((modifiers() & VMModifiers.PRIVATE) != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    public boolean isPackagePrivate() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
        return !isPublic() && !isPrivate() && !isProtected();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    public boolean isAbstract() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
        return((modifiers() & VMModifiers.ABSTRACT) != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
    public boolean isFinal() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
        return((modifiers() & VMModifiers.FINAL) != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    public boolean isStatic() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
        return((modifiers() & VMModifiers.STATIC) != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    public boolean isPrepared() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
        return (saKlass.getClassStatus() & JVMDIClassStatus.PREPARED) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    final void checkPrepared() throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
        if (! isPrepared()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
            throw new ClassNotPreparedException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    public boolean isVerified() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
        return (saKlass.getClassStatus() & JVMDIClassStatus.VERIFIED) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    public boolean isInitialized() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
        return (saKlass.getClassStatus() & JVMDIClassStatus.INITIALIZED) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
    public boolean failedToInitialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
        return (saKlass.getClassStatus() & JVMDIClassStatus.ERROR) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    private boolean isThrowableBacktraceField(sun.jvm.hotspot.oops.Field fld) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
        // refer to JvmtiEnv::GetClassFields in jvmtiEnv.cpp.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
        // We want to filter out java.lang.Throwable.backtrace (see 4446677).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
        // It contains some methodOops that aren't quite real Objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
        if (fld.getFieldHolder().getName().equals(vm.javaLangThrowable()) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
            fld.getID().getName().equals("backtrace")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
            return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
            return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
    public final List fields() throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
        List fields = (fieldsCache != null)? (List) fieldsCache.get() : null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
        if (fields == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
            checkPrepared();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
            if (saKlass instanceof ArrayKlass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
                fields = new ArrayList(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
                // Get a list of the sa Field types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
                List saFields = ((InstanceKlass)saKlass).getImmediateFields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
                // Create a list of our Field types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
                int len = saFields.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
                fields = new ArrayList(len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
                for (int ii = 0; ii < len; ii++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
                    sun.jvm.hotspot.oops.Field curField = (sun.jvm.hotspot.oops.Field)saFields.get(ii);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
                    if (! isThrowableBacktraceField(curField)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
                        fields.add(new FieldImpl(vm, this, curField));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
                    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
            fields = Collections.unmodifiableList(fields);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
            fieldsCache = new SoftReference(fields);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
        return fields;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    public final List allFields() throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
        List allFields = (allFieldsCache != null)? (List) allFieldsCache.get() : null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
        if (allFields == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
            checkPrepared();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
            if (saKlass instanceof ArrayKlass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
                // is 'length' a field of array klasses? To maintain
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
                // consistency with JVMDI-JDI we return 0 size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
                allFields = new ArrayList(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
                List saFields;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
                // Get a list of the sa Field types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
                saFields = ((InstanceKlass)saKlass).getAllFields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
                // Create a list of our Field types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
                int len = saFields.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
                allFields = new ArrayList(len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
                for (int ii = 0; ii < len; ii++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
                    sun.jvm.hotspot.oops.Field curField = (sun.jvm.hotspot.oops.Field)saFields.get(ii);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
                    if (! isThrowableBacktraceField(curField)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
                        allFields.add(new FieldImpl(vm, vm.referenceType(curField.getFieldHolder()), curField));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
                    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
            allFields = Collections.unmodifiableList(allFields);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
            allFieldsCache = new SoftReference(allFields);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
        return allFields;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
    abstract List inheritedTypes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    void addVisibleFields(List visibleList, Map visibleTable, List ambiguousNames) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
        List list = visibleFields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
        Iterator iter = list.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
        while (iter.hasNext()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
            Field field = (Field)iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
            String name = field.name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
            if (!ambiguousNames.contains(name)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
                Field duplicate = (Field)visibleTable.get(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
                if (duplicate == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
                    visibleList.add(field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
                    visibleTable.put(name, field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
                } else if (!field.equals(duplicate)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
                    ambiguousNames.add(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
                    visibleTable.remove(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
                    visibleList.remove(duplicate);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
                } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
                    // identical field from two branches; do nothing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
    public final List visibleFields() throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
        checkPrepared();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
         * Maintain two different collections of visible fields. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
         * list maintains a reasonable order for return. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
         * hash map provides an efficient way to lookup visible fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
         * by name, important for finding hidden or ambiguous fields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
        List visibleList = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
        Map  visibleTable = new HashMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
        /* Track fields removed from above collection due to ambiguity */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
        List ambiguousNames = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
        /* Add inherited, visible fields */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
        List types = inheritedTypes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
        Iterator iter = types.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
        while (iter.hasNext()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
            /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
             * TO DO: Be defensive and check for cyclic interface inheritance
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
             */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
            ReferenceTypeImpl type = (ReferenceTypeImpl)iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
            type.addVisibleFields(visibleList, visibleTable, ambiguousNames);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
         * Insert fields from this type, removing any inherited fields they
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
         * hide.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
        List retList = new ArrayList(fields());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
        iter = retList.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
        while (iter.hasNext()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
            Field field = (Field)iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
            Field hidden = (Field)visibleTable.get(field.name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
            if (hidden != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
                visibleList.remove(hidden);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
        retList.addAll(visibleList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
        return retList;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
   public final Field fieldByName(String fieldName) throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
        java.util.List searchList;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
        Field f;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
        // visibleFields calls checkPrepared
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
        searchList = visibleFields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
        for (int i=0; i<searchList.size(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
            f = (Field)searchList.get(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
            if (f.name().equals(fieldName)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
                return f;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
        //throw new NoSuchFieldException("Field '" + fieldName + "' not found in " + name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
        return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
    public final List methods() throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
        List methods = (methodsCache != null)? (List) methodsCache.get() : null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
        if (methods == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
            checkPrepared();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
            if (saKlass instanceof ArrayKlass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
                methods = new ArrayList(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
                List saMethods;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
                // Get a list of the SA Method types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
                saMethods = ((InstanceKlass)saKlass).getImmediateMethods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
                // Create a list of our MethodImpl types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
                int len = saMethods.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
                methods = new ArrayList(len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
                for (int ii = 0; ii < len; ii++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
                    methods.add(MethodImpl.createMethodImpl(vm, this, (sun.jvm.hotspot.oops.Method)saMethods.get(ii)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
            methods = Collections.unmodifiableList(methods);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
            methodsCache = new SoftReference(methods);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
        return methods;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    abstract List getAllMethods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
    public final List allMethods() throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
        List allMethods = (allMethodsCache != null)? (List) allMethodsCache.get() : null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
        if (allMethods == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
            checkPrepared();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
            allMethods = Collections.unmodifiableList(getAllMethods());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
            allMethodsCache = new SoftReference(allMethods);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
        return allMethods;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
     * Utility method used by subclasses to build lists of visible
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
     * methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
    void addToMethodMap(Map methodMap, List methodList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
        Iterator iter = methodList.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
        while (iter.hasNext()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
            Method method = (Method)iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
            methodMap.put(method.name().concat(method.signature()), method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    abstract void addVisibleMethods(Map methodMap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
    public final List visibleMethods() throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
        checkPrepared();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
         * Build a collection of all visible methods. The hash
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
         * map allows us to do this efficiently by keying on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
         * concatenation of name and signature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
        //System.out.println("jj: RTI: Calling addVisibleMethods for:" + this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
        Map map = new HashMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
        addVisibleMethods(map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
         * ... but the hash map destroys order. Methods should be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
         * returned in a sensible order, as they are in allMethods().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
         * So, start over with allMethods() and use the hash map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
         * to filter that ordered collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
        //System.out.println("jj: RTI: Calling allMethods for:" + this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
        List list = new ArrayList(allMethods());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
        //System.out.println("jj: allMethods = " + jjstr(list));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
        //System.out.println("jj: map = " + map.toString());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
        //System.out.println("jj: map = " + jjstr(map.values()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
        list.retainAll(map.values());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
        //System.out.println("jj: map = " + jjstr(list));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
        //System.exit(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
        return list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    static Object prev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    static public String jjstr(Collection cc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
        StringBuffer buf = new StringBuffer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
        buf.append("[");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
        Iterator i = cc.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
        boolean hasNext = i.hasNext();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
        while (hasNext) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
            Object o = i.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
            if (prev == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
                prev = o;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
                System.out.println("prev == curr?" + prev.equals(o));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
                System.out.println("prev == curr?" + (prev == o));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
            buf.append( o + "@" + o.hashCode());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
            //buf.append( ((Object)o).toString());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
            hasNext = i.hasNext();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
            if (hasNext)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
                buf.append(", ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
        buf.append("]");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
        return buf.toString();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
    public final List methodsByName(String name) throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
        // visibleMethods calls checkPrepared
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
        List methods = visibleMethods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
        ArrayList retList = new ArrayList(methods.size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
        Iterator iter = methods.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
        while (iter.hasNext()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
            Method candidate = (Method)iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
            if (candidate.name().equals(name)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
                retList.add(candidate);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
        retList.trimToSize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
        return retList;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
    public final List methodsByName(String name, String signature) throws ClassNotPreparedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
        // visibleMethods calls checkPrepared
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
        List methods = visibleMethods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
        ArrayList retList = new ArrayList(methods.size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
        Iterator iter = methods.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
        while (iter.hasNext()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
            Method candidate = (Method)iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
            if (candidate.name().equals(name) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
                candidate.signature().equals(signature)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
                retList.add(candidate);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
        retList.trimToSize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
        return retList;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
    List getInterfaces() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
        List myInterfaces;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
        if (saKlass instanceof ArrayKlass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
            // Actually, JLS says arrays implement Cloneable and Serializable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
            // But, JVMDI-JDI just returns 0 interfaces for arrays. We follow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
            // the same for consistency.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
            myInterfaces = new ArrayList(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
            // Get a list of the sa InstanceKlass types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
            List saInterfaces = ((InstanceKlass)saKlass).getDirectImplementedInterfaces();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
            // Create a list of our InterfaceTypes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
            int len = saInterfaces.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
            myInterfaces = new ArrayList(len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
            for (int ii = 0; ii < len; ii++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
                myInterfaces.add(new InterfaceTypeImpl(vm, (InstanceKlass)saInterfaces.get(ii)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
        return myInterfaces;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    public final List nestedTypes() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
        List nestedTypes = (nestedTypesCache != null)? (List) nestedTypesCache.get() : null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
        if (nestedTypes == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
            if (saKlass instanceof ArrayKlass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
                nestedTypes = new ArrayList(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
                ClassLoaderReference cl = classLoader();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
                List classes = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
                if (cl != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
                   classes = cl.visibleClasses();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
                } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
                   classes = vm.bootstrapClasses();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
                nestedTypes = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
                Iterator iter = classes.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
                while (iter.hasNext()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
                    ReferenceTypeImpl refType = (ReferenceTypeImpl)iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
                    Symbol candidateName = refType.ref().getName();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
                    if (((InstanceKlass)saKlass).isInnerOrLocalClassName(candidateName)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
                        nestedTypes.add(refType);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
                    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
            nestedTypes = Collections.unmodifiableList(nestedTypes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
            nestedTypesCache = new SoftReference(nestedTypes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
        return nestedTypes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    public Value getValue(Field sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
        List list = new ArrayList(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
        list.add(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
        Map map = getValues(list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
        return(Value)map.get(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
    /**
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
     * Returns a map of field values
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
    public Map getValues(List theFields) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
        //validateMirrors();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
        int size = theFields.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
        Map map = new HashMap(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
        for (int ii=0; ii<size; ii++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
            FieldImpl fieldImpl = (FieldImpl)theFields.get(ii);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
            validateFieldAccess(fieldImpl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
            // Do more validation specific to ReferenceType field getting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
            if (!fieldImpl.isStatic()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
                throw new IllegalArgumentException(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
                     "Attempt to use non-static field with ReferenceType: " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
                     fieldImpl.name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
            map.put(fieldImpl, fieldImpl.getValue());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
        return map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
    void validateFieldAccess(Field field) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
       /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
        * Field must be in this object's class, a superclass, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
        * implemented interface
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
        */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
        ReferenceTypeImpl declType = (ReferenceTypeImpl)field.declaringType();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
        if (!declType.isAssignableFrom(this)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
            throw new IllegalArgumentException("Invalid field");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
    public ClassObjectReference classObject() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
        return vm.classObjectMirror(ref().getJavaMirror());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
    SDE.Stratum stratum(String stratumID) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
        SDE sde = sourceDebugExtensionInfo();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
        if (!sde.isValid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
            sde = NO_SDE_INFO_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
        return sde.stratum(stratumID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
    public String sourceName() throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
        return (String)(sourceNames(vm.getDefaultStratum()).get(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
    public List sourceNames(String stratumID)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
                                throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
        SDE.Stratum stratum = stratum(stratumID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
        if (stratum.isJava()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
            List result = new ArrayList(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
            result.add(baseSourceName());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
            return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
        return stratum.sourceNames(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
    public List sourcePaths(String stratumID)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
                                throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
        SDE.Stratum stratum = stratum(stratumID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
        if (stratum.isJava()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
            List result = new ArrayList(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
            result.add(baseSourceDir() + baseSourceName());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
            return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
        return stratum.sourcePaths(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
    String baseSourceName() throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
      if (saKlass instanceof ArrayKlass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
            throw new AbsentInformationException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
      Symbol sym = ((InstanceKlass)saKlass).getSourceFileName();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
      if (sym != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
          return sym.asString();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
          throw new AbsentInformationException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
    String baseSourcePath() throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
        return baseSourceDir() + baseSourceName();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
    String baseSourceDir() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
        String typeName = name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
        StringBuffer sb = new StringBuffer(typeName.length() + 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
        int index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
        int nextIndex;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
        while ((nextIndex = typeName.indexOf('.', index)) > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
            sb.append(typeName.substring(index, nextIndex));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
            sb.append(java.io.File.separatorChar);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
            index = nextIndex + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
        return sb.toString();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
    public String sourceDebugExtension()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
                           throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
        if (!vm.canGetSourceDebugExtension()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
            throw new UnsupportedOperationException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
        SDE sde = sourceDebugExtensionInfo();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
        if (sde == NO_SDE_INFO_MARK) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
            throw new AbsentInformationException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
        return sde.sourceDebugExtension;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
    private SDE sourceDebugExtensionInfo() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
        if (!vm.canGetSourceDebugExtension()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
            return NO_SDE_INFO_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
        SDE sde = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
        sde = (sdeRef == null) ?  null : (SDE)sdeRef.get();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
        if (sde == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
           String extension = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
           if (saKlass instanceof InstanceKlass) {
13201
69f157caabcc 6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents: 10517
diff changeset
   691
              extension = ((InstanceKlass)saKlass).getSourceDebugExtension();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
           }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
           if (extension == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
              sde = NO_SDE_INFO_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
           } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
              sde = new SDE(extension);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
           }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
           sdeRef = new SoftReference(sde);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
        return sde;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
    public List availableStrata() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
        SDE sde = sourceDebugExtensionInfo();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
        if (sde.isValid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
            return sde.availableStrata();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
            List strata = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
            strata.add(SDE.BASE_STRATUM_NAME);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
            return strata;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
    /**
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
     * Always returns non-null stratumID
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
    public String defaultStratum() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
        SDE sdei = sourceDebugExtensionInfo();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
        if (sdei.isValid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
            return sdei.defaultStratumId;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
            return SDE.BASE_STRATUM_NAME;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
    public final int modifiers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
        if (modifiers == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
            modifiers = getModifiers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
        return modifiers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
    // new method since 1.6.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
    // Real body will be supplied later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
    public List instances(long maxInstances) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
        if (!vm.canGetInstanceInfo()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
            throw new UnsupportedOperationException(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
                      "target does not support getting instances");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
        if (maxInstances < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
            throw new IllegalArgumentException("maxInstances is less than zero: "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
                                              + maxInstances);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
        final List objects = new ArrayList(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
        if (isAbstract() || (this instanceof InterfaceType)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
            return objects;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
        final Klass givenKls = this.ref();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
        final long max = maxInstances;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
        vm.saObjectHeap().iterate(new DefaultHeapVisitor() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
                private long instCount=0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
                public boolean doObj(Oop oop) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
                    if (givenKls.equals(oop.getKlass())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
                        objects.add(vm.objectMirror(oop));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
                                                instCount++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
                    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
                    if (max > 0 && instCount >= max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
                        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
                                        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
                                        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
            });
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
        return objects;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
    int getModifiers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
        return (int) saKlass.getClassModifiers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
    public List allLineLocations()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
                            throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
        return allLineLocations(vm.getDefaultStratum(), null);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
    public List allLineLocations(String stratumID, String sourceName)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
                            throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
        checkPrepared();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
        boolean someAbsent = false; // A method that should have info, didn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
        SDE.Stratum stratum = stratum(stratumID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
        List list = new ArrayList();  // location list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
        for (Iterator iter = methods().iterator(); iter.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
            MethodImpl method = (MethodImpl)iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
            try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
                list.addAll(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
                   method.allLineLocations(stratum.id(), sourceName));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
            } catch(AbsentInformationException exc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
                someAbsent = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
        // If we retrieved no line info, and at least one of the methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
        // should have had some (as determined by an
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
        // AbsentInformationException being thrown) then we rethrow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
        // the AbsentInformationException.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
        if (someAbsent && list.size() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
            throw new AbsentInformationException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
        return list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
    public List locationsOfLine(int lineNumber)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
                           throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
        return locationsOfLine(vm.getDefaultStratum(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
                               null,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
                               lineNumber);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
    public List locationsOfLine(String stratumID,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
                                String sourceName,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
                                int lineNumber)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
                           throws AbsentInformationException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
        checkPrepared();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
        // A method that should have info, didn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
        boolean someAbsent = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
        // A method that should have info, did
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
        boolean somePresent = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
        List methods = methods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
        SDE.Stratum stratum = stratum(stratumID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
        List list = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
        Iterator iter = methods.iterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
        while(iter.hasNext()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
            MethodImpl method = (MethodImpl)iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
            // eliminate native and abstract to eliminate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
            // false positives
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
            if (!method.isAbstract() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
                !method.isNative()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
                try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
                    list.addAll(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
                       method.locationsOfLine(stratum.id(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
                                              sourceName,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
                                              lineNumber));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
                    somePresent = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
                } catch(AbsentInformationException exc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
                    someAbsent = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
                }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
        if (someAbsent && !somePresent) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
            throw new AbsentInformationException();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
        return list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
    Klass ref() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
        return saKlass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
    /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
     * Return true if an instance of this type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
     * can be assigned to a variable of the given type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
    abstract boolean isAssignableTo(ReferenceType type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
    boolean isAssignableFrom(ReferenceType type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
        return ((ReferenceTypeImpl)type).isAssignableTo(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
    boolean isAssignableFrom(ObjectReference object) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
        return object == null ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
            isAssignableFrom(object.referenceType());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
    int indexOf(Method method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
        // Make sure they're all here - the obsolete method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
        // won't be found and so will have index -1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
        return methods().indexOf(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
    int indexOf(Field field) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
        // Make sure they're all here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
        return fields().indexOf(field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
    private static boolean isPrimitiveArray(String signature) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
        int i = signature.lastIndexOf('[');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
         * TO DO: Centralize JNI signature knowledge.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
         *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
         * Ref:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
         *  jdk1.4/doc/guide/jpda/jdi/com/sun/jdi/doc-files/signature.html
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
        boolean isPA;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
        if (i < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
            isPA = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
            char c = signature.charAt(i + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
            isPA = (c != 'L');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
        return isPA;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
    Type findType(String signature) throws ClassNotLoadedException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
        Type type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
        if (signature.length() == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
            /* OTI FIX: Must be a primitive type or the void type */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
            char sig = signature.charAt(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
            if (sig == 'V') {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
                type = vm.theVoidType();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
                type = vm.primitiveTypeMirror(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
            // Must be a reference type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
            ClassLoaderReferenceImpl loader =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
                       (ClassLoaderReferenceImpl)classLoader();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
            if ((loader == null) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
                (isPrimitiveArray(signature)) //Work around 4450091
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
                ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
                // Caller wants type of boot class field
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
                type = vm.findBootType(signature);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
                // Caller wants type of non-boot class field
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
                type = loader.findType(signature);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
        return type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
    String loaderString() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
        if (classLoader() != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
            return "loaded by " + classLoader().toString();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
            return "loaded by bootstrap loader";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
    long uniqueID() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
        return vm.getAddressValue(ref());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
    // new method since 1.6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
    public int majorVersion() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
        if (!vm.canGetClassFileVersion()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
            throw new UnsupportedOperationException("Cannot get class file version");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
        return (int)((InstanceKlass)saKlass).majorVersion();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
    // new method since 1.6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
    public int minorVersion() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
        if (!vm.canGetClassFileVersion()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
            throw new UnsupportedOperationException("Cannot get class file version");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
        return (int)((InstanceKlass)saKlass).minorVersion();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
    // new method since 1.6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
    public int constantPoolCount() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
        if (!vm.canGetConstantPool()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
            throw new UnsupportedOperationException("Cannot get constant pool");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
        if (saKlass instanceof ArrayKlass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
            return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
            return (int)((InstanceKlass)saKlass).getConstants().getLength();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
    // new method since 1.6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
    public byte[] constantPool() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
        if (!vm.canGetConstantPool()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
            throw new UnsupportedOperationException("Cannot get constant pool");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
        if (this instanceof ArrayType || this instanceof PrimitiveType) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
                        byte bytes[] = new byte[0];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
            return bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
            try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
                ((InstanceKlass)saKlass).getConstants().writeBytes(bs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
            } catch (IOException ex) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
                                ex.printStackTrace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
                                byte bytes[] = new byte[0];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
                                return bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
            return bs.toByteArray();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
}