source: trunk/openjdk/jdk/src/share/back/StackFrameImpl.c

Last change on this file was 278, checked in by dmik, 14 years ago

trunk: Merged in openjdk6 b22 from branches/vendor/oracle.

File size: 13.6 KB
Line 
1/*
2 * Copyright (c) 1998, 2005, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include "util.h"
27#include "StackFrameImpl.h"
28#include "inStream.h"
29#include "outStream.h"
30#include "threadControl.h"
31#include "FrameID.h"
32
33static jdwpError
34validateThreadFrame(jthread thread, FrameID frame)
35{
36 jvmtiError error;
37 jdwpError serror;
38 jint count;
39 error = threadControl_suspendCount(thread, &count);
40 if ( error == JVMTI_ERROR_NONE ) {
41 if ( count > 0 ) {
42 serror = validateFrameID(thread, frame);
43 } else {
44 serror = JDWP_ERROR(THREAD_NOT_SUSPENDED);
45 }
46 } else {
47 serror = map2jdwpError(error);
48 }
49 return serror;
50}
51
52static jdwpError
53writeVariableValue(JNIEnv *env, PacketOutputStream *out, jthread thread,
54 FrameNumber fnum, jint slot, jbyte typeKey)
55{
56 jvmtiError error;
57 jvalue value;
58
59 if (isObjectTag(typeKey)) {
60
61 WITH_LOCAL_REFS(env, 1) {
62
63 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalObject)
64 (gdata->jvmti, thread, fnum, slot, &value.l);
65
66 if (error != JVMTI_ERROR_NONE) {
67 outStream_setError(out, map2jdwpError(error));
68 } else {
69 (void)outStream_writeByte(out, specificTypeKey(env, value.l));
70 (void)outStream_writeObjectRef(env, out, value.l);
71 }
72
73 } END_WITH_LOCAL_REFS(env);
74
75 } else {
76 /*
77 * For primitive types, the type key is bounced back as is.
78 */
79 (void)outStream_writeByte(out, typeKey);
80 switch (typeKey) {
81 case JDWP_TAG(BYTE): {
82 jint intValue;
83 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalInt)
84 (gdata->jvmti, thread, fnum, slot, &intValue);
85 (void)outStream_writeByte(out, (jbyte)intValue);
86 break;
87 }
88
89 case JDWP_TAG(CHAR): {
90 jint intValue;
91 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalInt)
92 (gdata->jvmti, thread, fnum, slot, &intValue);
93 (void)outStream_writeChar(out, (jchar)intValue);
94 break;
95 }
96
97 case JDWP_TAG(FLOAT):
98 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalFloat)
99 (gdata->jvmti, thread, fnum, slot, &value.f);
100 (void)outStream_writeFloat(out, value.f);
101 break;
102
103 case JDWP_TAG(DOUBLE):
104 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalDouble)
105 (gdata->jvmti, thread, fnum, slot, &value.d);
106 (void)outStream_writeDouble(out, value.d);
107 break;
108
109 case JDWP_TAG(INT):
110 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalInt)
111 (gdata->jvmti, thread, fnum, slot, &value.i);
112 (void)outStream_writeInt(out, value.i);
113 break;
114
115 case JDWP_TAG(LONG):
116 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalLong)
117 (gdata->jvmti, thread, fnum, slot, &value.j);
118 (void)outStream_writeLong(out, value.j);
119 break;
120
121 case JDWP_TAG(SHORT): {
122 jint intValue;
123 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalInt)
124 (gdata->jvmti, thread, fnum, slot, &intValue);
125 (void)outStream_writeShort(out, (jshort)intValue);
126 break;
127 }
128
129 case JDWP_TAG(BOOLEAN):{
130 jint intValue;
131 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalInt)
132 (gdata->jvmti, thread, fnum, slot, &intValue);
133 (void)outStream_writeBoolean(out, (jboolean)intValue);
134 break;
135 }
136
137 default:
138 return JDWP_ERROR(INVALID_TAG);
139 }
140 }
141
142 return map2jdwpError(error);
143}
144
145static jdwpError
146readVariableValue(JNIEnv *env, PacketInputStream *in, jthread thread,
147 FrameNumber fnum, jint slot, jbyte typeKey)
148{
149 jvmtiError error;
150 jvalue value;
151
152 if (isObjectTag(typeKey)) {
153
154 value.l = inStream_readObjectRef(env, in);
155
156 error = JVMTI_FUNC_PTR(gdata->jvmti,SetLocalObject)
157 (gdata->jvmti, thread, fnum, slot, value.l);
158
159 } else {
160 switch (typeKey) {
161 case JDWP_TAG(BYTE):
162 value.b = inStream_readByte(in);
163 error = JVMTI_FUNC_PTR(gdata->jvmti,SetLocalInt)
164 (gdata->jvmti, thread, fnum, slot, value.b);
165 break;
166
167 case JDWP_TAG(CHAR):
168 value.c = inStream_readChar(in);
169 error = JVMTI_FUNC_PTR(gdata->jvmti,SetLocalInt)
170 (gdata->jvmti, thread, fnum, slot, value.c);
171 break;
172
173 case JDWP_TAG(FLOAT):
174 value.f = inStream_readFloat(in);
175 error = JVMTI_FUNC_PTR(gdata->jvmti,SetLocalFloat)
176 (gdata->jvmti, thread, fnum, slot, value.f);
177 break;
178
179 case JDWP_TAG(DOUBLE):
180 value.d = inStream_readDouble(in);
181 error = JVMTI_FUNC_PTR(gdata->jvmti,SetLocalDouble)
182 (gdata->jvmti, thread, fnum, slot, value.d);
183 break;
184
185 case JDWP_TAG(INT):
186 value.i = inStream_readInt(in);
187 error = JVMTI_FUNC_PTR(gdata->jvmti,SetLocalInt)
188 (gdata->jvmti, thread, fnum, slot, value.i);
189 break;
190
191 case JDWP_TAG(LONG):
192 value.j = inStream_readLong(in);
193 error = JVMTI_FUNC_PTR(gdata->jvmti,SetLocalLong)
194 (gdata->jvmti, thread, fnum, slot, value.j);
195 break;
196
197 case JDWP_TAG(SHORT):
198 value.s = inStream_readShort(in);
199 error = JVMTI_FUNC_PTR(gdata->jvmti,SetLocalInt)
200 (gdata->jvmti, thread, fnum, slot, value.s);
201 break;
202
203 case JDWP_TAG(BOOLEAN):
204 value.z = inStream_readBoolean(in);
205 error = JVMTI_FUNC_PTR(gdata->jvmti,SetLocalInt)
206 (gdata->jvmti, thread, fnum, slot, value.z);
207 break;
208
209 default:
210 return JDWP_ERROR(INVALID_TAG);
211 }
212 }
213
214 return map2jdwpError(error);
215}
216
217static jboolean
218getValues(PacketInputStream *in, PacketOutputStream *out)
219{
220 JNIEnv *env;
221 int i;
222 jdwpError serror;
223 jthread thread;
224 FrameID frame;
225 jint variableCount;
226
227 env = getEnv();
228
229 thread = inStream_readThreadRef(env, in);
230 if (inStream_error(in)) {
231 return JNI_TRUE;
232 }
233 frame = inStream_readFrameID(in);
234 if (inStream_error(in)) {
235 return JNI_TRUE;
236 }
237 variableCount = inStream_readInt(in);
238 if (inStream_error(in)) {
239 return JNI_TRUE;
240 }
241
242 /*
243 * Validate the frame id
244 */
245 serror = validateThreadFrame(thread, frame);
246 if (serror != JDWP_ERROR(NONE)) {
247 outStream_setError(out, serror);
248 return JNI_TRUE;
249 }
250
251 (void)outStream_writeInt(out, variableCount);
252 for (i = 0; (i < variableCount) && !outStream_error(out); i++) {
253 jint slot;
254 jbyte typeKey;
255 FrameNumber fnum;
256
257 slot = inStream_readInt(in);
258 if (inStream_error(in))
259 break;
260 typeKey = inStream_readByte(in);
261 if (inStream_error(in))
262 break;
263
264 fnum = getFrameNumber(frame);
265 serror = writeVariableValue(env, out, thread, fnum, slot, typeKey);
266 if (serror != JDWP_ERROR(NONE)) {
267 outStream_setError(out, serror);
268 break;
269 }
270 }
271
272 return JNI_TRUE;
273}
274
275static jboolean
276setValues(PacketInputStream *in, PacketOutputStream *out)
277{
278 JNIEnv *env;
279 jint i;
280 jdwpError serror;
281 jthread thread;
282 FrameID frame;
283 jint variableCount;
284
285 env = getEnv();
286
287 thread = inStream_readThreadRef(env, in);
288 if (inStream_error(in)) {
289 return JNI_TRUE;
290 }
291 frame = inStream_readFrameID(in);
292 if (inStream_error(in)) {
293 return JNI_TRUE;
294 }
295 variableCount = inStream_readInt(in);
296 if (inStream_error(in)) {
297 return JNI_TRUE;
298 }
299
300 /*
301 * Validate the frame id
302 */
303 serror = validateThreadFrame(thread, frame);
304 if (serror != JDWP_ERROR(NONE)) {
305 outStream_setError(out, serror);
306 return JNI_TRUE;
307 }
308
309 for (i = 0; (i < variableCount) && !inStream_error(in); i++) {
310
311 jint slot;
312 jbyte typeKey;
313 FrameNumber fnum;
314
315 slot = inStream_readInt(in);
316 if (inStream_error(in)) {
317 return JNI_TRUE;
318 }
319 typeKey = inStream_readByte(in);
320 if (inStream_error(in)) {
321 return JNI_TRUE;
322 }
323
324 fnum = getFrameNumber(frame);
325 serror = readVariableValue(env, in, thread, fnum, slot, typeKey);
326 if (serror != JDWP_ERROR(NONE))
327 break;
328 }
329
330 if (serror != JDWP_ERROR(NONE)) {
331 outStream_setError(out, serror);
332 }
333
334 return JNI_TRUE;
335}
336
337static jboolean
338thisObject(PacketInputStream *in, PacketOutputStream *out)
339{
340 JNIEnv *env;
341 jdwpError serror;
342 jthread thread;
343 FrameID frame;
344
345 env = getEnv();
346
347 thread = inStream_readThreadRef(env, in);
348 if (inStream_error(in)) {
349 return JNI_TRUE;
350 }
351
352 frame = inStream_readFrameID(in);
353 if (inStream_error(in)) {
354 return JNI_TRUE;
355 }
356
357 /*
358 * Validate the frame id
359 */
360 serror = validateThreadFrame(thread, frame);
361 if (serror != JDWP_ERROR(NONE)) {
362 outStream_setError(out, serror);
363 return JNI_TRUE;
364 }
365
366 WITH_LOCAL_REFS(env, 2) {
367
368 jvmtiError error;
369 jmethodID method;
370 jlocation location;
371 FrameNumber fnum;
372
373 /*
374 * Find out if the given frame is for a static or native method.
375 */
376 fnum = getFrameNumber(frame);
377 error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
378 (gdata->jvmti, thread, fnum, &method, &location);
379 if (error == JVMTI_ERROR_NONE) {
380
381 jint modifiers;
382
383 error = methodModifiers(method, &modifiers);
384 if (error == JVMTI_ERROR_NONE) {
385
386 jobject this_object;
387
388 /*
389 * Return null for static or native methods; otherwise, the JVM
390 * spec guarantees that "this" is in slot 0
391 */
392 if (modifiers & (MOD_STATIC | MOD_NATIVE)) {
393 this_object = NULL;
394 (void)outStream_writeByte(out, specificTypeKey(env, this_object));
395 (void)outStream_writeObjectRef(env, out, this_object);
396 } else {
397 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalObject)
398 (gdata->jvmti, thread, fnum, 0, &this_object);
399 if (error == JVMTI_ERROR_NONE) {
400 (void)outStream_writeByte(out, specificTypeKey(env, this_object));
401 (void)outStream_writeObjectRef(env, out, this_object);
402 }
403 }
404
405 }
406 }
407 serror = map2jdwpError(error);
408
409 } END_WITH_LOCAL_REFS(env);
410
411 if (serror != JDWP_ERROR(NONE))
412 outStream_setError(out, serror);
413
414 return JNI_TRUE;
415}
416
417static jboolean
418popFrames(PacketInputStream *in, PacketOutputStream *out)
419{
420 jvmtiError error;
421 jdwpError serror;
422 jthread thread;
423 FrameID frame;
424 FrameNumber fnum;
425
426 thread = inStream_readThreadRef(getEnv(), in);
427 if (inStream_error(in)) {
428 return JNI_TRUE;
429 }
430
431 frame = inStream_readFrameID(in);
432 if (inStream_error(in)) {
433 return JNI_TRUE;
434 }
435
436 /*
437 * Validate the frame id
438 */
439 serror = validateThreadFrame(thread, frame);
440 if (serror != JDWP_ERROR(NONE)) {
441 outStream_setError(out, serror);
442 return JNI_TRUE;
443 }
444
445 if (threadControl_isDebugThread(thread)) {
446 outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
447 return JNI_TRUE;
448 }
449
450 fnum = getFrameNumber(frame);
451 error = threadControl_popFrames(thread, fnum);
452 if (error != JVMTI_ERROR_NONE) {
453 serror = map2jdwpError(error);
454 outStream_setError(out, serror);
455 }
456 return JNI_TRUE;
457}
458
459void *StackFrame_Cmds[] = { (void *)0x4
460 ,(void *)getValues
461 ,(void *)setValues
462 ,(void *)thisObject
463 ,(void *)popFrames
464};
Note: See TracBrowser for help on using the repository browser.