1 /*
  2  * Copyright (c) 2000, 2017, 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.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 package sun.jvm.hotspot.runtime;
 26 
 27 import java.util.*;
 28 import sun.jvm.hotspot.debugger.*;
 29 import sun.jvm.hotspot.interpreter.*;
 30 import sun.jvm.hotspot.oops.*;
 31 import sun.jvm.hotspot.utilities.*;
 32 
 33 public class InterpretedVFrame extends JavaVFrame {
 34   /** JVM state */
 35   public Method getMethod() {
 36     return getFrame().getInterpreterFrameMethod();
 37   }
 38 
 39   public StackValueCollection getLocals() {
 40     Method m = getMethod();
 41 
 42     int length = (int) m.getMaxLocals();
 43 
 44     if (m.isNative()) {
 45       // If the method is native, getMaxLocals is not telling the truth.
 46       // maxlocals then equals the size of parameters
 47       length = (int) m.getSizeOfParameters();
 48     }
 49 
 50     StackValueCollection result = new StackValueCollection(length);
 51 
 52     // Get oopmap describing oops and int for current bci
 53     OopMapCacheEntry oopMask = getMethod().getMaskFor(getBCI());
 54 
 55     // handle locals
 56     for(int i = 0; i < length; i++) {
 57       // Find stack location
 58       Address addr = addressOfLocalAt(i);
 59 
 60       // Depending on oop/int put it in the right package
 61       StackValue sv;
 62       if (oopMask.isOop(i)) {
 63         // oop value
 64         sv = new StackValue(addr.getOopHandleAt(0), 0);
 65       } else {
 66         // integer
 67         // Fetch a signed integer the size of a stack slot
 68         sv = new StackValue(addr.getCIntegerAt(0, VM.getVM().getAddressSize(), false));
 69       }
 70       result.add(sv);
 71     }
 72 
 73     return result;
 74   }
 75 
 76   public StackValueCollection getExpressions() {
 77     int length = getFrame().getInterpreterFrameExpressionStackSize();
 78 
 79     if (getMethod().isNative()) {
 80       // If the method is native, there is no expression stack
 81       length = 0;
 82     }
 83 
 84     int nofLocals = (int) getMethod().getMaxLocals();
 85     StackValueCollection result = new StackValueCollection(length);
 86 
 87     // Get oopmap describing oops and int for current bci
 88     OopMapCacheEntry oopMask = getMethod().getMaskFor(getBCI());
 89 
 90     for(int i = 0; i < length; i++) {
 91       // Find stack location
 92       Address addr = addressOfExpressionStackAt(i);
 93 
 94       // Depending on oop/int put it in the right package
 95       StackValue sv;
 96       if (oopMask.isOop(i + nofLocals)) {
 97         // oop value
 98         sv = new StackValue(addr.getOopHandleAt(0), 0);
 99       } else {
100         // integer
101         // Fetch a signed integer the size of a stack slot
102         sv = new StackValue(addr.getCIntegerAt(0, VM.getVM().getAddressSize(), false));
103       }
104       result.add(sv);
105     }
106 
107     return result;
108   }
109 
110   /** Returns List<MonitorInfo> */
111   public List<MonitorInfo> getMonitors() {
112     List<MonitorInfo> result = new ArrayList<>(5);
113     for (BasicObjectLock current = getFrame().interpreterFrameMonitorEnd();
114          current.address().lessThan(getFrame().interpreterFrameMonitorBegin().address());
115          current = getFrame().nextMonitorInInterpreterFrame(current)) {
116       result.add(new MonitorInfo(current.obj(), false, false));
117     }
118     return result;
119   }
120 
121   /** Test operation */
122   public boolean isInterpretedFrame() { return true; }
123 
124   /** Package-internal constructor */
125   InterpretedVFrame(Frame fr, RegisterMap regMap, JavaThread thread) {
126     super(fr, regMap, thread);
127   }
128 
129   /** Accessor for Byte Code Index (NOTE: access to BCP is not allowed
130       in this system; see Frame.java) */
131   public int getBCI() {
132     return getFrame().getInterpreterFrameBCI();
133   }
134 
135   /** Setter for Byte Code Index */
136   // FIXME: not yet implementable
137   //  public void setBCI(int bci) {
138   //    getFrame().setInterpreterFrameBCI(bci);
139   //  }
140 
141   public void verify() {
142   }
143 
144   //--------------------------------------------------------------------------------
145   // Internals only below this point
146   //
147 
148   private Address addressOfLocalAt(int index) {
149     if (Assert.ASSERTS_ENABLED) {
150       Assert.that(getFrame().isInterpretedFrame(), "frame should be an interpreted frame");
151     }
152     return fr.addressOfInterpreterFrameLocal(index);
153   }
154 
155   private Address addressOfExpressionStackAt(int index) {
156     return fr.addressOfInterpreterFrameExpressionStackSlot(index);
157   }
158 }