KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ch > ethz > inf > iks > jvmai > jvmdi > JoinPointContext


1 //
2
// This file is part of the prose package.
3
//
4
// The contents of this file are subject to the Mozilla Public License
5
// Version 1.1 (the "License"); you may not use this file except in
6
// compliance with the License. You may obtain a copy of the License at
7
// http://www.mozilla.org/MPL/
8
//
9
// Software distributed under the License is distributed on an "AS IS" basis,
10
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
// for the specific language governing rights and limitations under the
12
// License.
13
//
14
// The Original Code is prose.
15
//
16
// The Initial Developer of the Original Code is Andrei Popovici. Portions
17
// created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
18
// All Rights Reserved.
19
//
20
// Contributor(s):
21
// $Id: JoinPointContext.java,v 1.1.1.1 2003/07/02 15:30:50 apopovic Exp $
22
// =====================================================================
23
//
24
// (history at end)
25
//
26

27 package ch.ethz.inf.iks.jvmai.jvmdi;
28 import ch.ethz.jvmai.JoinPoint;
29 import java.lang.reflect.Modifier JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31
32 // used packages
33
import java.util.*;
34 import java.io.*;
35
36 /**
37  * Class JoinPointContext encapsulates local variable info. Because various
38  * types of join-points (Field Access, Field Modififcattion, Method Entry, Exit)
39  * have to have access to local variables, this functionality has been
40  * <em>delegated</em> to JoinPointContext (as opposed to being
41  * <em>inherited</em> from some root object.
42  *
43  * @version $Revision: 1.1.1.1 $
44  * @author Andrei Popovici
45  */

