23 */
24
25 package sun.jvm.hotspot.oops;
26
27 import java.util.*;
28
29 import sun.jvm.hotspot.debugger.*;
30 import sun.jvm.hotspot.memory.*;
31 import sun.jvm.hotspot.runtime.*;
32 import sun.jvm.hotspot.types.TypeDataBase;
33 import sun.jvm.hotspot.utilities.*;
34 import sun.jvm.hotspot.jdi.JVMTIThreadState;
35
36 /** A utility class encapsulating useful oop operations */
37
38 public class OopUtilities implements /* imports */ JVMTIThreadState {
39
40 // FIXME: access should be synchronized and cleared when VM is
41 // resumed
42 // String fields
43 private static IntField offsetField;
44 private static IntField countField;
45 private static OopField valueField;
46 // ThreadGroup fields
47 private static OopField threadGroupParentField;
48 private static OopField threadGroupNameField;
49 private static IntField threadGroupNThreadsField;
50 private static OopField threadGroupThreadsField;
51 private static IntField threadGroupNGroupsField;
52 private static OopField threadGroupGroupsField;
53 // Thread fields
54 private static OopField threadNameField;
55 private static OopField threadGroupField;
56 private static LongField threadEETopField;
57 //tid field is new since 1.5
58 private static LongField threadTIDField;
59 // threadStatus field is new since 1.5
60 private static IntField threadStatusField;
61 // parkBlocker field is new since 1.6
62 private static OopField threadParkBlockerField;
63
64 // possible values of java_lang_Thread::ThreadStatus
79 // java.util.concurrent.locks.AbstractOwnableSynchronizer fields
80 private static OopField absOwnSyncOwnerThreadField;
81
82 static {
83 VM.registerVMInitializedObserver(new Observer() {
84 public void update(Observable o, Object data) {
85 initialize(VM.getVM().getTypeDataBase());
86 }
87 });
88 }
89
90 private static synchronized void initialize(TypeDataBase db) {
91 // FIXME: don't need this observer; however, do need a VM resumed
92 // and suspended observer to refetch fields
93 }
94
95 public static String charArrayToString(TypeArray charArray) {
96 if (charArray == null) {
97 return null;
98 }
99 return charArrayToString(charArray, 0, (int) charArray.getLength());
100 }
101
102 public static String charArrayToString(TypeArray charArray, int offset, int length) {
103 if (charArray == null) {
104 return null;
105 }
106 final int limit = offset + length;
107 if (Assert.ASSERTS_ENABLED) {
108 Assert.that(offset >= 0 && limit <= charArray.getLength(), "out of bounds");
109 }
110 StringBuffer buf = new StringBuffer(length);
111 for (int i = offset; i < limit; i++) {
112 buf.append(charArray.getCharAt(i));
113 }
114 return buf.toString();
115 }
116
117 public static String escapeString(String s) {
118 StringBuilder sb = null;
119 for (int index = 0; index < s.length(); index++) {
120 char value = s.charAt(index);
121 if (value >= 32 && value < 127 || value == '\'' || value == '\\') {
122 if (sb != null) {
123 sb.append(value);
124 }
125 } else {
126 if (sb == null) {
127 sb = new StringBuilder(s.length() * 2);
128 sb.append(s, 0, index);
129 }
130 sb.append("\\u");
131 if (value < 0x10) sb.append("000");
132 else if (value < 0x100) sb.append("00");
133 else if (value < 0x1000) sb.append("0");
134 sb.append(Integer.toHexString(value));
135 }
136 }
137 if (sb != null) {
138 return sb.toString();
139 }
140 return s;
141 }
142
143 public static String stringOopToString(Oop stringOop) {
144 if (offsetField == null) {
145 InstanceKlass k = (InstanceKlass) stringOop.getKlass();
146 offsetField = (IntField) k.findField("offset", "I"); // optional
147 countField = (IntField) k.findField("count", "I"); // optional
148 valueField = (OopField) k.findField("value", "[C");
149 if (Assert.ASSERTS_ENABLED) {
150 Assert.that(valueField != null, "Field \'value\' of java.lang.String not found");
151 }
152 }
153 if (offsetField != null && countField != null) {
154 return charArrayToString((TypeArray) valueField.getValue(stringOop),
155 offsetField.getValue(stringOop),
156 countField.getValue(stringOop));
157 }
158 return charArrayToString((TypeArray) valueField.getValue(stringOop));
159 }
160
161 public static String stringOopToEscapedString(Oop stringOop) {
162 return escapeString(stringOopToString(stringOop));
163 }
164
165 private static void initThreadGroupFields() {
166 if (threadGroupParentField == null) {
167 SystemDictionary sysDict = VM.getVM().getSystemDictionary();
168 InstanceKlass k = sysDict.getThreadGroupKlass();
169 threadGroupParentField = (OopField) k.findField("parent", "Ljava/lang/ThreadGroup;");
170 threadGroupNameField = (OopField) k.findField("name", "Ljava/lang/String;");
171 threadGroupNThreadsField = (IntField) k.findField("nthreads", "I");
172 threadGroupThreadsField = (OopField) k.findField("threads", "[Ljava/lang/Thread;");
173 threadGroupNGroupsField = (IntField) k.findField("ngroups", "I");
174 threadGroupGroupsField = (OopField) k.findField("groups", "[Ljava/lang/ThreadGroup;");
175 if (Assert.ASSERTS_ENABLED) {
176 Assert.that(threadGroupParentField != null &&
177 threadGroupNameField != null &&
178 threadGroupNThreadsField != null &&
|
23 */
24
25 package sun.jvm.hotspot.oops;
26
27 import java.util.*;
28
29 import sun.jvm.hotspot.debugger.*;
30 import sun.jvm.hotspot.memory.*;
31 import sun.jvm.hotspot.runtime.*;
32 import sun.jvm.hotspot.types.TypeDataBase;
33 import sun.jvm.hotspot.utilities.*;
34 import sun.jvm.hotspot.jdi.JVMTIThreadState;
35
36 /** A utility class encapsulating useful oop operations */
37
38 public class OopUtilities implements /* imports */ JVMTIThreadState {
39
40 // FIXME: access should be synchronized and cleared when VM is
41 // resumed
42 // String fields
43 private static ByteField coderField;
44 private static OopField valueField;
45 // ThreadGroup fields
46 private static OopField threadGroupParentField;
47 private static OopField threadGroupNameField;
48 private static IntField threadGroupNThreadsField;
49 private static OopField threadGroupThreadsField;
50 private static IntField threadGroupNGroupsField;
51 private static OopField threadGroupGroupsField;
52 // Thread fields
53 private static OopField threadNameField;
54 private static OopField threadGroupField;
55 private static LongField threadEETopField;
56 //tid field is new since 1.5
57 private static LongField threadTIDField;
58 // threadStatus field is new since 1.5
59 private static IntField threadStatusField;
60 // parkBlocker field is new since 1.6
61 private static OopField threadParkBlockerField;
62
63 // possible values of java_lang_Thread::ThreadStatus
78 // java.util.concurrent.locks.AbstractOwnableSynchronizer fields
79 private static OopField absOwnSyncOwnerThreadField;
80
81 static {
82 VM.registerVMInitializedObserver(new Observer() {
83 public void update(Observable o, Object data) {
84 initialize(VM.getVM().getTypeDataBase());
85 }
86 });
87 }
88
89 private static synchronized void initialize(TypeDataBase db) {
90 // FIXME: don't need this observer; however, do need a VM resumed
91 // and suspended observer to refetch fields
92 }
93
94 public static String charArrayToString(TypeArray charArray) {
95 if (charArray == null) {
96 return null;
97 }
98 int length = (int)charArray.getLength();
99 StringBuffer buf = new StringBuffer(length);
100 for (int i = 0; i < length; i++) {
101 buf.append(charArray.getCharAt(i));
102 }
103 return buf.toString();
104 }
105
106 public static String byteArrayToString(TypeArray byteArray, byte coder) {
107 if (byteArray == null) {
108 return null;
109 }
110 int length = (int)byteArray.getLength() >> coder;
111 StringBuffer buf = new StringBuffer(length);
112 if (coder == 0) {
113 // Latin1 encoded
114 for (int i = 0; i < length; i++) {
115 buf.append((char)(byteArray.getByteAt(i) & 0xff));
116 }
117 } else {
118 // UTF16 encoded
119 for (int i = 0; i < length; i++) {
120 buf.append(byteArray.getCharAt(i));
121 }
122 }
123 return buf.toString();
124 }
125
126 public static String escapeString(String s) {
127 StringBuilder sb = null;
128 for (int index = 0; index < s.length(); index++) {
129 char value = s.charAt(index);
130 if (value >= 32 && value < 127 || value == '\'' || value == '\\') {
131 if (sb != null) {
132 sb.append(value);
133 }
134 } else {
135 if (sb == null) {
136 sb = new StringBuilder(s.length() * 2);
137 sb.append(s, 0, index);
138 }
139 sb.append("\\u");
140 if (value < 0x10) sb.append("000");
141 else if (value < 0x100) sb.append("00");
142 else if (value < 0x1000) sb.append("0");
143 sb.append(Integer.toHexString(value));
144 }
145 }
146 if (sb != null) {
147 return sb.toString();
148 }
149 return s;
150 }
151
152 public static String stringOopToString(Oop stringOop) {
153 InstanceKlass k = (InstanceKlass) stringOop.getKlass();
154 coderField = (ByteField) k.findField("coder", "B");
155 valueField = (OopField) k.findField("value", "[B");
156 if (Assert.ASSERTS_ENABLED) {
157 Assert.that(coderField != null, "Field \'coder\' of java.lang.String not found");
158 Assert.that(valueField != null, "Field \'value\' of java.lang.String not found");
159 }
160 return byteArrayToString((TypeArray) valueField.getValue(stringOop), coderField.getValue(stringOop));
161 }
162
163 public static String stringOopToEscapedString(Oop stringOop) {
164 return escapeString(stringOopToString(stringOop));
165 }
166
167 private static void initThreadGroupFields() {
168 if (threadGroupParentField == null) {
169 SystemDictionary sysDict = VM.getVM().getSystemDictionary();
170 InstanceKlass k = sysDict.getThreadGroupKlass();
171 threadGroupParentField = (OopField) k.findField("parent", "Ljava/lang/ThreadGroup;");
172 threadGroupNameField = (OopField) k.findField("name", "Ljava/lang/String;");
173 threadGroupNThreadsField = (IntField) k.findField("nthreads", "I");
174 threadGroupThreadsField = (OopField) k.findField("threads", "[Ljava/lang/Thread;");
175 threadGroupNGroupsField = (IntField) k.findField("ngroups", "I");
176 threadGroupGroupsField = (OopField) k.findField("groups", "[Ljava/lang/ThreadGroup;");
177 if (Assert.ASSERTS_ENABLED) {
178 Assert.that(threadGroupParentField != null &&
179 threadGroupNameField != null &&
180 threadGroupNThreadsField != null &&
|