src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/RegisterMap.java
author erikj
Tue, 12 Sep 2017 19:03:39 +0200
changeset 47216 71c04702a3d5
parent 35217 hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/RegisterMap.java@ce4b5303a813
permissions -rw-r--r--
8187443: Forest Consolidation: Move files to unified layout Reviewed-by: darcy, ihse
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
     2
 * Copyright (c) 2000, 2006, 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.runtime;
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
import sun.jvm.hotspot.debugger.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
import sun.jvm.hotspot.interpreter.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
import sun.jvm.hotspot.code.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
import sun.jvm.hotspot.types.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
import sun.jvm.hotspot.utilities.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
/** <P> A companion structure used for stack traversal. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
    RegisterMap contains misc. information needed in order to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
    correct stack traversal of stack frames.  Hence, it must always be
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
    passed in as an argument to Frame.sender(RegisterMap). </P>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
    <P> The use of RegisterMaps is slightly different in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
    Serviceability Agent APIs than in the VM itself. In the VM, a
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
    RegisterMap is created either for a particular thread or cloned
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
    from another RegisterMap. In these APIs, a JavaThread is the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
    top-level factory for RegisterMaps, and RegisterMaps know how to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
    copy themselves (through either the clone() or copy()
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
    methods). </P> */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
public abstract class RegisterMap implements Cloneable {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  /** Location of registers */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  protected Address[]  location;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  // FIXME: don't know about LocationValidType
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
  protected long[]     locationValid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  /** Should include argument_oop marked locations for compiler */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  protected boolean    includeArgumentOops;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  /** Reference to current thread */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  protected JavaThread thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  /** Tells if the register map needs to be updated when traversing the stack */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  protected boolean    updateMap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  /** Location of a frame where the pc is not at a call (NULL if no frame exists) */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  protected static int regCount;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  protected static int locationValidTypeSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  protected static int locationValidSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  static {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    VM.registerVMInitializedObserver(new Observer() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
        public void update(Observable o, Object data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
          initialize(VM.getVM().getTypeDataBase());
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  private static void initialize(TypeDataBase db) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
    regCount = db.lookupIntConstant("ConcreteRegisterImpl::number_of_registers").intValue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
    // FIXME: don't know about LocationValidType. The LocationValidType is typedef'ed as julong
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    // so used julong to get the size of LocationValidType.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
    locationValidTypeSize = (int)db.lookupType("julong").getSize() * 8;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
    locationValidSize = (regCount + locationValidTypeSize - 1) / locationValidTypeSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  protected RegisterMap(JavaThread thread, boolean updateMap) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
    this.thread    = thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    this.updateMap = updateMap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    location      = new Address[regCount];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
    locationValid = new long[locationValidSize];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
    clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  /** Makes a copy of map into this */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  protected RegisterMap(RegisterMap map) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
      Assert.that(map != null, "RegisterMap must be present");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    this.thread              = map.getThread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    this.updateMap           = map.getUpdateMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    this.includeArgumentOops = map.getIncludeArgumentOops();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    location                 = new Address[map.location.length];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    locationValid            = new long[map.locationValid.length];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    initializeFromPD(map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    if (updateMap) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
      for (int i = 0; i < locationValidSize; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
        long bits = (!getUpdateMap()) ? 0 : map.locationValid[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
        locationValid[i] = bits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
        // for whichever bits are set, pull in the corresponding map->_location
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
        int j = i*locationValidTypeSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
        while (bits != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
          if ((bits & 1) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
            if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
              Assert.that(0 <= j && j < regCount, "range check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
            location[j] = map.location[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
          bits >>>= 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
          j += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  public abstract Object clone();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  public RegisterMap copy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
    return (RegisterMap) clone();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  public void clear() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    setIncludeArgumentOops(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    if (!VM.getVM().isCore()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
      if (updateMap) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
        for (int i = 0; i < locationValid.length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
          locationValid[i] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
        clearPD();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
        initializePD();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  public Address getLocation(VMReg reg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
    int i = reg.getValue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    int index = i / locationValidTypeSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
    if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
      Assert.that(0 <= i && i < regCount, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
      Assert.that(0 <= index && index < locationValidSize, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    if ((locationValid[index] & (1 << i % locationValidTypeSize)) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
      return location[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
      return getLocationPD(reg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  public void setLocation(VMReg reg, Address loc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    int i = reg.getValue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    int index = i / locationValidTypeSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
      Assert.that(0 <= i && i < regCount, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
      Assert.that(0 <= index && index < locationValidSize, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
      Assert.that(updateMap, "updating map that does not need updating");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    location[i]          = loc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    locationValid[index] |= (1 << (i % locationValidTypeSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  public boolean getIncludeArgumentOops() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    return includeArgumentOops;
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 void setIncludeArgumentOops(boolean f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    includeArgumentOops = f;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  public JavaThread getThread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    return thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  public boolean getUpdateMap() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    return updateMap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  public void print() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    printOn(System.out);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  public void printOn(PrintStream tty) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    tty.println("Register map");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    for (int i = 0; i < location.length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
      Address src = getLocation(new VMReg(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
      if (src != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
        tty.print("  " + VMRegImpl.getRegisterName(i) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
                  " [" + src + "] = ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
        if (src.andWithMask(VM.getVM().getAddressSize() - 1) != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
          tty.print("<misaligned>");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
          tty.print(src.getAddressAt(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
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  /** Platform-dependent clear() functionality */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  protected abstract void clearPD();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  /** Platform-dependent initialize() functionality */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  protected abstract void initializePD();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  /** Platform-dependent initializeFrom() functionality */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  protected abstract void initializeFromPD(RegisterMap map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  /** Platform-dependent getLocation() functionality */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  protected abstract Address getLocationPD(VMReg reg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
}