hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java
author coleenp
Sun, 13 Apr 2008 17:43:42 -0400
changeset 360 21d113ecbf6a
parent 1 489c9b5090e2
child 670 ddf3e9583f2f
permissions -rw-r--r--
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
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
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
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;
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
import java.util.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
import sun.jvm.hotspot.debugger.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
import sun.jvm.hotspot.types.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
import sun.jvm.hotspot.types.basic.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
import sun.jvm.hotspot.utilities.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
/** <P> This is the cross-platform TypeDataBase used by the Oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
    hierarchy. The decision was made to make this cross-platform by
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
    having the VM export the necessary symbols via a built-in table;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
    see src/share/vm/runtime/vmStructs.[ch]pp for more details. </P>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
    <P> <B>WARNING</B>: clients should refer to this class through the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
    TypeDataBase interface and not directly to the HotSpotTypeDataBase
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
    type. </P>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
    <P> NOTE: since we are fetching the sizes of the Java primitive types
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
public class HotSpotTypeDataBase extends BasicTypeDataBase {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  private Debugger symbolLookup;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  private String[] jvmLibNames;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  private static final int UNINITIALIZED_SIZE = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  private static final int C_INT8_SIZE  = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  private static final int C_INT32_SIZE = 4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  private static final int C_INT64_SIZE = 8;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  private static final boolean DEBUG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  static {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    DEBUG = System.getProperty("sun.jvm.hotspot.HotSpotTypeDataBase.DEBUG")
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
            != null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  /** <P> This requires a SymbolLookup mechanism as well as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
      MachineDescription. Note that we do not need a NameMangler since
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
      we use the vmStructs mechanism to avoid looking up C++
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
      symbols. </P>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
      <P> NOTE that it is guaranteed that this constructor will not
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
      attempt to fetch any Java values from the remote process, only C
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
      integers and addresses. This is required because we are fetching
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
      the sizes of the Java primitive types from the remote process,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
      implying that attempting to fetch them before their sizes are
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
      known is illegal. </P>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
      <P> Throws NoSuchSymbolException if a problem occurred while
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
      looking up one of the bootstrapping symbols related to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
      VMStructs table in the remote VM; this may indicate that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
      remote process is not actually a HotSpot VM. </P>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  public HotSpotTypeDataBase(MachineDescription machDesc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
                             VtblAccess vtblAccess,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
                             Debugger symbolLookup,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
                             String[] jvmLibNames) throws NoSuchSymbolException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
    super(machDesc, vtblAccess);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
    this.symbolLookup = symbolLookup;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    this.jvmLibNames = jvmLibNames;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
    readVMTypes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
    initializePrimitiveTypes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
    readVMStructs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
    readVMIntConstants();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    readVMLongConstants();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  private void readVMTypes() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    // Get the variables we need in order to traverse the VMTypeEntry[]
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    long typeEntryTypeNameOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    long typeEntrySuperclassNameOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    long typeEntryIsOopTypeOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    long typeEntryIsIntegerTypeOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    long typeEntryIsUnsignedOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    long typeEntrySizeOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    long typeEntryArrayStride;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
    typeEntryTypeNameOffset       = getLongValueFromProcess("gHotSpotVMTypeEntryTypeNameOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    typeEntrySuperclassNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySuperclassNameOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
    typeEntryIsOopTypeOffset      = getLongValueFromProcess("gHotSpotVMTypeEntryIsOopTypeOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
    typeEntryIsIntegerTypeOffset  = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
    typeEntryIsUnsignedOffset     = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
    typeEntrySizeOffset           = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
    typeEntryArrayStride          = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    // Fetch the address of the VMTypeEntry*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    Address entryAddr = lookupInProcess("gHotSpotVMTypes");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    //    System.err.println("gHotSpotVMTypes address = " + entryAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    // Dereference this once to get the pointer to the first VMTypeEntry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    //    dumpMemory(entryAddr, 80);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    entryAddr = entryAddr.getAddressAt(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
    if (entryAddr == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
      throw new RuntimeException("gHotSpotVMTypes was not initialized properly in the remote process; can not continue");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    // Start iterating down it until we find an entry with no name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    Address typeNameAddr = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
      // Fetch the type name first
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
      typeNameAddr = entryAddr.getAddressAt(typeEntryTypeNameOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
      if (typeNameAddr != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
        String typeName = CStringUtilities.getString(typeNameAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
        String superclassName = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
        Address superclassNameAddr = entryAddr.getAddressAt(typeEntrySuperclassNameOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
        if (superclassNameAddr != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
          superclassName = CStringUtilities.getString(superclassNameAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
        boolean isOopType     = (entryAddr.getCIntegerAt(typeEntryIsOopTypeOffset, C_INT32_SIZE, false) != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
        boolean isIntegerType = (entryAddr.getCIntegerAt(typeEntryIsIntegerTypeOffset, C_INT32_SIZE, false) != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
        boolean isUnsigned    = (entryAddr.getCIntegerAt(typeEntryIsUnsignedOffset, C_INT32_SIZE, false) != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
        long size             = entryAddr.getCIntegerAt(typeEntrySizeOffset, C_INT64_SIZE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
        createType(typeName, superclassName, isOopType, isIntegerType, isUnsigned, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
      entryAddr = entryAddr.addOffsetTo(typeEntryArrayStride);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    } while (typeNameAddr != null);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  private void initializePrimitiveTypes() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
    // Look up the needed primitive types by name...they had better be present
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    setJBooleanType(lookupPrimitiveType("jboolean"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    setJByteType   (lookupPrimitiveType("jbyte"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    setJCharType   (lookupPrimitiveType("jchar"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    setJDoubleType (lookupPrimitiveType("jdouble"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    setJFloatType  (lookupPrimitiveType("jfloat"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
    setJIntType    (lookupPrimitiveType("jint"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    setJLongType   (lookupPrimitiveType("jlong"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    setJShortType  (lookupPrimitiveType("jshort"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    // Indicate that these are the Java primitive types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    ((BasicType) getJBooleanType()).setIsJavaPrimitiveType(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    ((BasicType) getJByteType()).setIsJavaPrimitiveType(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    ((BasicType) getJCharType()).setIsJavaPrimitiveType(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    ((BasicType) getJDoubleType()).setIsJavaPrimitiveType(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    ((BasicType) getJFloatType()).setIsJavaPrimitiveType(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
    ((BasicType) getJIntType()).setIsJavaPrimitiveType(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    ((BasicType) getJLongType()).setIsJavaPrimitiveType(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    ((BasicType) getJShortType()).setIsJavaPrimitiveType(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  private Type lookupPrimitiveType(String typeName) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    Type type = lookupType(typeName, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    if (type == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
      throw new RuntimeException("Error initializing the HotSpotDataBase: could not find the primitive type \"" +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
                                 typeName + "\" in the remote VM's VMStructs table. This type is required in " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
                                 "order to determine the size of Java primitive types. Can not continue.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
    return type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  private void readVMStructs() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    // Get the variables we need in order to traverse the VMStructEntry[]
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
    long structEntryTypeNameOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    long structEntryFieldNameOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    long structEntryTypeStringOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    long structEntryIsStaticOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    long structEntryOffsetOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
    long structEntryAddressOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    long structEntryArrayStride;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    structEntryTypeNameOffset     = getLongValueFromProcess("gHotSpotVMStructEntryTypeNameOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    structEntryFieldNameOffset    = getLongValueFromProcess("gHotSpotVMStructEntryFieldNameOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    structEntryTypeStringOffset   = getLongValueFromProcess("gHotSpotVMStructEntryTypeStringOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
    structEntryIsStaticOffset     = getLongValueFromProcess("gHotSpotVMStructEntryIsStaticOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
    structEntryOffsetOffset       = getLongValueFromProcess("gHotSpotVMStructEntryOffsetOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
    structEntryAddressOffset      = getLongValueFromProcess("gHotSpotVMStructEntryAddressOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
    structEntryArrayStride        = getLongValueFromProcess("gHotSpotVMStructEntryArrayStride");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    // Fetch the address of the VMStructEntry*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    Address entryAddr = lookupInProcess("gHotSpotVMStructs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    // Dereference this once to get the pointer to the first VMStructEntry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    entryAddr = entryAddr.getAddressAt(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    if (entryAddr == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
      throw new RuntimeException("gHotSpotVMStructs was not initialized properly in the remote process; can not continue");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    // Start iterating down it until we find an entry with no name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
    Address fieldNameAddr = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    String typeName = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    String fieldName = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    String typeString = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
    boolean isStatic = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
    long offset = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    Address staticFieldAddr = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    long size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    long index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    String opaqueName = "<opaque>";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
    lookupOrCreateClass(opaqueName, false, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
      // Fetch the field name first
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
      fieldNameAddr = entryAddr.getAddressAt(structEntryFieldNameOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
      if (fieldNameAddr != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
        fieldName = CStringUtilities.getString(fieldNameAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
        // Now the rest of the names. Keep in mind that the type name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
        // may be NULL, indicating that the type is opaque.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
        Address addr = entryAddr.getAddressAt(structEntryTypeNameOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
        if (addr == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
          throw new RuntimeException("gHotSpotVMStructs unexpectedly had a NULL type name at index " + index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
        typeName = CStringUtilities.getString(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
        addr = entryAddr.getAddressAt(structEntryTypeStringOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
        if (addr == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
          typeString = opaqueName;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
          typeString = CStringUtilities.getString(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
        isStatic = !(entryAddr.getCIntegerAt(structEntryIsStaticOffset, C_INT32_SIZE, false) == 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
        if (isStatic) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
          staticFieldAddr = entryAddr.getAddressAt(structEntryAddressOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
          offset = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
          offset = entryAddr.getCIntegerAt(structEntryOffsetOffset, C_INT64_SIZE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
          staticFieldAddr = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
        // The containing Type must already be in the database -- no exceptions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
        BasicType containingType = lookupOrFail(typeName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
        // The field's Type must already be in the database -- no exceptions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
        BasicType fieldType = lookupOrFail(typeString);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
        // Create field by type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
        createField(containingType, fieldName, fieldType,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
                    isStatic, offset, staticFieldAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
      ++index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
      entryAddr = entryAddr.addOffsetTo(structEntryArrayStride);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
    } while (fieldNameAddr != null);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  private void readVMIntConstants() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    // Get the variables we need in order to traverse the VMIntConstantEntry[]
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    long intConstantEntryNameOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
    long intConstantEntryValueOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
    long intConstantEntryArrayStride;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
    intConstantEntryNameOffset  = getLongValueFromProcess("gHotSpotVMIntConstantEntryNameOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
    intConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMIntConstantEntryValueOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    intConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMIntConstantEntryArrayStride");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    // Fetch the address of the VMIntConstantEntry*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    Address entryAddr = lookupInProcess("gHotSpotVMIntConstants");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    // Dereference this once to get the pointer to the first VMIntConstantEntry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
    entryAddr = entryAddr.getAddressAt(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
    if (entryAddr == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
      throw new RuntimeException("gHotSpotVMIntConstants was not initialized properly in the remote process; can not continue");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
    // Start iterating down it until we find an entry with no name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
    Address nameAddr = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
      // Fetch the type name first
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
      nameAddr = entryAddr.getAddressAt(intConstantEntryNameOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
      if (nameAddr != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
        String name = CStringUtilities.getString(nameAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
        int value = (int) entryAddr.getCIntegerAt(intConstantEntryValueOffset, C_INT32_SIZE, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
        // Be a little resilient
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
        Integer oldValue = lookupIntConstant(name, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
        if (oldValue == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
          addIntConstant(name, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
          if (oldValue.intValue() != value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
            throw new RuntimeException("Error: the integer constant \"" + name +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
                                       "\" had its value redefined (old was " + oldValue +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
                                       ", new is " + value + ". Aborting.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
            System.err.println("Warning: the int constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMIntConstants) " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
                               "had its value declared as " + value + " twice. Continuing.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
      entryAddr = entryAddr.addOffsetTo(intConstantEntryArrayStride);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    } while (nameAddr != null);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   309
      String symbol = "heapOopSize"; // global int constant and value is initialized at runtime.
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   310
      addIntConstant(symbol, (int)lookupInProcess(symbol).getCIntegerAt(0, 4, false));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  private void readVMLongConstants() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
    // Get the variables we need in order to traverse the VMLongConstantEntry[]
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    long longConstantEntryNameOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
    long longConstantEntryValueOffset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
    long longConstantEntryArrayStride;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    longConstantEntryNameOffset  = getLongValueFromProcess("gHotSpotVMLongConstantEntryNameOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
    longConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMLongConstantEntryValueOffset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    longConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMLongConstantEntryArrayStride");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
    // Fetch the address of the VMLongConstantEntry*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
    Address entryAddr = lookupInProcess("gHotSpotVMLongConstants");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
    // Dereference this once to get the pointer to the first VMLongConstantEntry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    entryAddr = entryAddr.getAddressAt(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    if (entryAddr == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
      throw new RuntimeException("gHotSpotVMLongConstants was not initialized properly in the remote process; can not continue");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
    // Start iterating down it until we find an entry with no name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    Address nameAddr = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
      // Fetch the type name first
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
      nameAddr = entryAddr.getAddressAt(longConstantEntryNameOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
      if (nameAddr != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
        String name = CStringUtilities.getString(nameAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
        int value = (int) entryAddr.getCIntegerAt(longConstantEntryValueOffset, C_INT64_SIZE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
        // Be a little resilient
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
        Long oldValue = lookupLongConstant(name, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
        if (oldValue == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
          addLongConstant(name, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
          if (oldValue.longValue() != value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
            throw new RuntimeException("Error: the long constant \"" + name +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
                                       "\" had its value redefined (old was " + oldValue +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
                                       ", new is " + value + ". Aborting.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
            System.err.println("Warning: the long constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMLongConstants) " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
                               "had its value declared as " + value + " twice. Continuing.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
      entryAddr = entryAddr.addOffsetTo(longConstantEntryArrayStride);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    } while (nameAddr != null);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
  private BasicType lookupOrFail(String typeName) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
    BasicType type = (BasicType) lookupType(typeName, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
    if (type == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
      throw new RuntimeException("Type \"" + typeName + "\", referenced in VMStructs::localHotSpotVMStructs in the remote VM, " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
                                 "was not present in the remote VMStructs::localHotSpotVMTypes table (should have been caught " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
                                 "in the debug build of that VM). Can not continue.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
    return type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  private long getLongValueFromProcess(String symbol) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
    return lookupInProcess(symbol).getCIntegerAt(0, C_INT64_SIZE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  private Address lookupInProcess(String symbol) throws NoSuchSymbolException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
    // FIXME: abstract away the loadobject name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
    for (int i = 0; i < jvmLibNames.length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
      Address addr = symbolLookup.lookup(jvmLibNames[i], symbol);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
      if (addr != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
        return addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
    String errStr = "(";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
    for (int i = 0; i < jvmLibNames.length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
      errStr += jvmLibNames[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
      if (i < jvmLibNames.length - 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
        errStr += ", ";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
    errStr += ")";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
    throw new NoSuchSymbolException(symbol,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
                                    "Could not find symbol \"" + symbol +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
                                    "\" in any of the known library names " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
                                    errStr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  private BasicType lookupOrCreateClass(String typeName, boolean isOopType,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
                                        boolean isIntegerType, boolean isUnsigned) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
    BasicType type = (BasicType) lookupType(typeName, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    if (type == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
      // Create a new type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
      type = createBasicType(typeName, isOopType, isIntegerType, isUnsigned);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
    return type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  /** Creates a new BasicType, initializes its size to -1 so we can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
      test to ensure that all types' sizes are initialized by VMTypes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
      and adds it to the database. Takes care of initializing integer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
      and oop types properly. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  private BasicType createBasicType(String typeName, boolean isOopType,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
                                    boolean isIntegerType, boolean isUnsigned) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
    BasicType type = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    if (isIntegerType) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
      type = new BasicCIntegerType(this, typeName, isUnsigned);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
      if (typeNameIsPointerType(typeName)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
        type = recursiveCreateBasicPointerType(typeName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
        type = new BasicType(this, typeName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
      if (isOopType) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
        // HACK: turn markOop into a C integer type. This allows
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
        // proper handling of it in the Serviceability Agent. (FIXME
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
        // -- consider doing something different here)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
        if (typeName.equals("markOop")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
          type = new BasicCIntegerType(this, typeName, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
          type.setIsOopType(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
    type.setSize(UNINITIALIZED_SIZE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
    addType(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
    return type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  /** Recursively creates a PointerType from the string representation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
      of the type's name. Note that this currently needs some
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
      workarounds due to incomplete information in the VMStructs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
      database. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  private BasicPointerType recursiveCreateBasicPointerType(String typeName) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
    String targetTypeName = typeName.substring(0, typeName.lastIndexOf('*')).trim();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    Type targetType = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
    if (typeNameIsPointerType(targetTypeName)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
      targetType = recursiveCreateBasicPointerType(targetTypeName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
      targetType = lookupType(targetTypeName, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
      if (targetType == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
        // Workaround for missing C integer types in database.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
        // Also looks like we can't throw an exception for other
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
        // missing target types because there are some in old
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
        // VMStructs tables that didn't have the target type declared.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
        // For this case, we create basic types that never get filled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
        // in.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
        if (targetTypeName.equals("char") ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
            targetTypeName.equals("const char")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
          // We don't have a representation of const-ness of C types in the SA
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
          BasicType basicTargetType = createBasicType(targetTypeName, false, true, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
          basicTargetType.setSize(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
          targetType = basicTargetType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
        } else if (targetTypeName.equals("u_char")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
          BasicType basicTargetType = createBasicType(targetTypeName, false, true, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
          basicTargetType.setSize(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
          targetType = basicTargetType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
          if (DEBUG) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
            System.err.println("WARNING: missing target type \"" + targetTypeName + "\" for pointer type \"" + typeName + "\"");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
          targetType = createBasicType(targetTypeName, false, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
    return new BasicPointerType(this, typeName, targetType);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  private boolean typeNameIsPointerType(String typeName) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
    int i = typeName.length() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
    while (i >= 0 && Character.isWhitespace(typeName.charAt(i))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
      --i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
    if (i >= 0 && typeName.charAt(i) == '*') {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
    public void createType(String typeName, String superclassName,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
                           boolean isOopType, boolean isIntegerType,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
                           boolean isUnsigned, long size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
        // See whether we have a superclass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
        BasicType superclass = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
        if (superclassName != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
            // Fetch or create it (FIXME: would get oop types wrong if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
            // they had a hierarchy; consider using lookupOrFail)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
            superclass = lookupOrCreateClass(superclassName, false, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
        // Lookup or create the current type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
        BasicType curType = lookupOrCreateClass(typeName, isOopType, isIntegerType, isUnsigned);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
        // Set superclass and/or ensure it's correct
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
        if (superclass != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
            if (curType.getSuperclass() == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
                // Set the superclass in the current type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
                curType.setSuperclass(superclass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
            if (curType.getSuperclass() != superclass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
                throw new RuntimeException("Error: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
                                           "had its superclass redefined (old was " + curType.getSuperclass().getName() + ", new is " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
                                           superclass.getName() + ").");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
        // Classes are created with a size of UNINITIALIZED_SIZE.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
        // Set size if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
        if (curType.getSize() == UNINITIALIZED_SIZE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
            curType.setSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
            if (curType.getSize() != size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
                throw new RuntimeException("Error: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
                                           "had its size redefined (old was " + curType.getSize() + ", new is " + size + ").");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
            System.err.println("Warning: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
                               "had its size declared as " + size + " twice. Continuing.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
    /** "Virtual constructor" for fields based on type */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    public void createField(BasicType containingType,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
                            String name, Type type, boolean isStatic,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
                            long offset, Address staticFieldAddress) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
        // Add field to containing type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
        containingType.addField(internalCreateField(containingType, name, type, isStatic, offset, staticFieldAddress));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
    Field internalCreateField(BasicType containingType,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
                              String name, Type type, boolean isStatic,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
                              long offset, Address staticFieldAddress) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
    // "Virtual constructor" based on type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
    if (type.isOopType()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
      return new BasicOopField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
                               isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
    if (type instanceof CIntegerType) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
      return new BasicCIntegerField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
                                    isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
    if (type.equals(getJBooleanType())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
      return new BasicJBooleanField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
                                    isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    if (type.equals(getJByteType())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
      return new BasicJByteField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
                                 isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    if (type.equals(getJCharType())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
      return new BasicJCharField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
                                 isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
    if (type.equals(getJDoubleType())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
      return new BasicJDoubleField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
                                   isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
    if (type.equals(getJFloatType())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
      return new BasicJFloatField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
                                  isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
    if (type.equals(getJIntType())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
      return new BasicJIntField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
                                isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
    if (type.equals(getJLongType())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
      return new BasicJLongField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
                                 isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
    if (type.equals(getJShortType())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
      return new BasicJShortField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
                                  isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
    // Unknown ("opaque") type. Instantiate ordinary Field.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
    return new BasicField(this, containingType, name, type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
                          isStatic, offset, staticFieldAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  // For debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  private void dumpMemory(Address addr, int len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
    int i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    while (i < len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
      System.err.print(addr.addOffsetTo(i) + ":");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
      for (int j = 0; j < 8 && i < len; i++, j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
        String s = Long.toHexString(addr.getCIntegerAt(i, 1, true));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
        System.err.print(" 0x");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
        for (int k = 0; k < 2 - s.length(); k++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
          System.err.print("0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
        System.err.print(s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
      System.err.println();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
}