blob: 2f39a9e93bfe178b4a9bd6fdb16edb82e425d60b [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-2005 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26#include "util.h"
27#include "ObjectReferenceImpl.h"
28#include "commonRef.h"
29#include "inStream.h"
30#include "outStream.h"
31
32static jboolean
33referenceType(PacketInputStream *in, PacketOutputStream *out)
34{
35 JNIEnv *env;
36 jobject object;
37
38 env = getEnv();
39
40 object = inStream_readObjectRef(env, in);
41 if (inStream_error(in)) {
42 return JNI_TRUE;
43 }
44
45 WITH_LOCAL_REFS(env, 1) {
46
47 jbyte tag;
48 jclass clazz;
49
50 clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
51 tag = referenceTypeTag(clazz);
52
53 (void)outStream_writeByte(out, tag);
54 (void)outStream_writeObjectRef(env, out, clazz);
55
56 } END_WITH_LOCAL_REFS(env);
57
58 return JNI_TRUE;
59}
60
61static jboolean
62getValues(PacketInputStream *in, PacketOutputStream *out)
63{
64 sharedGetFieldValues(in, out, JNI_FALSE);
65 return JNI_TRUE;
66}
67
68
69static jvmtiError
70readFieldValue(JNIEnv *env, PacketInputStream *in, jclass clazz,
71 jobject object, jfieldID field, char *signature)
72{
73 jvalue value;
74 jvmtiError error;
75
76 switch (signature[0]) {
77 case JDWP_TAG(ARRAY):
78 case JDWP_TAG(OBJECT):
79 value.l = inStream_readObjectRef(env, in);
80 JNI_FUNC_PTR(env,SetObjectField)(env, object, field, value.l);
81 break;
82
83 case JDWP_TAG(BYTE):
84 value.b = inStream_readByte(in);
85 JNI_FUNC_PTR(env,SetByteField)(env, object, field, value.b);
86 break;
87
88 case JDWP_TAG(CHAR):
89 value.c = inStream_readChar(in);
90 JNI_FUNC_PTR(env,SetCharField)(env, object, field, value.c);
91 break;
92
93 case JDWP_TAG(FLOAT):
94 value.f = inStream_readFloat(in);
95 JNI_FUNC_PTR(env,SetFloatField)(env, object, field, value.f);
96 break;
97
98 case JDWP_TAG(DOUBLE):
99 value.d = inStream_readDouble(in);
100 JNI_FUNC_PTR(env,SetDoubleField)(env, object, field, value.d);
101 break;
102
103 case JDWP_TAG(INT):
104 value.i = inStream_readInt(in);
105 JNI_FUNC_PTR(env,SetIntField)(env, object, field, value.i);
106 break;
107
108 case JDWP_TAG(LONG):
109 value.j = inStream_readLong(in);
110 JNI_FUNC_PTR(env,SetLongField)(env, object, field, value.j);
111 break;
112
113 case JDWP_TAG(SHORT):
114 value.s = inStream_readShort(in);
115 JNI_FUNC_PTR(env,SetShortField)(env, object, field, value.s);
116 break;
117
118 case JDWP_TAG(BOOLEAN):
119 value.z = inStream_readBoolean(in);
120 JNI_FUNC_PTR(env,SetBooleanField)(env, object, field, value.z);
121 break;
122 }
123
124 error = JVMTI_ERROR_NONE;
125 if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
126 error = AGENT_ERROR_JNI_EXCEPTION;
127 }
128
129 return error;
130}
131
132static jboolean
133setValues(PacketInputStream *in, PacketOutputStream *out)
134{
135 JNIEnv *env;
136 jint count;
137 jvmtiError error;
138 jobject object;
139
140 env = getEnv();
141
142 object = inStream_readObjectRef(env, in);
143 if (inStream_error(in)) {
144 return JNI_TRUE;
145 }
146 count = inStream_readInt(in);
147 if (inStream_error(in)) {
148 return JNI_TRUE;
149 }
150
151 error = JVMTI_ERROR_NONE;
152
153 WITH_LOCAL_REFS(env, count + 1) {
154
155 jclass clazz;
156
157 clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
158
159 if (clazz != NULL ) {
160
161 int i;
162
163 for (i = 0; (i < count) && !inStream_error(in); i++) {
164
165 jfieldID field;
166 char *signature = NULL;
167
168 field = inStream_readFieldID(in);
169 if (inStream_error(in))
170 break;
171
172 error = fieldSignature(clazz, field, NULL, &signature, NULL);
173 if (error != JVMTI_ERROR_NONE) {
174 break;
175 }
176
177 error = readFieldValue(env, in, clazz, object, field, signature);
178 jvmtiDeallocate(signature);
179
180 if (error != JVMTI_ERROR_NONE) {
181 break;
182 }
183 }
184 }
185
186 if (error != JVMTI_ERROR_NONE) {
187 outStream_setError(out, map2jdwpError(error));
188 }
189
190 } END_WITH_LOCAL_REFS(env);
191
192 return JNI_TRUE;
193}
194
195static jboolean
196monitorInfo(PacketInputStream *in, PacketOutputStream *out)
197{
198 JNIEnv *env;
199 jobject object;
200
201 env = getEnv();
202
203 object = inStream_readObjectRef(env, in);
204 if (inStream_error(in)) {
205 return JNI_TRUE;
206 }
207
208 WITH_LOCAL_REFS(env, 1) {
209
210 jvmtiError error;
211 jvmtiMonitorUsage info;
212
213 (void)memset(&info, 0, sizeof(info));
214 error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectMonitorUsage)
215 (gdata->jvmti, object, &info);
216 if (error != JVMTI_ERROR_NONE) {
217 outStream_setError(out, map2jdwpError(error));
218 } else {
219 int i;
220 (void)outStream_writeObjectRef(env, out, info.owner);
221 (void)outStream_writeInt(out, info.entry_count);
222 (void)outStream_writeInt(out, info.waiter_count);
223 for (i = 0; i < info.waiter_count; i++) {
224 (void)outStream_writeObjectRef(env, out, info.waiters[i]);
225 }
226 }
227
228 if (info.waiters != NULL )
229 jvmtiDeallocate(info.waiters);
230
231 } END_WITH_LOCAL_REFS(env);
232
233 return JNI_TRUE;
234}
235
236static jboolean
237invokeInstance(PacketInputStream *in, PacketOutputStream *out)
238{
239 return sharedInvoke(in, out);
240}
241
242static jboolean
243disableCollection(PacketInputStream *in, PacketOutputStream *out)
244{
245 jlong id;
246 jvmtiError error;
247
248 id = inStream_readObjectID(in);
249 if (inStream_error(in)) {
250 return JNI_TRUE;
251 }
252
253 error = commonRef_pin(id);
254 if (error != JVMTI_ERROR_NONE) {
255 outStream_setError(out, map2jdwpError(error));
256 }
257
258 return JNI_TRUE;
259}
260
261static jboolean
262enableCollection(PacketInputStream *in, PacketOutputStream *out)
263{
264 jvmtiError error;
265 jlong id;
266
267 id = inStream_readObjectID(in);
268 if (inStream_error(in)) {
269 return JNI_TRUE;
270 }
271
272 error = commonRef_unpin(id);
273 if (error != JVMTI_ERROR_NONE) {
274 outStream_setError(out, map2jdwpError(error));
275 }
276
277 return JNI_TRUE;
278}
279
280static jboolean
281isCollected(PacketInputStream *in, PacketOutputStream *out)
282{
283 jobject ref;
284 jlong id;
285 JNIEnv *env;
286
287 env = getEnv();
288 id = inStream_readObjectID(in);
289 if (inStream_error(in)) {
290 return JNI_TRUE;
291 }
292
293 if (id == NULL_OBJECT_ID) {
294 outStream_setError(out, JDWP_ERROR(INVALID_OBJECT));
295 return JNI_TRUE;
296 }
297
298 ref = commonRef_idToRef(env, id);
299 (void)outStream_writeBoolean(out, (jboolean)(ref == NULL));
300
301 commonRef_idToRef_delete(env, ref);
302
303 return JNI_TRUE;
304}
305
306
307static jboolean
308referringObjects(PacketInputStream *in, PacketOutputStream *out)
309{
310 jobject object;
311 jint maxReferrers;
312 JNIEnv *env;
313
314 env = getEnv();
315
316 if (gdata->vmDead) {
317 outStream_setError(out, JDWP_ERROR(VM_DEAD));
318 return JNI_TRUE;
319 }
320
321 object = inStream_readObjectRef(env,in);
322 if (inStream_error(in)) {
323 return JNI_TRUE;
324 }
325
326 maxReferrers = inStream_readInt(in);
327 if (inStream_error(in)) {
328 return JNI_TRUE;
329 }
330
331 WITH_LOCAL_REFS(env, 1) {
332 jvmtiError error;
333 ObjectBatch referrerBatch;
334
335 error = objectReferrers(object, &referrerBatch, maxReferrers);
336 if (error != JVMTI_ERROR_NONE) {
337 outStream_setError(out, map2jdwpError(error));
338 } else {
339 int kk;
340
341 (void)outStream_writeInt(out, referrerBatch.count);
342 for (kk = 0; kk < referrerBatch.count; kk++) {
343 jobject ref;
344
345 ref = referrerBatch.objects[kk];
346 (void)outStream_writeByte(out, specificTypeKey(env, ref));
347 (void)outStream_writeObjectRef(env, out, ref);
348 }
349 jvmtiDeallocate(referrerBatch.objects);
350 }
351 } END_WITH_LOCAL_REFS(env);
352 return JNI_TRUE;
353}
354
355void *ObjectReference_Cmds[] = { (void *)10
356 ,(void *)referenceType
357 ,(void *)getValues
358 ,(void *)setValues
359 ,(void *)NULL /* no longer used */
360 ,(void *)monitorInfo
361 ,(void *)invokeInstance
362 ,(void *)disableCollection
363 ,(void *)enableCollection
364 ,(void *)isCollected
365 ,(void *)referringObjects
366 };