0
|
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.compiler;
|
|
26
|
|
27 import java.util.*;
|
|
28
|
|
29 import sun.jvm.hotspot.code.*;
|
|
30 import sun.jvm.hotspot.runtime.*;
|
|
31 import sun.jvm.hotspot.types.*;
|
|
32 import sun.jvm.hotspot.utilities.*;
|
|
33
|
|
34 public class OopMapValue {
|
|
35 private short value;
|
|
36 private short contentReg;
|
|
37
|
|
38 /** Read from target VM; located in compiler/oopMap.hpp */
|
|
39 // How bits are organized
|
|
40 static int TYPE_BITS;
|
|
41 static int REGISTER_BITS;
|
|
42 static int TYPE_SHIFT;
|
|
43 static int REGISTER_SHIFT;
|
|
44 static int TYPE_MASK;
|
|
45 static int TYPE_MASK_IN_PLACE;
|
|
46 static int REGISTER_MASK;
|
|
47 static int REGISTER_MASK_IN_PLACE;
|
|
48
|
|
49 // Types of OopValues
|
|
50 static int UNUSED_VALUE;
|
|
51 static int OOP_VALUE;
|
|
52 static int VALUE_VALUE;
|
|
53 static int DEAD_VALUE;
|
|
54 static int CALLEE_SAVED_VALUE;
|
|
55 static int DERIVED_OOP_VALUE;
|
|
56
|
|
57 static {
|
|
58 VM.registerVMInitializedObserver(new Observer() {
|
|
59 public void update(Observable o, Object data) {
|
|
60 initialize(VM.getVM().getTypeDataBase());
|
|
61 }
|
|
62 });
|
|
63 }
|
|
64
|
|
65 private static void initialize(TypeDataBase db) {
|
|
66 TYPE_BITS = db.lookupIntConstant("OopMapValue::type_bits").intValue();
|
|
67 REGISTER_BITS = db.lookupIntConstant("OopMapValue::register_bits").intValue();
|
|
68 TYPE_SHIFT = db.lookupIntConstant("OopMapValue::type_shift").intValue();
|
|
69 REGISTER_SHIFT = db.lookupIntConstant("OopMapValue::register_shift").intValue();
|
|
70 TYPE_MASK = db.lookupIntConstant("OopMapValue::type_mask").intValue();
|
|
71 TYPE_MASK_IN_PLACE = db.lookupIntConstant("OopMapValue::type_mask_in_place").intValue();
|
|
72 REGISTER_MASK = db.lookupIntConstant("OopMapValue::register_mask").intValue();
|
|
73 REGISTER_MASK_IN_PLACE = db.lookupIntConstant("OopMapValue::register_mask_in_place").intValue();
|
|
74 UNUSED_VALUE = db.lookupIntConstant("OopMapValue::unused_value").intValue();
|
|
75 OOP_VALUE = db.lookupIntConstant("OopMapValue::oop_value").intValue();
|
|
76 VALUE_VALUE = db.lookupIntConstant("OopMapValue::value_value").intValue();
|
|
77 DEAD_VALUE = db.lookupIntConstant("OopMapValue::dead_value").intValue();
|
|
78 CALLEE_SAVED_VALUE = db.lookupIntConstant("OopMapValue::callee_saved_value").intValue();
|
|
79 DERIVED_OOP_VALUE = db.lookupIntConstant("OopMapValue::derived_oop_value").intValue();
|
|
80 }
|
|
81
|
|
82 public static abstract class OopTypes {
|
|
83 public static final OopTypes UNUSED_VALUE = new OopTypes() { int getValue() { return OopMapValue.UNUSED_VALUE; }};
|
|
84 public static final OopTypes OOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.OOP_VALUE; }};
|
|
85 public static final OopTypes VALUE_VALUE = new OopTypes() { int getValue() { return OopMapValue.VALUE_VALUE; }};
|
|
86 public static final OopTypes DEAD_VALUE = new OopTypes() { int getValue() { return OopMapValue.DEAD_VALUE; }};
|
|
87 public static final OopTypes CALLEE_SAVED_VALUE = new OopTypes() { int getValue() { return OopMapValue.CALLEE_SAVED_VALUE; }};
|
|
88 public static final OopTypes DERIVED_OOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.DERIVED_OOP_VALUE; }};
|
|
89
|
|
90 abstract int getValue();
|
|
91 protected OopTypes() {}
|
|
92 }
|
|
93
|
|
94 public OopMapValue() { setValue((short) 0); setContentReg(new VMReg(0)); }
|
|
95 public OopMapValue(VMReg reg, OopTypes t) { setReg(reg); setType(t); }
|
|
96 public OopMapValue(VMReg reg, OopTypes t, VMReg reg2) { setReg(reg); setType(t); setContentReg(reg2); }
|
|
97 public OopMapValue(CompressedReadStream stream) { readFrom(stream); }
|
|
98
|
|
99 public void readFrom(CompressedReadStream stream) {
|
|
100 setValue((short) stream.readInt());
|
|
101 if (isCalleeSaved() || isDerivedOop()) {
|
|
102 setContentReg(new VMReg(stream.readInt()));
|
|
103 }
|
|
104 }
|
|
105
|
|
106 // Querying
|
|
107 public boolean isOop() { return (getValue() & TYPE_MASK_IN_PLACE) == OOP_VALUE; }
|
|
108 public boolean isValue() { return (getValue() & TYPE_MASK_IN_PLACE) == VALUE_VALUE; }
|
|
109 public boolean isDead() { return (getValue() & TYPE_MASK_IN_PLACE) == DEAD_VALUE; }
|
|
110 public boolean isCalleeSaved() { return (getValue() & TYPE_MASK_IN_PLACE) == CALLEE_SAVED_VALUE; }
|
|
111 public boolean isDerivedOop() { return (getValue() & TYPE_MASK_IN_PLACE) == DERIVED_OOP_VALUE; }
|
|
112
|
|
113 public VMReg getReg() { return new VMReg((getValue() & REGISTER_MASK_IN_PLACE) >> REGISTER_SHIFT); }
|
|
114 public void setReg(VMReg r) { setValue((short) (r.getValue() << REGISTER_SHIFT | (getValue() & TYPE_MASK_IN_PLACE))); }
|
|
115
|
|
116 public OopTypes getType() {
|
|
117 int which = (getValue() & TYPE_MASK_IN_PLACE);
|
|
118 if (which == UNUSED_VALUE) return OopTypes.UNUSED_VALUE;
|
|
119 else if (which == OOP_VALUE) return OopTypes.OOP_VALUE;
|
|
120 else if (which == VALUE_VALUE) return OopTypes.VALUE_VALUE;
|
|
121 else if (which == DEAD_VALUE) return OopTypes.DEAD_VALUE;
|
|
122 else if (which == CALLEE_SAVED_VALUE) return OopTypes.CALLEE_SAVED_VALUE;
|
|
123 else if (which == DERIVED_OOP_VALUE) return OopTypes.DERIVED_OOP_VALUE;
|
|
124 else throw new InternalError("unknown which " + which + " (TYPE_MASK_IN_PLACE = " + TYPE_MASK_IN_PLACE + ")");
|
|
125 }
|
|
126 public void setType(OopTypes t) { setValue((short) ((getValue() & REGISTER_MASK_IN_PLACE) | t.getValue())); }
|
|
127
|
|
128 public VMReg getContentReg() { return new VMReg(contentReg); }
|
|
129 public void setContentReg(VMReg r) { contentReg = (short) r.getValue(); }
|
|
130
|
|
131 /** Physical location queries */
|
|
132 public boolean isRegisterLoc() { return (getReg().lessThan(VM.getVM().getVMRegImplInfo().getStack0())); }
|
|
133 public boolean isStackLoc() { return (getReg().greaterThanOrEqual(VM.getVM().getVMRegImplInfo().getStack0())); }
|
|
134
|
|
135 /** Returns offset from sp. */
|
|
136 public int getStackOffset() {
|
|
137 if (Assert.ASSERTS_ENABLED) {
|
|
138 Assert.that(isStackLoc(), "must be stack location");
|
|
139 }
|
|
140 return getReg().minus(VM.getVM().getVMRegImplInfo().getStack0());
|
|
141 }
|
|
142
|
|
143 //--------------------------------------------------------------------------------
|
|
144 // Internals only below this point
|
|
145 //
|
|
146
|
|
147 private void setValue(short value) {
|
|
148 this.value = value;
|
|
149 }
|
|
150
|
|
151 private int getValue() {
|
|
152 return value;
|
|
153 }
|
|
154 }
|