comparison agent/src/share/classes/sun/jvm/hotspot/runtime/RegisterMap.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 package sun.jvm.hotspot.runtime;
26
27 import java.io.*;
28 import java.util.*;
29
30 import sun.jvm.hotspot.debugger.*;
31 import sun.jvm.hotspot.interpreter.*;
32 import sun.jvm.hotspot.code.*;
33 import sun.jvm.hotspot.types.*;
34 import sun.jvm.hotspot.utilities.*;
35
36 /** <P> A companion structure used for stack traversal. The
37 RegisterMap contains misc. information needed in order to do
38 correct stack traversal of stack frames. Hence, it must always be
39 passed in as an argument to Frame.sender(RegisterMap). </P>
40
41 <P> The use of RegisterMaps is slightly different in the
42 Serviceability Agent APIs than in the VM itself. In the VM, a
43 RegisterMap is created either for a particular thread or cloned
44 from another RegisterMap. In these APIs, a JavaThread is the
45 top-level factory for RegisterMaps, and RegisterMaps know how to
46 copy themselves (through either the clone() or copy()
47 methods). </P> */
48
49 public abstract class RegisterMap implements Cloneable {
50 /** Location of registers */
51 protected Address[] location;
52 // FIXME: don't know about LocationValidType
53 protected long[] locationValid;
54 /** Should include argument_oop marked locations for compiler */
55 protected boolean includeArgumentOops;
56 /** Reference to current thread */
57 protected JavaThread thread;
58 /** Tells if the register map needs to be updated when traversing the stack */
59 protected boolean updateMap;
60 /** Location of a frame where the pc is not at a call (NULL if no frame exists) */
61 protected static int regCount;
62 protected static int locationValidTypeSize;
63 protected static int locationValidSize;
64
65 static {
66 VM.registerVMInitializedObserver(new Observer() {
67 public void update(Observable o, Object data) {
68 initialize(VM.getVM().getTypeDataBase());
69 }
70 });
71 }
72
73 private static void initialize(TypeDataBase db) {
74 regCount = db.lookupIntConstant("ConcreteRegisterImpl::number_of_registers").intValue();
75 // FIXME: don't know about LocationValidType. The LocationValidType is typedef'ed as julong
76 // so used julong to get the size of LocationValidType.
77 locationValidTypeSize = (int)db.lookupType("julong").getSize() * 8;
78 locationValidSize = (regCount + locationValidTypeSize - 1) / locationValidTypeSize;
79 }
80
81 protected RegisterMap(JavaThread thread, boolean updateMap) {
82 this.thread = thread;
83 this.updateMap = updateMap;
84 location = new Address[regCount];
85 locationValid = new long[locationValidSize];
86 clear();
87 }
88
89 /** Makes a copy of map into this */
90 protected RegisterMap(RegisterMap map) {
91 if (Assert.ASSERTS_ENABLED) {
92 Assert.that(map != null, "RegisterMap must be present");
93 }
94 this.thread = map.getThread();
95 this.updateMap = map.getUpdateMap();
96 this.includeArgumentOops = map.getIncludeArgumentOops();
97 location = new Address[map.location.length];
98 locationValid = new long[map.locationValid.length];
99 initializeFromPD(map);
100 if (updateMap) {
101 for (int i = 0; i < locationValidSize; i++) {
102 long bits = (!getUpdateMap()) ? 0 : map.locationValid[i];
103 locationValid[i] = bits;
104 // for whichever bits are set, pull in the corresponding map->_location
105 int j = i*locationValidTypeSize;
106 while (bits != 0) {
107 if ((bits & 1) != 0) {
108 if (Assert.ASSERTS_ENABLED) {
109 Assert.that(0 <= j && j < regCount, "range check");
110 }
111 location[j] = map.location[j];
112 }
113 bits >>>= 1;
114 j += 1;
115 }
116 }
117 }
118 }
119
120 public abstract Object clone();
121
122 public RegisterMap copy() {
123 return (RegisterMap) clone();
124 }
125
126 public void clear() {
127 setIncludeArgumentOops(true);
128 if (!VM.getVM().isCore()) {
129 if (updateMap) {
130 for (int i = 0; i < locationValid.length; i++) {
131 locationValid[i] = 0;
132 }
133 clearPD();
134 } else {
135 initializePD();
136 }
137 }
138 }
139
140 public Address getLocation(VMReg reg) {
141 int i = reg.getValue();
142 int index = i / locationValidTypeSize;
143 if (Assert.ASSERTS_ENABLED) {
144 Assert.that(0 <= i && i < regCount, "sanity check");
145 Assert.that(0 <= index && index < locationValidSize, "sanity check");
146 }
147 if ((locationValid[index] & (1 << i % locationValidTypeSize)) != 0) {
148 return location[i];
149 } else {
150 return getLocationPD(reg);
151 }
152 }
153
154 public void setLocation(VMReg reg, Address loc) {
155 int i = reg.getValue();
156 int index = i / locationValidTypeSize;
157 if (Assert.ASSERTS_ENABLED) {
158 Assert.that(0 <= i && i < regCount, "sanity check");
159 Assert.that(0 <= index && index < locationValidSize, "sanity check");
160 Assert.that(updateMap, "updating map that does not need updating");
161 }
162 location[i] = loc;
163 locationValid[index] |= (1 << (i % locationValidTypeSize));
164 }
165
166 public boolean getIncludeArgumentOops() {
167 return includeArgumentOops;
168 }
169
170 public void setIncludeArgumentOops(boolean f) {
171 includeArgumentOops = f;
172 }
173
174 public JavaThread getThread() {
175 return thread;
176 }
177
178 public boolean getUpdateMap() {
179 return updateMap;
180 }
181
182 public void print() {
183 printOn(System.out);
184 }
185
186 public void printOn(PrintStream tty) {
187 tty.println("Register map");
188 for (int i = 0; i < location.length; i++) {
189 Address src = getLocation(new VMReg(i));
190 if (src != null) {
191 tty.print(" " + VMRegImpl.getRegisterName(i) +
192 " [" + src + "] = ");
193 if (src.andWithMask(VM.getVM().getAddressSize() - 1) != null) {
194 tty.print("<misaligned>");
195 } else {
196 tty.print(src.getAddressAt(0));
197 }
198 }
199 }
200 }
201
202 /** Platform-dependent clear() functionality */
203 protected abstract void clearPD();
204 /** Platform-dependent initialize() functionality */
205 protected abstract void initializePD();
206 /** Platform-dependent initializeFrom() functionality */
207 protected abstract void initializeFromPD(RegisterMap map);
208 /** Platform-dependent getLocation() functionality */
209 protected abstract Address getLocationPD(VMReg reg);
210 }