46 public
47 class JoinPointContext
48 {
49     private static int UNDEFINED_DEPTH=-1;
50
51     protected Thread JavaDoc thread; // immutable
52
protected JoinPointLocation location; // immutable
53
protected int depth; // mutable
54
protected int height; // mutable
55

56     private int state; // mutable
57
private static int SLOT_THIS_OBJ;
58     private static int STATE_GOT_NOTHING = 0x0;
59     private static int STATE_GOT_ARGS = 0x02;
60     private static int STATE_GOT_THIS = 0x01;
61     private static int STATE_GOT_INFO = 0x04;
62
63     private Object JavaDoc thisObject;
64     private Object JavaDoc[] argValues;
65     private Class JavaDoc[] argTypes;
66     private String JavaDoc[] argNames;
67     private int[] argSlots;
68
69     protected JoinPointContext()
70     {
71     this(Thread.currentThread(),UNDEFINED_DEPTH,0);
72     }
73
74     private JoinPointContext(Thread JavaDoc t, int dpth,int hght)
75     {
76       this.location = new JoinPointLocation();
77       this.depth = dpth;
78       this.height = hght; // fix for JRE 1.4.0, where 'depth' is not correclty computed on jvmdi.
79
this.thread = t;
80       this.state = 0;
81     }
82
83     protected JoinPointContext callerContext()
84     {
85       JoinPointContext newContext = new JoinPointContext(thread,depth-1,height + 1);
86       doGetCallerLocationData(newContext.location,thread,depth-1,height+1);
87       return newContext;
88     }
89
90     protected void invalidate()
91     {
92     state = 0;
93     location.executingMethod = null;
94     }
95
96     protected boolean isValid()
97     {
98     return location.executingMethod == null;
99     }
100
101
102
103
104     protected Object JavaDoc[] getArgs()
105     {
106       if ( (state & STATE_GOT_ARGS) != 0)
107       return argValues;
108
109
110       doGetLocalVariableInfo();
111
112       for (int i = 0; i < argValues.length; i++)
113       argValues[i]=getLocalValue(argTypes[i],argSlots[i]);
114
115       state |= STATE_GOT_ARGS;
116       return argValues;
117
118     }
119
120   protected Object JavaDoc getThis()
121     {
122     if ( (state & STATE_GOT_THIS) != 0)
123         return thisObject;
124
125
126     if ( ( location.executingMethod.getModifiers() & Modifier.STATIC ) != 0)
127         thisObject = null;
128     else
129         thisObject = getLocalValue(java.lang.Object JavaDoc.class,0);
130
131     state |= STATE_GOT_THIS;
132     return thisObject;
133     }
134
135     protected String JavaDoc[] getParameterNames()
136     {
137     doGetLocalVariableInfo();
138     return argNames;
139     }
140
141
142   private Object JavaDoc[][] preAllocatedArgs = new Object JavaDoc[][]{ new Object JavaDoc[0],
143                              new Object JavaDoc[1],
144                              new Object JavaDoc[2],
145                              new Object JavaDoc[3],
146                              new Object JavaDoc[4],
147                              new Object JavaDoc[5]};
148
149
150     private int[][] preAllocatedSlots = new int[][]{ new int[0],
151                               new int[1],
152                               new int[2],
153                               new int[3],
154                               new int[4],
155                               new int[5]};
156
157
158     private String JavaDoc[][] preAllocatedNames = new String JavaDoc[][]{ new String JavaDoc[0],
159                                new String JavaDoc[1],
160                                new String JavaDoc[2],
161                                new String JavaDoc[3],
162                                new String JavaDoc[4],
163                                 new String JavaDoc[5]};
164
165     private void doGetLocalVariableInfo()
166     {
167     if ((state & STATE_GOT_INFO) != 0)
168         return;
169
170     // allocate or reuse parameters
171
argTypes = location.executingMethod.getParameterTypes();
172     if (argTypes.length <5)
173         {
174         argValues = preAllocatedArgs[argTypes.length];
175         argSlots = preAllocatedSlots[argTypes.length];
176         argNames = preAllocatedNames[argTypes.length];
177         }
178     else
179         {
180         argValues = new Object JavaDoc[argTypes.length];
181         argSlots = new int[argTypes.length];
182         argNames = new String JavaDoc[argTypes.length];
183         }
184
185
186     try
187         {
188
189         // call the Vm to obtain the parameters
190
doGetLocalVariables(thread,location.executingMethod,location.executingMethod.getDeclaringClass(),argNames,argSlots);
191         }
192     catch(AbsentInformationException e)
193         {
194         // no debugger info, we compute the offsets ourselves
195
int slot = 0;
196         if ( (location.executingMethod.getModifiers() & Modifier.STATIC) == 0)
197             slot++;
198
199         for(int i = 0; i<argTypes.length; i++)
200             {
201             argNames[i] = null;
202             argSlots[i] = slot;
203             if ( Double JavaDoc.class.isAssignableFrom(argTypes[i]) || Long JavaDoc.class.isAssignableFrom(argTypes[i]) )
204                 slot+=2;
205             else
206                 slot+=1;
207             }
208         }
209     state |= STATE_GOT_INFO;
210     }
211
212
213
214    /*
215      * Set the local value in thread t, frameNumber frames up from frameId,
216      * located in the frame at slot index, to the value v.
217      *
218      * @throws StackFrameException if the frame is opaque (e.g., native)
219      * @throws InternalValueException if the frameId does not exist in
220      * this vm or the slot index is out of range
221      * @throws ProseVmException for a type mismatch
222      */

223     protected
224     void setLocalValue(Object JavaDoc v, int index) throws ClassCastException JavaDoc
225     {
226       doGetLocalVariableInfo();
227       Class JavaDoc cls = argTypes[index];
228       Thread JavaDoc crtThread = thread;
229       if (cls.isAssignableFrom(Boolean.TYPE))
230       {
231         setLocalBoolean(crtThread,depth,height,argSlots[index],((Boolean JavaDoc)v).booleanValue());
232         return;
233       }
234       if (cls.isAssignableFrom(Byte.TYPE))
235     {
236       setLocalInt(crtThread,depth,height,argSlots[index],((Byte JavaDoc)v).byteValue());
237       return;
238     }
239
240       if (cls.isAssignableFrom(Character.TYPE))
241       {
242     setLocalInt(crtThread,depth,height,argSlots[index],((Character JavaDoc)v).charValue());
243     return;
244       }
245
246       if (cls.isAssignableFrom(Short.TYPE))
247       {
248     setLocalInt(crtThread,depth,height,argSlots[index],((Short JavaDoc)v).shortValue());
249     return;
250       }
251
252       if (cls.isAssignableFrom(Integer.TYPE))
253       {
254     setLocalInt(crtThread,depth,height,argSlots[index],((Integer JavaDoc)v).intValue());
255     return;
256       }
257
258       if (cls.isAssignableFrom(Long.TYPE))
259     {
260       setLocalLong(crtThread,depth,height,argSlots[index],((Long JavaDoc)v).longValue());
261       return;
262     }
263       if (cls.isAssignableFrom (Double.TYPE))
264       {
265     setLocalDouble(crtThread,depth,height,argSlots[index],((Double JavaDoc)v).doubleValue());
266     return;
267       }
268
269       if (cls.isAssignableFrom(Float.TYPE))
270     {
271       setLocalFloat(crtThread,depth,height,argSlots[index],((Float JavaDoc)v).floatValue());
272       return;
273     }
274
275
276       setLocalObject(crtThread,depth,height,argSlots[index],v);
277     }
278
279     /*
280      * @throws StackFrameException if the frame is opaque (e.g., native)
281      * @throws InternalValueException if the frameId does not exist in
282      * this vm or the slot index is out of range
283      * @throws ProseVmException for a type mismatch, if the signature
284      * does not correspond to the variable in the slot.
285      */

286
287   protected Object JavaDoc getLocalValue(Class JavaDoc cls, int slot)
288     {
289       Thread JavaDoc crtThread = thread;
290
291       if (cls.isAssignableFrom(Boolean.TYPE))
292     {
293       return getLocalBoolean(crtThread,depth,height,slot)?Boolean.TRUE:Boolean.FALSE;
294     }
295
296       if (cls.isAssignableFrom(Byte.TYPE))
297           return new Byte JavaDoc((byte)getLocalInt(crtThread,depth,height,slot));
298
299       if (cls.isAssignableFrom(Character.TYPE))
300             return new Character JavaDoc((char)getLocalInt(crtThread,depth,height,slot));
301
302       if (cls.isAssignableFrom(Short.TYPE))
303         return new Short JavaDoc((short)getLocalInt(crtThread,depth,height,slot));
304
305       if (cls.isAssignableFrom(Integer.TYPE))
306     return new Integer JavaDoc((int)getLocalInt(crtThread,depth,height,slot));
307
308       if (cls.isAssignableFrom(Long.TYPE))
309         return new Long JavaDoc((int)getLocalLong(crtThread,depth,height,slot));
310
311       if (cls.isAssignableFrom(Double.TYPE))
312         return new Double JavaDoc((int)getLocalDouble(crtThread,depth,height,slot));
313
314       if (cls.isAssignableFrom (Float.TYPE))
315       return new Float JavaDoc(getLocalFloat(crtThread,depth,height,slot));
316
317       return getLocalObject(crtThread,depth,height,slot);
318
319     }
320
321   private static native void doGetLocalVariables(Thread JavaDoc t, Method JavaDoc meth, Class JavaDoc cls, String JavaDoc[] aNames, int[] aSlots);
322
323   /** FOR all 'getLocalXXX':Return the value in the stack of the
324    * thread <code>t</code>, located at slot <code>slot</code> in the
325    * stackframe <code>height</code> stackframes away (up) from the
326    * currently executing join point and <code>depth</code> stackframes
327    * down from the top of the stack.
328    */

329     private static native Object JavaDoc getLocalObject(Thread JavaDoc t, int depth, int height, int slot);
330
331     private static native int getLocalInt(Thread JavaDoc t, int depth, int height, int slot);
332
333     private static native byte getLocalByte(Thread JavaDoc t, int depth, int height, int slot);
334
335     private static native char getLocalChar(Thread JavaDoc t, int depth, int height, int slot);
336
337     private static native short getLocalShort(Thread JavaDoc t, int depth, int height, int slot);
338
339     private static native long getLocalLong(Thread JavaDoc t, int depth, int height, int slot);
340
341     private static native boolean getLocalBoolean(Thread JavaDoc t, int depth, int height, int slot);
342
343     private static native double getLocalDouble(Thread JavaDoc t, int depth, int height, int slot);
344
345     private static native float getLocalFloat(Thread JavaDoc t, int depth, int height, int slot);
346
347     private static native void setLocalObject(Thread JavaDoc t, int depth, int height, int slot, Object JavaDoc value);
348
349     private static native void setLocalInt(Thread JavaDoc t, int depth, int height, int slot, int value);
350
351     private static native void setLocalLong(Thread JavaDoc t, int depth, int height, int slot, long value);
352
353     private static native void setLocalBoolean(Thread JavaDoc t, int depth, int height, int slot, boolean value);
354
355     /** Set the value in the stack of the thread <code>t</code>, located at slot <code>slot</code>
356      * in the stackframe <code>frameNum</code> stackframes away (up) from the <code>baseFrame</code>.
357      */

358     private static native void setLocalDouble(Thread JavaDoc t, int depth, int height, int slot, double value);
359
360     /** Set the value in the stack of the thread <code>t</code>, located at slot <code>slot</code>
361      * in the stackframe <code>frameNum</code> stackframes away (up) from the <code>baseFrame</code>.
362      */

363     private static native void setLocalFloat(Thread JavaDoc t, int depth, int height, int slot, float value);
364
365     private native void doGetCallerLocationData(JoinPointLocation jpl, Thread JavaDoc t, int depth,int height);
366
367 }
368
369
370 //======================================================================
371
//
372
// $Log: JoinPointContext.java,v $
373
// Revision 1.1.1.1 2003/07/02 15:30:50 apopovic
374
// Imported from ETH Zurich
375
//
376
// Revision 1.6 2003/05/06 15:51:16 popovici
377
// Mozilla-ification
378
//
379
// Revision 1.5 2003/05/05 17:46:26 popovici
380
// Refactorization step (runes->prose) cleanup
381
//
382
// Revision 1.4 2003/04/30 14:46:33 popovici
383
// 2 Bugs: when reading Floats from the stack, we used to get a local int instead of a local float.
384
// Second: when writing to the stack, we used to write in the wrong slot
385
//
386
// Revision 1.3 2003/03/13 12:46:30 popovici
387
// Bug fix in the extraction of slot offsets. The non-native solution
388
// (computing offsets) was inverting static and non-static cases
389
//
390
// Revision 1.2 2003/03/04 16:09:36 popovici
391
// Documentation improvements
392
//
393
// Revision 1.1 2003/03/04 11:26:41 popovici
394
// Important refactorization step (march):
395
// - removal of 'JoinPointEvents'; JoinPoints now have the same function as events
396
// - reimplementation of the JVMAIDebuggerAspectInterface (better performance, coding conventions, removal of ProseVM
397
// structures
398
//
399
Popular Tags