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
00013 import gov.nasa.arc.ase.jpf.jvm.runtime.*;
00014
00015
00016 public class ThreadInfo implements iThreadInfo, Cloneable {
00017 int status = STATUS.NEW;
00018 ClassInfo ci = null;
00019 Stack JVMStack = new Stack();
00020
00021
00022 LockSet lockset = new LockSet();
00023
00024
00025
00026 Ref ref = Ref.NULL;
00027 int target = -1;
00028 int threadref = -1;
00029 int lock_count = 0;
00030
00031
00032 int tdIndex;
00033 boolean tdChanged = true;
00034
00035
00036 private boolean anyFrameChanged = false;
00037
00038 private BitSet frameChanged = new BitSet();
00039
00040 private int[] frameData = new int[0];
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
00051
00052
00053 public ThreadInfo() {
00054
00055 if (LockOrder.on())
00056 lockTree = new LockTree(this);
00057
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
00074 len--;
00075 frameData = new int[len];
00076 System.arraycopy(data, 1, frameData, 0, len);
00077
00078
00079 for (int idx = 0; idx < len; idx++)
00080 JVMStack.push(VirtualMachine.framePool.getObject(frameData[idx]));
00081 }
00082
00083 private void addFrame(StackFrame sf) {
00084 inSameMethod = false;
00085
00086
00087 if(JVMStack.size() != 0) {
00088 StackFrame sf1 = getTopStackFrame();
00089 sf.setUpto(sf1.pcs());
00090 }
00091
00092
00093
00094
00095 anyFrameChanged = true;
00096 frameChanged.set(JVMStack.size());
00097
00098
00099
00100 JVMStack.push(sf);
00101 }
00102 public void callerPop(int n) {
00103 int index = JVMStack.size() - 2;
00104
00105
00106 cloneFrame(index);
00107
00108 ((StackFrame)JVMStack.get(index)).pop(n);
00109 }
00110
00111 public void clearOperandStack() {
00112
00113
00114 cloneFrame();
00115
00116 ((StackFrame)JVMStack.peek()).clearOperandStack();
00117 }
00118
00119
00120 public void cloneFrame() {
00121 cloneFrame(JVMStack.size()-1);
00122 }
00123
00124 public void cloneFrame(int idx) {
00125 if (!frameChanged.get(idx)) {
00126
00127 anyFrameChanged = true;
00128 frameChanged.set(idx);
00129
00130
00131 Object sf = ((StackFrame)JVMStack.get(idx)).clone();
00132 JVMStack.set(idx, sf);
00133 }
00134 }
00135
00136 public InstructionHandle createAndThrowException(String classname,
00137 SystemState ss, KernelState ks, ThreadInfo th) {
00138
00139
00140
00141
00142 cloneFrame();
00143
00144 return createAndThrowException(classname, ss, ks, th);
00145 }
00146
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
00165
00166
00167
00168
00169
00170 public int depth() {
00171 return JVMStack.size();
00172 }
00173
00174 public int doRandom(int max, Scheduler sch) {
00175 return ((StackFrame)JVMStack.peek()).doRandom(max, sch);
00176 }
00177
00178 public void dup() {
00179
00180
00181 cloneFrame();
00182
00183 ((StackFrame)JVMStack.peek()).dup();
00184 }
00185
00186 public void dup_x1() {
00187
00188
00189 cloneFrame();
00190
00191 ((StackFrame)JVMStack.peek()).dup_x1();
00192 }
00193
00194 public void dup_x2() {
00195
00196
00197 cloneFrame();
00198
00199 ((StackFrame)JVMStack.peek()).dup_x2();
00200 }
00201
00202 public void dup2() {
00203
00204
00205 cloneFrame();
00206
00207 ((StackFrame)JVMStack.peek()).dup2();
00208 }
00209 public void dup2_x1() {
00210
00211
00212 cloneFrame();
00213
00214 ((StackFrame)JVMStack.peek()).dup2_x1();
00215 }
00216
00217 public void dup2_x2() {
00218
00219
00220 cloneFrame();
00221
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
00242
00243
00244
00245
00246 ((TrailInfo)ss.getTrailInfo()).addPC(pc);
00247
00248
00249 pc = pc.getInstruction().execute(ss, ks, this);
00250
00251
00252 if (JVMStack.size() != 0) setPC(pc);
00253
00254 return pc;
00255 }
00256
00257
00258
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
00271 ss.setTrailInfo(threadref, line, currentMethod.getClassInfo().getClassName());
00272
00273
00274
00275
00276
00277
00278
00279 ss.saveAtomicData(threadref, depth, currentMethod, line);
00280
00281
00282
00283
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
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
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
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 return true;
00330 }
00331
00332
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
00339 public int getCalleeThis(int locals) {
00340 if (JVMStack.size() != 0)
00341 return ((StackFrame)JVMStack.peek()).getCalleeThis(locals);
00342
00343
00344
00345
00346
00347 return -1;
00348 }
00349 public ClassInfo getClassInfo() {
00350 return ci;
00351 }
00352
00353 public ConstantPoolGen getCPG() {
00354 return ((StackFrame)JVMStack.peek()).getConstantPool();
00355 }
00356
00357 public ClassInfo getCurrentClass() {
00358 return ((StackFrame)JVMStack.peek()).getClassInfo();
00359 }
00360
00361 public ClassInfo getCurrentClass(int idx) {
00362 return ((StackFrame)JVMStack.get(idx)).getClassInfo();
00363 }
00364
00365 public int getCurrentLine() {
00366 return ((StackFrame)JVMStack.peek()).getCurrentLine();
00367 }
00368
00369 public int getCurrentLine(int idx) {
00370 return ((StackFrame)JVMStack.get(idx)).getCurrentLine();
00371 }
00372
00373 public MethodInfo getCurrentMethod() {
00374 return ((StackFrame)JVMStack.peek()).getMethodInfo();
00375 }
00376
00377 public MethodInfo getCurrentMethod(int idx) {
00378 return ((StackFrame)JVMStack.get(idx)).getMethodInfo();
00379 }
00380
00381 public int getLocalVariable(int idx) {
00382 return ((StackFrame)JVMStack.peek()).getLocalVariable(idx);
00383 }
00384 public int getLockCount(){
00385 return lock_count;
00386 }
00387
00388
00389
00390
00391 public LockSet getLockSet(){
00392 return lockset;
00393 }
00394 public LockTree getLockTree(){
00395 return lockTree;
00396 }
00397
00398 public long getLongLocalVariable(int idx) {
00399 return ((StackFrame)JVMStack.peek()).getLongLocalVariable(idx);
00400 }
00401 public InstructionHandle getPC() {
00402 if (JVMStack.size() == 0)
00403
00404 return null;
00405 else
00406 return ((StackFrame)JVMStack.peek()).getPC();
00407 }
00408
00409 public InstructionHandle getPC(int i) {
00410 if (i < JVMStack.size())
00411 return ((StackFrame)JVMStack.get(i)).getPC();
00412 else
00413
00414 return null;
00415 }
00416 public Ref getReference() {
00417 return ref;
00418 }
00419
00420
00421
00422 public int getStatus(){
00423 return status;
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 public int[] getStoringData() {
00451
00452 update();
00453
00454 int l = frameData.length;
00455 int[] threadData = new int[l + 1];
00456
00457 if(tdChanged) {
00458 tdIndex = threadData[0] = VirtualMachine.threadPool.getIndex(newThreadData());
00459 tdChanged = false;
00460 } else
00461 threadData[0] = tdIndex;
00462
00463
00464 if (l > 0) System.arraycopy(frameData, 0, threadData, 1, l);
00465
00466
00467 return threadData;
00468 }
00469 public int getTarget() {
00470 return target;
00471 }
00472
00473 public int getThis() {
00474 if (JVMStack.size() != 0)
00475 return ((StackFrame)JVMStack.peek()).getThis();
00476
00477
00478
00479
00480
00481 return -1;
00482 }
00483 public int getThreadReference() {
00484 return threadref;
00485 }
00486
00487
00488
00489 public StackFrame getTopStackFrame() {
00490 return (StackFrame)JVMStack.peek();
00491 }
00492
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
00524 public void incIntLocalVariable(int index, int number) {
00525
00526
00527 cloneFrame();
00528
00529 ((StackFrame)JVMStack.peek()).incIntLocalVariable(index, number);
00530 }
00531
00532 public boolean isAlive(){
00533 return status == STATUS.RUNNING ||
00534 status == STATUS.WAITING ||
00535 status == STATUS.NOTIFIED;
00536 }
00537
00538 public boolean isEnabled(){
00539
00540
00541 if (RaceWindow.active && !RaceWindow.contains(ci.getClassName()))
00542 return false;
00543 else
00544
00545 return status == STATUS.RUNNING ||
00546 status == STATUS.NOTIFIED;
00547 }
00548
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
00559 public boolean isRunnable(iSystemState ss, iKernelState ks) {
00560 try {
00561 if (!isEnabled())
00562 return false;
00563
00564 Instruction ins = getPC().getInstruction();
00565
00566
00567
00568
00569
00570 if(Engine.options.real_counterexample)
00571 if(ins.examine((SystemState)ss, (KernelState)ks, this))
00572 return false;
00573
00574
00575
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
00587 public boolean isRunning(){
00588 return status == STATUS.RUNNING;
00589 }
00590
00591 public boolean isSafe() {
00592 if (!isEnabled())
00593 return false;
00594
00595 return ((StackFrame)JVMStack.peek()).isSafe();
00596 }
00597
00598 public void local2stack(int index) {
00599
00600
00601 cloneFrame();
00602
00603 ((StackFrame)JVMStack.peek()).local2stack(index);
00604 }
00605
00606 public void local2stack2(int index) {
00607
00608
00609 cloneFrame();
00610
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
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
00632 public void newFrame(MethodInfo mi) {
00633
00634
00635
00636
00637 addFrame(new StackFrame(mi, mi.getClassInfo()));
00638 }
00639
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
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 public int pcs() {
00688 if(JVMStack.size() == 0) return 0;
00689 return getTopStackFrame().pcs();
00690 }
00691
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
00705 public int pop() {
00706
00707
00708 cloneFrame();
00709
00710 return ((StackFrame)JVMStack.peek()).pop();
00711 }
00712 public void pop(int n) {
00713
00714
00715 cloneFrame();
00716
00717 ((StackFrame)JVMStack.peek()).pop(n);
00718 }
00719 public long pop2() {
00720
00721
00722 cloneFrame();
00723
00724 return ((StackFrame)JVMStack.peek()).pop2();
00725 }
00726
00727 public void popFrame() {
00728
00729
00730
00731 if(size() != 0)
00732 throw new InternalError("non-empty stack frame popped");
00733
00734 removeFrame();
00735
00736
00737
00738 anyFrameChanged = true;
00739 frameChanged.set(JVMStack.size());
00740
00741
00742 if (JVMStack.size() == 0) {
00743
00744 tdChanged = true;
00745
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
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
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
00783 public void push(int v) {
00784
00785
00786 cloneFrame();
00787
00788 ((StackFrame)JVMStack.peek()).push(v);
00789 }
00790 public void push2(long v) {
00791
00792
00793 cloneFrame();
00794
00795 ((StackFrame)JVMStack.peek()).push2(v);
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 public void removeArguments(MethodInfo mi) {
00813 pop(mi.getArgumentSize());
00814 }
00815
00816
00817
00818 private void removeFrame() {
00819
00820 if(((StackFrame)JVMStack.peek()).hasAnyRef())
00821 VirtualMachine.activateGC();
00822
00823
00824
00825
00826 if(inAtomicMethod && depth == depth()) {
00827 depth = 0;
00828 inAtomicMethod = false;
00829 }
00830 JVMStack.pop();
00831 inSameMethod = JVMStack.size() != 0 && getCurrentMethod() == currentMethod;
00832 }
00833
00834
00835
00836
00837
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
00853 len--;
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
00861
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
00867 JVMStack.setSize(len);
00868 } else {
00869
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
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) {
00890
00891 tdChanged = true;
00892
00893 ci = c;
00894 }
00895
00896
00897
00898
00899 }
00900
00901 public void setLocalVariable(int idx, int v) {
00902
00903
00904 cloneFrame();
00905
00906 ((StackFrame)JVMStack.peek()).setLocalVariable(idx, v);
00907 }
00908
00909 public void setLocalVariableRef(int idx) {
00910
00911
00912 cloneFrame();
00913
00914 ((StackFrame)JVMStack.peek()).setLocalVariableRef(idx);
00915 }
00916 public void setLockCount(int l){
00917
00918 tdChanged = true;
00919
00920 lock_count = l;
00921 }
00922 public void setOperandRef() {
00923
00924 cloneFrame();
00925
00926 ((StackFrame)JVMStack.peek()).setOperandRef();
00927 }
00928
00929 public void setPC(InstructionHandle pc) {
00930 if (JVMStack.size() != 0) {
00931
00932
00933 cloneFrame();
00934
00935 ((StackFrame)JVMStack.peek()).setPC(pc);
00936 }
00937 }
00938 public void setReference(Ref o) {
00939
00940 tdChanged = true;
00941
00942 ref = o;
00943 }
00944 public void setStatus(int s) {
00945
00946 tdChanged = true;
00947
00948 status = s;
00949 }
00950 public void setTarget(int t) {
00951
00952 tdChanged = true;
00953
00954 target = t;
00955 }
00956 public void setThreadReference(int t) {
00957 threadref = t;
00958 }
00959
00960 public int size() {
00961 return getTopStackFrame().operands.size();
00962 }
00963
00964 public void stack2local(int index) {
00965
00966
00967 cloneFrame();
00968
00969 ((StackFrame)JVMStack.peek()).stack2local(index);
00970 }
00971
00972 public void stack2local2(int index) {
00973
00974
00975 cloneFrame();
00976
00977 ((StackFrame)JVMStack.peek()).stack2local2(index);
00978 }
00979
00980 public void swap() {
00981
00982
00983 cloneFrame();
00984
00985 ((StackFrame)JVMStack.peek()).swap();
00986 }
00987
00988
00989
00990 public void update() {
00991
00992 if (anyFrameChanged) {
00993
00994 int s = JVMStack.size();
00995
00996
00997 int[] nFrameData = new int[s];
00998
00999 System.arraycopy(frameData, 0, nFrameData, 0, Math.min(s, frameData.length));
01000
01001 frameData = nFrameData;
01002
01003
01004 for (int i = 0; i < s; i++)
01005
01006 if (frameChanged.get(i)) {
01007
01008 StackFrame o = (StackFrame)JVMStack.get(i);
01009
01010 HashPool.PoolEntry e = VirtualMachine.framePool.getEntry(o);
01011
01012 JVMStack.set(i, e.getObject());
01013
01014 frameData[i] = e.getIndex();
01015 }
01016 }
01017
01018
01019 anyFrameChanged = false;
01020 frameChanged = new BitSet();
01021 }
01022 public int xpop() {
01023
01024
01025 cloneFrame();
01026
01027 return ((StackFrame)JVMStack.peek()).xpop();
01028 }
01029 public void xSetLocalVariableRef(int idx) {
01030
01031
01032 cloneFrame();
01033
01034 ((StackFrame)JVMStack.peek()).xSetLocalVariableRef(idx);
01035 }
01036 public void xSetOperandRef() {
01037
01038 cloneFrame();
01039
01040 ((StackFrame)JVMStack.peek()).xSetOperandRef();
01041 }
01042 }