Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

ThreadInfo.java

00001 package gov.nasa.arc.ase.jpf.jvm;
00002 
00003 import de.fub.bytecode.classfile.LineNumberTable;
00004 import de.fub.bytecode.Constants;
00005 import de.fub.bytecode.generic.*;
00006 import gov.nasa.arc.ase.jpf.*;
00007 import gov.nasa.arc.ase.util.Debug;
00008 import gov.nasa.arc.ase.util.HashData;
00009 import gov.nasa.arc.ase.util.HashPool;
00010 import java.io.*;
00011 import java.util.*;
00012 // ifdef RACE
00013 import gov.nasa.arc.ase.jpf.jvm.runtime.*;
00014 //#endif RACE
00015 
00016 public class ThreadInfo implements iThreadInfo, Cloneable {
00017   int status = STATUS.NEW;  // status of the thread
00018   ClassInfo   ci = null;    // class of the thread object
00019   Stack       JVMStack = new Stack();
00020                     // virtual machine stack
00021 // ifdef RACE
00022   LockSet lockset = new LockSet();
00023                     // set of locks used by the thread
00024 //#endif RACE
00025 
00026   Ref ref = Ref.NULL;       // object reference of the thread object
00027   int target = -1;  // object reference of the target
00028   int threadref = -1;       // position in the thread list
00029   int lock_count = 0;       // lock counter of the thread
00030 
00031 // ifdef NO_COMPRESSION
00032   int tdIndex;
00033   boolean tdChanged = true;
00034 
00035   // information used to cache the storing data information
00036   private boolean anyFrameChanged = false;
00037                     // frames are changed
00038   private BitSet frameChanged = new BitSet();
00039                     // frames that did change
00040   private int[] frameData = new int[0]; // index of the frames
00041   LockTree lockTree;
00042 
00043   private int depth = 0;
00044   private MethodInfo currentMethod = null;
00045   private int line = -1;
00046 
00047   private boolean inAtomicMethod = false;
00048   private boolean inSameMethod = true;
00049 
00050 //#endif NO_COMPRESSION
00051 
00052   // creates a new thread
00053   public ThreadInfo() {
00054 // ifdef RACE
00055     if (LockOrder.on())
00056       lockTree = new LockTree(this);
00057 //#endif RACE
00058   }  
00059   public ThreadInfo(KernelState ks, int[] data) {
00060     int len = data.length;
00061 
00062     ThreadData td = (ThreadData)VirtualMachine.threadPool.getObject(data[0]);
00063 
00064     tdIndex = data[0];
00065     tdChanged = false;
00066 
00067     status = td.status;
00068     ref = td.ref;
00069     ci = td.ci;
00070     target = td.target;
00071     lock_count = td.lock_count;
00072 
00073     // now we load the frame data
00074     len--;                  // skips the integers
00075     frameData = new int[len];
00076     System.arraycopy(data, 1, frameData, 0, len);
00077 
00078     // now we set all the frames
00079     for (int idx = 0; idx < len; idx++)
00080       JVMStack.push(VirtualMachine.framePool.getObject(frameData[idx]));
00081   }  
00082   // adds a frame
00083   private void addFrame(StackFrame sf) {
00084     inSameMethod = false;
00085 
00086     // EXTRA
00087     if(JVMStack.size() != 0) {
00088       StackFrame sf1 = getTopStackFrame();
00089       sf.setUpto(sf1.pcs());
00090     }
00091     // EXTRA
00092 
00093 // ifdef NO_COMPRESSION
00094     // sets the changed flags first
00095     anyFrameChanged = true;
00096     frameChanged.set(JVMStack.size());
00097 //#endif NO_COMPRESSION
00098 
00099     // push the new frame on the stack
00100     JVMStack.push(sf);
00101   }  
00102   public void callerPop(int n) {
00103     int index = JVMStack.size() - 2;
00104 // ifdef NO_COMPRESSION
00105     // creates a clone of the caller stack frame
00106     cloneFrame(index);
00107 //#endif NO_COMPRESSION
00108     ((StackFrame)JVMStack.get(index)).pop(n);
00109   }  
00110   // clears the operand stack of all value (used in case of exceptions)
00111   public void clearOperandStack() {
00112 // ifdef NO_COMPRESSION
00113     // creates a clone of the top stack frame
00114     cloneFrame();
00115 //#endif NO_COMPRESSION
00116     ((StackFrame)JVMStack.peek()).clearOperandStack();
00117   }  
00118 // ifdef NO_COMPRESSION
00119   // creates a clone of the top stack frame
00120   public void cloneFrame() {
00121     cloneFrame(JVMStack.size()-1);
00122   }  
00123   // creates a clone of the stack frame and set the fields
00124   public void cloneFrame(int idx) {
00125     if (!frameChanged.get(idx)) {
00126       // sets all the flags
00127       anyFrameChanged = true;
00128       frameChanged.set(idx);
00129       
00130       // make a clone and put that on the stack
00131       Object sf = ((StackFrame)JVMStack.get(idx)).clone();
00132       JVMStack.set(idx, sf);
00133     }
00134   }  
00135   // creates an exception of the given class and throws it
00136   public InstructionHandle createAndThrowException(String classname,
00137       SystemState ss, KernelState ks, ThreadInfo th) {
00138 // ifdef NO_COMPRESSION
00139     //** warning: I think we don't need to clone the frame here,    **//
00140     //**          but just to avoid errors we clone it anyway for now.  **//
00141     // creates a clone of the top stack frame
00142     cloneFrame();
00143 //#endif NO_COMPRESSION
00144     return createAndThrowException(classname, ss, ks, th);
00145   }  
00146 // ifdef MARK_N_SWEEP
00147   public void createMethodStackFrame(MethodInfo mi) {
00148     int nargs = mi.getArgumentSize();
00149     int[] args = new int[nargs];
00150     boolean[] refs = new boolean[nargs];
00151 
00152     for(int i = 0, cnt = nargs-1; i < nargs; i++, cnt--) {
00153       args[cnt] = peek(i);
00154       refs[cnt] = isOperandRef(i);
00155     }
00156 
00157     newFrame(mi);
00158 
00159     for(int i = 0; i < nargs; i++) {
00160       setLocalVariable(i, args[i]);
00161       if(refs[i]) setLocalVariableRef(i);
00162     }
00163   }  
00164 //#endif MARK_N_SWEEP
00165 
00166   // these functions allows you to access the StackFrame methods, filtering
00167   // the ones that alter a stack frame so that a clone is created.
00168 
00169   // gets the depth of the stack
00170   public int depth() {
00171     return JVMStack.size();
00172   }  
00173   // gets the next random value
00174   public int doRandom(int max, Scheduler sch) {
00175     return ((StackFrame)JVMStack.peek()).doRandom(max, sch);
00176   }  
00177   // duplicates an entry on the top stack frame
00178   public void dup() {
00179 // ifdef NO_COMPRESSION
00180     // creates a clone of the top stack frame
00181     cloneFrame();
00182 //#endif NO_COMPRESSION
00183     ((StackFrame)JVMStack.peek()).dup();
00184   }  
00185   // duplicates an entry on the top stack frame
00186   public void dup_x1() {
00187 // ifdef NO_COMPRESSION
00188     // creates a clone of the top stack frame
00189     cloneFrame();
00190 //#endif NO_COMPRESSION
00191     ((StackFrame)JVMStack.peek()).dup_x1();
00192   }  
00193   // duplicates an entry on the top stack frame
00194   public void dup_x2() {
00195 // ifdef NO_COMPRESSION
00196     // creates a clone of the top stack frame
00197     cloneFrame();
00198 //#endif NO_COMPRESSION
00199     ((StackFrame)JVMStack.peek()).dup_x2();
00200   }  
00201   // duplicates an entry on the top stack frame
00202   public void dup2() {
00203 // ifdef NO_COMPRESSION
00204     // creates a clone of the top stack frame
00205     cloneFrame();
00206 //#endif NO_COMPRESSION
00207     ((StackFrame)JVMStack.peek()).dup2();
00208   }  
00209   public void dup2_x1() {
00210 // ifdef NO_COMPRESSION
00211     // creates a clone of the top stack frame
00212     cloneFrame();
00213 //#endif NO_COMPRESSION
00214     ((StackFrame)JVMStack.peek()).dup2_x1();
00215   }  
00216   // duplicates an entry on the top stack frame
00217   public void dup2_x2() {
00218 // ifdef NO_COMPRESSION
00219     // creates a clone of the top stack frame
00220     cloneFrame();
00221 //#endif NO_COMPRESSION
00222     ((StackFrame)JVMStack.peek()).dup2_x2();
00223   }  
00224   public void executeAtomicMethod() {
00225     if(depth == 0) {
00226       depth = depth();
00227       inAtomicMethod = true;
00228     }
00229   }  
00230   public void executeAtomicMethod(int offset) {
00231     if(depth == 0) {
00232       depth = depth() + offset;
00233       inAtomicMethod = true;
00234     }
00235   }  
00236   /********************************************************************/
00237 
00238   public InstructionHandle executeInstruction(SystemState ss, KernelState ks) {
00239     InstructionHandle pc = getPC();
00240 
00241 // ifdef DEBUG_SEARCH
00242 
00243 //#endif DEBUG_SEARCH
00244 
00245     // adds this bytecode instruction to the trail
00246     ((TrailInfo)ss.getTrailInfo()).addPC(pc);
00247 
00248     // execute the next bytecode
00249     pc = pc.getInstruction().execute(ss, ks, this);
00250 
00251     // we did not return from the last frame stack
00252     if (JVMStack.size() != 0) setPC(pc);
00253 
00254     return pc;
00255   }  
00256 // ifdef DEBUG_SEARCH
00257 
00258 //#endif DEBUG_SEARCH
00259   
00260   public boolean executeStep(SystemState ss, KernelState ks) {
00261     if(currentMethod == null) {
00262       line = getCurrentLine();
00263       currentMethod = getCurrentMethod();
00264       inSameMethod = true;
00265     } else
00266       inSameMethod = (currentMethod == getCurrentMethod());
00267 
00268     LineNumberTable lines = currentMethod.getLineNumbers();
00269 
00270     // first sets the trail information so that we can reconstruct the trail
00271     ss.setTrailInfo(threadref, line, currentMethod.getClassInfo().getClassName());
00272 
00273 // ifdef DEBUG_SEARCH
00274 
00275 
00276 
00277 //#endif DEBUG_SEARCH
00278 
00279     ss.saveAtomicData(threadref, depth, currentMethod, line);
00280 
00281 // ifdef DEBUG_SEARCH
00282 
00283 //#endif DEBUG_SEARCH
00284     while(true) {
00285       InstructionHandle pc = executeInstruction(ss, ks);
00286       Runner.instructions++;
00287 
00288       if(pc == null) break;
00289       if(TransitionResult.atomicLevel != 0) {
00290     if(pc.getInstruction().examine(ss, ks, this)) continue;
00291 //    throw new InternalError("Non-deterministic statement in atomic block");
00292     if(!isRunnable(ss, ks)) {
00293       printStackTrace();
00294       throw new InternalError("Non-executable statement in atomic block");
00295     }
00296     continue;
00297       }
00298       if(!isRunnable(ss, ks)) break;
00299       if(inAtomicMethod) {
00300     if(pc.getInstruction().examine(ss, ks, this)) continue;
00301 //    throw new InternalError("Non-deterministic statement in atomic method");
00302     continue;
00303       }
00304       if(!inSameMethod || (
00305         line != lines.getSourceLine(pc.getPosition()) && 
00306         !(pc.getInstruction() instanceof ReturnInstruction))) {
00307     currentMethod = null;
00308     line = -1;
00309     break;
00310       }
00311     }
00312     
00313 // ifdef DEBUG_SEARCH
00314 
00315 
00316 //#endif DEBUG_SEARCH
00317 
00318 // ifdef REACHABILITY
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 //#endif REACHABILITY
00328 
00329     return true;
00330   }  
00331   // part of the bandera extension
00332   // checks if next instruction can be non deterministic
00333   /********************************************************************/
00334   public boolean findNondeterminismInNextInstruction(iSystemState ss, iKernelState ks) {
00335     Instruction ins = getPC().getInstruction();
00336     return ins.examine((SystemState)ss, (KernelState)ks, this);
00337   }  
00338   // gets the pointer to the object reference this
00339   public int getCalleeThis(int locals) {
00340     if (JVMStack.size() != 0)
00341       return ((StackFrame)JVMStack.peek()).getCalleeThis(locals);
00342 
00343 // ifdef DEBUG
00344 
00345 //#endif DEBUG
00346 
00347     return -1;
00348   }  
00349   public ClassInfo getClassInfo() {
00350     return ci;
00351   }  
00352   // gets the constant pool of the topmost frame
00353   public ConstantPoolGen getCPG() {
00354     return ((StackFrame)JVMStack.peek()).getConstantPool();    
00355   }  
00356   // gets the current class running
00357   public ClassInfo getCurrentClass() {
00358     return ((StackFrame)JVMStack.peek()).getClassInfo();
00359   }  
00360   // gets the current class running
00361   public ClassInfo getCurrentClass(int idx) {
00362     return ((StackFrame)JVMStack.get(idx)).getClassInfo();
00363   }  
00364   // gets the current line running
00365   public int getCurrentLine() {
00366     return ((StackFrame)JVMStack.peek()).getCurrentLine();
00367   }  
00368   // gets the current line running
00369   public int getCurrentLine(int idx) {
00370     return ((StackFrame)JVMStack.get(idx)).getCurrentLine();
00371   }  
00372   // gets the current method running
00373   public MethodInfo getCurrentMethod() {
00374     return ((StackFrame)JVMStack.peek()).getMethodInfo();
00375   }  
00376   // gets the current method running
00377   public MethodInfo getCurrentMethod(int idx) {
00378     return ((StackFrame)JVMStack.get(idx)).getMethodInfo();
00379   }  
00380   // gets a local variable in the top stack frame
00381   public int getLocalVariable(int idx) {
00382     return ((StackFrame)JVMStack.peek()).getLocalVariable(idx);
00383   }  
00384   public int getLockCount(){
00385     return lock_count;
00386   }  
00387 //#endif NO_COMPRESSION
00388 
00389 // ifdef RACE
00390   // these functions works of the locks set
00391   public LockSet getLockSet(){  
00392     return lockset;
00393   }  
00394   public LockTree getLockTree(){
00395     return lockTree;
00396   }  
00397   // gets a long local variable in the top stack frame
00398   public long getLongLocalVariable(int idx) {
00399     return ((StackFrame)JVMStack.peek()).getLongLocalVariable(idx);
00400   }  
00401   public InstructionHandle getPC() {
00402     if (JVMStack.size() == 0)
00403       // thread is stopped no instruction handle
00404       return null;
00405     else
00406       return ((StackFrame)JVMStack.peek()).getPC();
00407   }  
00408   // gets the current instruction handle
00409   public InstructionHandle getPC(int i) {
00410     if (i < JVMStack.size())
00411       return ((StackFrame)JVMStack.get(i)).getPC();
00412     else
00413       // thread is stopped no instruction handle
00414       return null;
00415   }  
00416   public Ref getReference() {
00417     return ref;
00418   }  
00419 //#endif RACE
00420 
00421   // functions to get and set the value of the internal fields
00422   public int getStatus(){
00423     return status;
00424   }  
00425 // ifdef NO_FASTBACKTRACK
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 // ifdef NO_COMPRESSION
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 //#endif NO_COMPRESSION
00445 
00446 //#endif NO_FASTBACKTRACK
00447 
00448 // ifdef NO_COMPRESSION
00449   // gets the information used for storing
00450   public int[] getStoringData() {
00451     // first let's update the information
00452     update();
00453 
00454     int l = frameData.length;           // number of frames
00455     int[] threadData = new int[l + 1];      // need four extra values
00456 
00457     if(tdChanged) {
00458       tdIndex = threadData[0] = VirtualMachine.threadPool.getIndex(newThreadData());
00459       tdChanged = false;
00460     } else
00461       threadData[0] = tdIndex;
00462 
00463     // saves the stack frame indexes
00464     if (l > 0) System.arraycopy(frameData, 0, threadData, 1, l);
00465 
00466     // returns the storing data
00467     return threadData;
00468   }  
00469   public int getTarget() {
00470     return target;
00471   }  
00472   // gets the pointer to the object reference this
00473   public int getThis() {
00474     if (JVMStack.size() != 0)
00475       return ((StackFrame)JVMStack.peek()).getThis();
00476 
00477 // ifdef DEBUG
00478 
00479 //#endif DEBUG
00480 
00481     return -1;
00482   }  
00483   public int getThreadReference() {
00484     return threadref;
00485   }  
00486 //#endif NO_COMPRESSION
00487 
00488   // this is a hacking used by the examine package
00489   public StackFrame getTopStackFrame() {
00490     return (StackFrame)JVMStack.peek();
00491   }  
00492   // EXTRA
00493   
00494   public TrailInfo getTrailInfo() {
00495     int l = getCurrentLine();
00496     MethodInfo m = getCurrentMethod();
00497     return new TrailInfo(threadref, 0, getCurrentLine(), getCurrentMethod().getClassInfo().getClassName());
00498   }  
00499   public void hash(HashData hd) {
00500     hd.add(status);
00501     hd.add(ref.reference);
00502     hd.add(target);
00503     hd.add(threadref);
00504     hd.add(lock_count);
00505 
00506     for(int i = 0, l = JVMStack.size(); i < l; i++)
00507       ((StackFrame)JVMStack.get(i)).hash(hd);
00508   }  
00509   public int hashCode() {
00510     HashData hd = new HashData();
00511 
00512     hd.add(status);
00513     hd.add(ref.reference);
00514     hd.add(target);
00515     hd.add(threadref);
00516     hd.add(lock_count);
00517 
00518     for(int i = 0, l = JVMStack.size(); i < l; i++)
00519       hd.add(JVMStack.get(i).hashCode());
00520 
00521     return hd.getValue();
00522   }  
00523   // increments a local variable
00524   public void incIntLocalVariable(int index, int number) {
00525 // ifdef NO_COMPRESSION
00526     // creates a clone of the top stack frame
00527     cloneFrame();
00528 //#endif NO_COMPRESSION
00529     ((StackFrame)JVMStack.peek()).incIntLocalVariable(index, number);
00530   }  
00531   // an alive thread is either running or waiting or notified
00532   public boolean isAlive(){
00533     return status == STATUS.RUNNING || 
00534       status == STATUS.WAITING || 
00535       status == STATUS.NOTIFIED;
00536   }  
00537   // an enabled thread is either running or notifed
00538   public boolean isEnabled(){
00539 // ifdef RACE
00540     // special handling for race conditions in runtime analysis
00541     if (RaceWindow.active && !RaceWindow.contains(ci.getClassName()))
00542       return false;
00543     else
00544 //#endif RACE
00545       return status == STATUS.RUNNING || 
00546     status == STATUS.NOTIFIED;
00547   }  
00548   // just notified
00549   public boolean isNotified(){
00550     return status == STATUS.NOTIFIED;
00551   }  
00552   public boolean isOperandRef() {
00553     return ((StackFrame)JVMStack.peek()).isOperandRef();
00554   }  
00555   public boolean isOperandRef(int idx) {
00556     return ((StackFrame)JVMStack.peek()).isOperandRef(idx);
00557   }  
00558   // a runnable thread is an enabled thread
00559   public boolean isRunnable(iSystemState ss, iKernelState ks) {
00560     try {
00561       if (!isEnabled())
00562     return false;
00563       
00564       Instruction ins = getPC().getInstruction();
00565 
00566       // this is a bandera extension to pilot the execution
00567       // a thread is runnable only if contains the next instruction
00568 
00569       /**************************************************************/
00570       if(Engine.options.real_counterexample)
00571     if(ins.examine((SystemState)ss, (KernelState)ks, this))
00572      return false;
00573       /**************************************************************/
00574 
00575       // the instruction needs to be executable as well
00576       return ins.isExecutable((SystemState)ss, (KernelState)ks, this);
00577     } catch(Exception e) {
00578       e.printStackTrace();
00579       printInternalErrorTrace(e);
00580       Engine.vm.getErrorTrail().print();
00581       System.exit(1);
00582     }
00583 
00584     return false;
00585   }  
00586   // just running
00587   public boolean isRunning(){
00588     return status == STATUS.RUNNING;
00589   }  
00590   // checks if the thread is safe (checks in the topmost frame)
00591   public boolean isSafe() {
00592     if (!isEnabled())
00593       return false;
00594 
00595     return ((StackFrame)JVMStack.peek()).isSafe();
00596   }  
00597   // copies a value from a local variable onto the stack
00598   public void local2stack(int index) {
00599 // ifdef NO_COMPRESSION
00600     // creates a clone of the top stack frame
00601     cloneFrame();
00602 //#endif NO_COMPRESSION
00603     ((StackFrame)JVMStack.peek()).local2stack(index);
00604   }  
00605   // copies a value from a local variable onto the stack
00606   public void local2stack2(int index) {
00607 // ifdef NO_COMPRESSION
00608     // creates a clone of the top stack frame
00609     cloneFrame();
00610 //#endif NO_COMPRESSION
00611     ((StackFrame)JVMStack.peek()).local2stack2(index);
00612   }  
00613   public void log() {
00614     Debug.println(Debug.MESSAGE, "TH#" + threadref + " #" + target + " " + (ref.isClass() ? "@" : "#") + ref.getReference() + " " + status);
00615     for(int i = 0; i < JVMStack.size(); i++)
00616       ((StackFrame)JVMStack.get(i)).log(i);
00617   }  
00618   public void log(KernelState ks) {
00619     ks.log();
00620   }  
00621 // ifdef MARK_N_SWEEP
00622   public void mark(DynamicArea da) {
00623     if(!ref.isNull() && !ref.isClass) da.mark(ref.reference);
00624     if(target != -1) da.mark(target);
00625 
00626     for(int i = 0, l = JVMStack.size(); i < l; i++) {
00627       StackFrame sf = (StackFrame)JVMStack.get(i);
00628       sf.mark(da);
00629     }
00630   }  
00631   // creates a new stack frame and adds it to the stack
00632   public void newFrame(MethodInfo mi) {
00633 // ifdef DEBUG
00634 
00635 //#endif DEBUG
00636 
00637     addFrame(new StackFrame(mi, mi.getClassInfo()));
00638   }  
00639 //#endif MARK_N_SWEEP
00640 
00641   public ThreadData newThreadData() {
00642     ThreadData td = new ThreadData();
00643 
00644     td.status = status;
00645     td.ref = ref;
00646     td.ci = ci;
00647     td.target = target;
00648     td.lock_count = lock_count;
00649 
00650     return td;
00651   }  
00652 // ifdef NO_COMPRESSION
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 //#endif NO_COMPRESSION
00672 
00673 // ifdef NO_FASTBACKTRACK
00674 
00675 
00676 
00677 
00678 
00679 
00680 
00681 
00682 
00683 
00684 //#endif NO_FASTBACKTRACK
00685 
00686   // EXTRA
00687   public int pcs() {
00688     if(JVMStack.size() == 0) return 0;
00689     return getTopStackFrame().pcs();
00690   }  
00691   // peeks a value from the top stack frame
00692   public int peek() {
00693     return ((StackFrame)JVMStack.peek()).peek();
00694   }  
00695   public int peek(int n) {
00696     return ((StackFrame)JVMStack.peek()).peek(n);
00697   }  
00698   public long peek2() {
00699     return ((StackFrame)JVMStack.peek()).peek2();
00700   }  
00701   public long peek2(int n) {
00702     return ((StackFrame)JVMStack.peek()).peek2(n);
00703   }  
00704   // pops a value from the top stack frame
00705   public int pop() {
00706 // ifdef NO_COMPRESSION
00707     // creates a clone of the top stack frame
00708     cloneFrame();
00709 //#endif NO_COMPRESSION
00710     return ((StackFrame)JVMStack.peek()).pop();
00711   }  
00712   public void pop(int n) {
00713 // ifdef NO_COMPRESSION
00714     // creates a clone of the top stack frame
00715     cloneFrame();
00716 //#endif NO_COMPRESSION
00717     ((StackFrame)JVMStack.peek()).pop(n);
00718   }  
00719   public long pop2() {
00720 // ifdef NO_COMPRESSION
00721     // creates a clone of the top stack frame
00722     cloneFrame();
00723 //#endif NO_COMPRESSION
00724     return ((StackFrame)JVMStack.peek()).pop2();
00725   }  
00726   // removes a stack frame
00727   public void popFrame() {
00728 // ifdef DEBUG
00729 
00730 //#endif DEBUG
00731     if(size() != 0)
00732       throw new InternalError("non-empty stack frame popped");
00733 
00734     removeFrame();
00735 
00736 // ifdef NO_COMPRESSION
00737     // a stack frame has been changed
00738     anyFrameChanged = true;
00739     frameChanged.set(JVMStack.size());
00740     // if I removes the last stack frame then the thread is stopped
00741 //#endif NO_COMPRESSION
00742     if (JVMStack.size() == 0) {
00743 // ifdef NO_COMPRESSION
00744       tdChanged = true;
00745 //#endif NO_COMPRESSION
00746       status = STATUS.STOPPED;
00747     }
00748   }  
00749   public void printInternalErrorTrace(Throwable e) {
00750     String msg = e.getMessage();
00751     if(msg != null)
00752       Debug.println(Debug.ERROR, "exception " + e.getClass().getName() + ": " + msg);
00753     else
00754       Debug.println(Debug.ERROR, "exception " + e.getClass().getName());
00755     printStackTrace();
00756     if(msg != null)
00757       Debug.println(Debug.ERROR, "exception " + e.getClass().getName() + ": " + msg);
00758     else
00759       Debug.println(Debug.ERROR, "exception " + e.getClass().getName());
00760     printStackContent();
00761   }  
00762 // ifdef DISTRIBUTED
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771 
00772 //#endif DISTRIBUTED
00773 
00774   public void printStackContent() {
00775     for(int i = JVMStack.size()-1; i >= 0; i--)
00776       ((StackFrame)JVMStack.get(i)).printStackContent();
00777   }  
00778   public void printStackTrace() {
00779     for(int i = JVMStack.size()-1; i >= 0; i--)
00780       ((StackFrame)JVMStack.get(i)).printStackTrace();
00781   }  
00782   // pushes a value onto the top stack frame
00783   public void push(int v) {
00784 // ifdef NO_COMPRESSION
00785     // creates a clone of the top stack frame
00786     cloneFrame();
00787 //#endif NO_COMPRESSION
00788     ((StackFrame)JVMStack.peek()).push(v);
00789   }  
00790   public void push2(long v) {
00791 // ifdef NO_COMPRESSION
00792     // creates a clone of the top stack frame
00793     cloneFrame();
00794 //#endif NO_COMPRESSION
00795     ((StackFrame)JVMStack.peek()).push2(v);
00796   }  
00797 //#else MARK_N_SWEEP
00798 
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 
00807 
00808 
00809 
00810 //#endif MARK_N_SWEEP
00811 
00812   public void removeArguments(MethodInfo mi) {
00813     pop(mi.getArgumentSize());
00814   }  
00815 //#endif NO_COMPRESSION
00816 
00817   // removes a frame
00818   private void removeFrame() {
00819 // ifdef MARK_N_SWEEP
00820     if(((StackFrame)JVMStack.peek()).hasAnyRef())
00821       VirtualMachine.activateGC();
00822 //#endif MARK_N_SWEEP
00823 // ifdef REFERENCE_COUNT
00824 
00825 //#endif REFERENCE_COUNT
00826     if(inAtomicMethod && depth == depth()) {
00827       depth = 0;
00828       inAtomicMethod = false;
00829     }
00830     JVMStack.pop();
00831     inSameMethod = JVMStack.size() != 0 && getCurrentMethod() == currentMethod;
00832   }  
00833 // ifdef NO_COMPRESSION
00834   // this function transform a threadinfo into another thread info
00835   // simply changing all the information. if we are lucky many of
00836   // the stack frames are in common and we don't need to go through
00837   // the pool
00838   public void revertTo(KernelState ks, int[] data) {
00839     int len = data.length;
00840 
00841     ThreadData td = (ThreadData)VirtualMachine.threadPool.getObject(data[0]);
00842 
00843     tdIndex = data[0];
00844     tdChanged = false;
00845 
00846     status = td.status;
00847     ref = td.ref;
00848     ci = td.ci;
00849     target = td.target;
00850     lock_count = td.lock_count;
00851 
00852     // now we load the new frame data
00853     len--;                  // skips the integers
00854     int[] nFrameData = new int[len];
00855     System.arraycopy(data, 1, nFrameData, 0, len);
00856 
00857     int s = Math.min(frameData.length, JVMStack.size());
00858 
00859     if (s >= len) {
00860       // if there are less frames now then before
00861       // we just update the one in common
00862       for (int idx = 0; idx < len; idx++)
00863     if(nFrameData[idx] != frameData[idx])
00864       JVMStack.set(idx,
00865           VirtualMachine.framePool.getObject(nFrameData[idx]));
00866       // then throw away the rest
00867       JVMStack.setSize(len);
00868     } else {
00869       // otherwise we update the one in common
00870       for (int idx = 0; idx < s; idx++)
00871     if(nFrameData[idx] != frameData[idx])
00872       JVMStack.set(idx,
00873           VirtualMachine.framePool.getObject(nFrameData[idx]));
00874       JVMStack.setSize(s);
00875       // and we add the next ones (if any)
00876       for (int idx = s; idx < len; idx++)
00877     JVMStack.push(VirtualMachine.framePool.getObject(nFrameData[idx]));
00878     }
00879     frameData = nFrameData;
00880   }  
00881   public void setAtomicData(int d, MethodInfo m, int l) {
00882     depth = d;
00883     inAtomicMethod = d != 0;
00884 
00885     currentMethod = m;
00886     line = l;
00887   }  
00888   public void setClassInfo(ClassInfo c) {
00889     if (ci == null) { // only set once for each thread
00890 // ifdef NO_COMPRESSION
00891       tdChanged = true;
00892 //#endif NO_COMPRESSION
00893       ci = c;
00894     }
00895 // ifdef DEBUG
00896 
00897 
00898 //#endif DEBUG
00899   }  
00900   // sets a local variable in the top stack frame
00901   public void setLocalVariable(int idx, int v) {
00902 // ifdef NO_COMPRESSION
00903     // creates a copy of the top stack frame first
00904     cloneFrame();
00905 //#endif NO_COMPRESSION
00906     ((StackFrame)JVMStack.peek()).setLocalVariable(idx, v);
00907   }  
00908 // ifdef MARK_N_SWEEP
00909   public void setLocalVariableRef(int idx) {
00910 // ifdef NO_COMPRESSION
00911     // creates a copy of the top stack frame first
00912     cloneFrame();
00913 //#endif NO_COMPRESSION
00914     ((StackFrame)JVMStack.peek()).setLocalVariableRef(idx);
00915   }  
00916   public void setLockCount(int l){
00917 // ifdef NO_COMPRESSION
00918     tdChanged = true;
00919 //#endif NO_COMPRESSION
00920     lock_count = l;
00921   }  
00922   public void setOperandRef() {
00923 // ifdef NO_COMPRESSION
00924     cloneFrame();
00925 //#endif NO_COMPRESSION
00926     ((StackFrame)JVMStack.peek()).setOperandRef();
00927   }  
00928   // sets the current instruction handle
00929   public void setPC(InstructionHandle pc) {
00930     if (JVMStack.size() != 0) {
00931 // ifdef NO_COMPRESSION
00932       // creates a clone of the top stack frame
00933       cloneFrame();
00934 //#endif NO_COMPRESSION
00935       ((StackFrame)JVMStack.peek()).setPC(pc);
00936     }
00937   }  
00938   public void setReference(Ref o) {
00939 // ifdef NO_COMPRESSION
00940     tdChanged = true;
00941 //#endif NO_COMPRESSION
00942     ref = o;
00943   }  
00944   public void setStatus(int s) {
00945 // ifdef NO_COMPRESSION
00946     tdChanged = true;
00947 //#endif NO_COMPRESSION
00948     status = s;
00949   }  
00950   public void setTarget(int t) {
00951 // ifdef NO_COMPRESSION
00952     tdChanged = true;
00953 //#endif NO_COMPRESSION
00954     target = t;
00955   }  
00956   public void setThreadReference(int t) {
00957     threadref = t;
00958   }  
00959   // gets the size of the operand stack
00960   public int size() {
00961     return getTopStackFrame().operands.size();
00962   }  
00963   // copies a value from the stack to a local variable
00964   public void stack2local(int index) {
00965 // ifdef NO_COMPRESSION
00966     // creates a clone of the top stack frame
00967     cloneFrame();
00968 //#endif NO_COMPRESSION
00969     ((StackFrame)JVMStack.peek()).stack2local(index);
00970   }  
00971   // copies a value from the stack to a local variable
00972   public void stack2local2(int index) {
00973 // ifdef NO_COMPRESSION
00974     // creates a clone of the top stack frame
00975     cloneFrame();
00976 //#endif NO_COMPRESSION
00977     ((StackFrame)JVMStack.peek()).stack2local2(index);
00978   }  
00979   // swaps two entry on the top stack frame
00980   public void swap() {
00981 // ifdef NO_COMPRESSION
00982     // creates a clone of the top stack frame
00983     cloneFrame();
00984 //#endif NO_COMPRESSION
00985     ((StackFrame)JVMStack.peek()).swap();
00986   }  
00987 //#endif NO_COMPRESSION
00988 
00989 // ifdef NO_COMPRESSION
00990   public void update() {
00991     // checks if any frame has changed
00992     if (anyFrameChanged) {
00993       // number of frames
00994       int s = JVMStack.size();
00995       // creates a new array because if could be smaller
00996       // or larger then the old one
00997       int[] nFrameData = new int[s];
00998       // copies the information
00999       System.arraycopy(frameData, 0, nFrameData, 0, Math.min(s, frameData.length));
01000       // puts it back in the original variable
01001       frameData = nFrameData;
01002 
01003       // scans the vector to find which ones have been changed
01004       for (int i = 0; i < s; i++)
01005     // for the one that are changed
01006     if (frameChanged.get(i)) {
01007       // gets the frame
01008       StackFrame o = (StackFrame)JVMStack.get(i);
01009       // put it throught the frame pool
01010       HashPool.PoolEntry e = VirtualMachine.framePool.getEntry(o);
01011       // sets the pointer to the value in the pool
01012       JVMStack.set(i, e.getObject());
01013       // sets the updated index
01014       frameData[i] = e.getIndex();
01015     }
01016     }
01017 
01018     // clears all the flags
01019     anyFrameChanged = false;
01020     frameChanged = new BitSet();
01021   }  
01022   public int xpop() {
01023 // ifdef NO_COMPRESSION
01024     // creates a clone of the top stack frame
01025     cloneFrame();
01026 //#endif NO_COMPRESSION
01027     return ((StackFrame)JVMStack.peek()).xpop();
01028   }  
01029   public void xSetLocalVariableRef(int idx) {
01030 // ifdef NO_COMPRESSION
01031     // creates a copy of the top stack frame first
01032     cloneFrame();
01033 //#endif NO_COMPRESSION
01034     ((StackFrame)JVMStack.peek()).xSetLocalVariableRef(idx);
01035   }  
01036   public void xSetOperandRef() {
01037 // ifdef NO_COMPRESSION
01038     cloneFrame();
01039 //#endif NO_COMPRESSION
01040     ((StackFrame)JVMStack.peek()).xSetOperandRef();
01041   }  
01042 }

Generated at Thu Feb 7 06:57:03 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001