hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ia64/IA64Frame.java
changeset 13909 9b94bf4dcc0c
parent 13908 6fa036b39eb9
parent 13907 52873e4bbeaa
child 13911 e59cfb5f223b
equal deleted inserted replaced
13908:6fa036b39eb9 13909:9b94bf4dcc0c
     1 /*
       
     2  * Copyright (c) 2003, 2012, 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.ia64;
       
    26 
       
    27 import java.util.*;
       
    28 // import sun.jvm.hotspot.asm.ia64.*;
       
    29 import sun.jvm.hotspot.code.*;
       
    30 import sun.jvm.hotspot.compiler.*;
       
    31 import sun.jvm.hotspot.debugger.*;
       
    32 import sun.jvm.hotspot.oops.*;
       
    33 import sun.jvm.hotspot.runtime.*;
       
    34 import sun.jvm.hotspot.types.*;
       
    35 import sun.jvm.hotspot.utilities.*;
       
    36 
       
    37 /** Specialization of and implementation of abstract methods of the
       
    38     Frame class for the ia64 family of CPUs. */
       
    39 
       
    40 public class IA64Frame extends Frame {
       
    41   private static final boolean DEBUG = false;
       
    42 
       
    43   // All frames
       
    44 
       
    45   // Interpreter frames
       
    46 
       
    47   // Entry frames
       
    48 
       
    49   // Native frames
       
    50 
       
    51   // an additional field beyond sp and pc:
       
    52   // Address raw_fp; // frame pointer only 1.4.2
       
    53 
       
    54   Address iframe;
       
    55 
       
    56   private IA64Frame() {
       
    57   }
       
    58 
       
    59   public IA64Frame(Address raw_sp, Address iframe, Address pc) {
       
    60     this.raw_sp = raw_sp;
       
    61     this.iframe = iframe;
       
    62     this.pc = pc;
       
    63     if (DEBUG) {
       
    64       System.err.println("IA64Frame(sp, iframe, pc): " + this);
       
    65       dumpStack();
       
    66     }
       
    67   }
       
    68 
       
    69   public Object clone() {
       
    70     IA64Frame frame = new IA64Frame();
       
    71     frame.raw_sp = raw_sp;
       
    72     frame.iframe = iframe;
       
    73     frame.pc = pc;
       
    74     return frame;
       
    75   }
       
    76 
       
    77   public boolean equals(Object arg) {
       
    78     if (arg == null) {
       
    79       return false;
       
    80     }
       
    81 
       
    82     if (!(arg instanceof IA64Frame)) {
       
    83       return false;
       
    84     }
       
    85 
       
    86     IA64Frame other = (IA64Frame) arg;
       
    87 
       
    88     return (AddressOps.equal(getSP(), other.getSP()) &&
       
    89             AddressOps.equal(getIFRAME(), other.getIFRAME()) &&
       
    90             AddressOps.equal(getPC(), other.getPC()));
       
    91   }
       
    92 
       
    93   public int hashCode() {
       
    94     if (iframe == null) {
       
    95       return 0;
       
    96     }
       
    97 
       
    98     return iframe.hashCode();
       
    99   }
       
   100 
       
   101   public String toString() {
       
   102     return "sp: " + (getSP() == null? "null" : getSP().toString()) +
       
   103          ", iframe: " + (getIFRAME() == null? "null" : getIFRAME().toString()) +
       
   104          ", pc: " + (pc == null? "null" : pc.toString());
       
   105   }
       
   106 
       
   107   // accessors for the instance variables
       
   108   public Address getFP() { return null; }
       
   109   public Address getIFRAME() { return iframe; }
       
   110   public Address getSP() { return raw_sp; }
       
   111   public Address getID() { return getFP(); }
       
   112 
       
   113   // FIXME: not implemented yet
       
   114   public boolean isSignalHandlerFrameDbg() { return false; }
       
   115   public int     getSignalNumberDbg()      { return 0;     }
       
   116   public String  getSignalNameDbg()        { return null;  }
       
   117 
       
   118   // FIXME: do sanity checks
       
   119   public boolean isInterpretedFrameValid() {
       
   120     return true;
       
   121   }
       
   122 
       
   123   public boolean isInterpretedFrame() { return iframe != null; }
       
   124 
       
   125 
       
   126   // FIXME: not applicable in current system
       
   127   //  void    patch_pc(Thread* thread, address pc);
       
   128 
       
   129   public Frame sender(RegisterMap regMap, CodeBlob cb) {
       
   130 
       
   131     if (iframe == null) {
       
   132       return null;
       
   133     }
       
   134 
       
   135     cInterpreter fr = new cInterpreter(iframe);
       
   136 
       
   137     if (fr.prev() == null) {
       
   138       Address wrapper = fr.wrapper();
       
   139       if ( wrapper == null) {
       
   140         return null;
       
   141       }
       
   142       IA64JavaCallWrapper jcw = new IA64JavaCallWrapper(wrapper);
       
   143       Address iprev = jcw.getPrevIFrame();
       
   144       if (iprev == null) {
       
   145         return null;
       
   146       }
       
   147       return new IA64Frame(null, iprev, null);
       
   148     } else {
       
   149       return new IA64Frame(null, fr.prev(), null);
       
   150     }
       
   151 
       
   152     /*
       
   153     IA64RegisterMap map = (IA64RegisterMap) regMap;
       
   154 
       
   155     if (Assert.ASSERTS_ENABLED) {
       
   156       Assert.that(map != null, "map must be set");
       
   157     }
       
   158 
       
   159     // Default is we done have to follow them. The sender_for_xxx will
       
   160     // update it accordingly
       
   161     map.setIncludeArgumentOops(false);
       
   162 
       
   163     if (isEntryFrame())       return senderForEntryFrame(map);
       
   164     if (isInterpretedFrame()) return senderForInterpreterFrame(map);
       
   165 
       
   166     if (!VM.getVM().isCore()) {
       
   167       if(cb == null) {
       
   168         cb = VM.getVM().getCodeCache().findBlob(getPC());
       
   169       } else {
       
   170         if (Assert.ASSERTS_ENABLED) {
       
   171           Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
       
   172         }
       
   173       }
       
   174 
       
   175       if (cb != null) {
       
   176          return senderForCompiledFrame(map, cb);
       
   177       }
       
   178     }
       
   179 
       
   180     // Must be native-compiled frame, i.e. the marshaling code for native
       
   181     // methods that exists in the core system.
       
   182     return new IA64Frame(getSenderSP(), getLink(), getSenderPC());
       
   183 
       
   184     */
       
   185   }
       
   186 
       
   187   private Frame senderForEntryFrame(IA64RegisterMap map) {
       
   188     if (Assert.ASSERTS_ENABLED) {
       
   189       Assert.that(map != null, "map must be set");
       
   190     }
       
   191     /*
       
   192     // Java frame called from C; skip all C frames and return top C
       
   193     // frame of that chunk as the sender
       
   194     IA64JavaCallWrapper jcw = (IA64JavaCallWrapper) getEntryFrameCallWrapper();
       
   195     if (Assert.ASSERTS_ENABLED) {
       
   196       Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero");
       
   197       Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack");
       
   198     }
       
   199     IA64Frame fr = new IA64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), null);
       
   200     map.clear();
       
   201     if (Assert.ASSERTS_ENABLED) {
       
   202       Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
       
   203     }
       
   204     return fr;
       
   205     */
       
   206     throw new RuntimeException("senderForEntryFrame NYI");
       
   207   }
       
   208 
       
   209   private Frame senderForInterpreterFrame(IA64RegisterMap map) {
       
   210     /*
       
   211     Address sp = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
       
   212     // We do not need to update the callee-save register mapping because above
       
   213     // us is either another interpreter frame or a converter-frame, but never
       
   214     // directly a compiled frame.
       
   215     return new IA64Frame(sp, getLink(), getSenderPC());
       
   216     */
       
   217     throw new RuntimeException("senderForInterpreterFrame NYI");
       
   218   }
       
   219 
       
   220   private Frame senderForDeoptimizedFrame(IA64RegisterMap map, CodeBlob cb) {
       
   221     // FIXME
       
   222     throw new RuntimeException("Deoptimized frames not handled yet");
       
   223   }
       
   224 
       
   225   private Frame senderForCompiledFrame(IA64RegisterMap map, CodeBlob cb) {
       
   226     //
       
   227     // NOTE: some of this code is (unfortunately) duplicated in IA64CurrentFrameGuess
       
   228     //
       
   229 
       
   230     if (Assert.ASSERTS_ENABLED) {
       
   231       Assert.that(map != null, "map must be set");
       
   232     }
       
   233 
       
   234     throw new RuntimeException("senderForCompiledFrame NYI");
       
   235 
       
   236     /*
       
   237 
       
   238     // frame owned by optimizing compiler
       
   239     Address        sender_sp = null;
       
   240 
       
   241     if (VM.getVM().isClientCompiler()) {
       
   242       sender_sp        = addressOfStackSlot(SENDER_SP_OFFSET);
       
   243     } else {
       
   244       if (Assert.ASSERTS_ENABLED) {
       
   245         Assert.that(cb.getFrameSize() >= 0, "Compiled by Compiler1: do not use");
       
   246       }
       
   247       sender_sp = getSP().addOffsetTo(cb.getFrameSize());
       
   248     }
       
   249 
       
   250     // On Intel the return_address is always the word on the stack
       
   251     Address sender_pc = sender_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
       
   252 
       
   253     if (map.getUpdateMap() && cb.getOopMaps() != null) {
       
   254       OopMapSet.updateRegisterMap(this, cb, map, true);
       
   255     }
       
   256 
       
   257     Address saved_fp = null;
       
   258     if (VM.getVM().isClientCompiler()) {
       
   259       saved_fp = getFP().getAddressAt(0);
       
   260     } else {
       
   261       int llink_offset = cb.getLinkOffset();
       
   262       if (llink_offset >= 0) {
       
   263         // Restore base-pointer, since next frame might be an interpreter frame.
       
   264         Address fp_addr = getSP().addOffsetTo(VM.getVM().getAddressSize() * llink_offset);
       
   265         saved_fp = fp_addr.getAddressAt(0);
       
   266       }
       
   267     }
       
   268 
       
   269     sender_sp = null ; // sp_addr.getAddressAt(0);
       
   270 
       
   271     return new IA64Frame(sender_sp, saved_fp, sender_pc);
       
   272 
       
   273     */
       
   274   }
       
   275 
       
   276   protected boolean hasSenderPD() {
       
   277     // FIXME
       
   278     return true;
       
   279   }
       
   280 
       
   281   public long frameSize() {
       
   282     throw new RuntimeException("frameSize NYI");
       
   283     /*
       
   284     return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize());
       
   285     */
       
   286   }
       
   287 
       
   288   public Address getLink() {
       
   289     throw new RuntimeException("getLink NYI");
       
   290     /*
       
   291     return addressOfStackSlot(LINK_OFFSET).getAddressAt(0);
       
   292     */
       
   293   }
       
   294 
       
   295   // FIXME: not implementable yet
       
   296   //inline void      frame::set_link(intptr_t* addr)  { *(intptr_t **)addr_at(link_offset) = addr; }
       
   297 
       
   298   public Address getUnextendedSP() { return getSP(); }
       
   299 
       
   300   // Return address:
       
   301   /*
       
   302   public Address getSenderPCAddr() { return addressOfStackSlot(RETURN_ADDR_OFFSET); }
       
   303   */
       
   304 
       
   305   public Address getSenderPC()     { return null;  }
       
   306 
       
   307   /*
       
   308   // return address of param, zero origin index.
       
   309   public Address getNativeParamAddr(int idx) {
       
   310     return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx);
       
   311   }
       
   312   */
       
   313 
       
   314   public Address getSenderSP()     { return null; }
       
   315 
       
   316   /*
       
   317   public Address compiledArgumentToLocationPD(VMReg reg, RegisterMap regMap, int argSize) {
       
   318     if (VM.getVM().isCore() || VM.getVM().isClientCompiler()) {
       
   319       throw new RuntimeException("Should not reach here");
       
   320     }
       
   321 
       
   322     return oopMapRegToLocation(reg, regMap);
       
   323   }
       
   324 
       
   325   */
       
   326 
       
   327   public Address addressOfInterpreterFrameLocals() {
       
   328     if (iframe == null) {
       
   329       throw new RuntimeException("Not an Interpreter frame");
       
   330     }
       
   331     cInterpreter fr = new cInterpreter(iframe);
       
   332     return fr.locals();
       
   333   }
       
   334 
       
   335   private Address addressOfInterpreterFrameBCX() {
       
   336     if (iframe == null) {
       
   337       throw new RuntimeException("Not an Interpreter frame");
       
   338     }
       
   339     cInterpreter fr = new cInterpreter(iframe);
       
   340     return fr.bcpAddr();
       
   341   }
       
   342 
       
   343   public int getInterpreterFrameBCI() {
       
   344     // FIXME: this is not atomic with respect to GC and is unsuitable
       
   345     // for use in a non-debugging, or reflective, system. Need to
       
   346     // figure out how to express this.
       
   347     Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
       
   348     Address methodHandle = addressOfInterpreterFrameMethod().getAddressAt(0);
       
   349     Method method = (Method)Metadata.instantiateWrapperFor(methodHandle);
       
   350     return bcpToBci(bcp, method);
       
   351   }
       
   352 
       
   353   public Address addressOfInterpreterFrameMDX() {
       
   354     return null;
       
   355   }
       
   356 
       
   357   // FIXME
       
   358   //inline int frame::interpreter_frame_monitor_size() {
       
   359   //  return BasicObjectLock::size();
       
   360   //}
       
   361 
       
   362   // expression stack
       
   363   // (the max_stack arguments are used by the GC; see class FrameClosure)
       
   364 
       
   365   public Address addressOfInterpreterFrameExpressionStack() {
       
   366     if (iframe == null) {
       
   367       throw new RuntimeException("Not an Interpreter frame");
       
   368     }
       
   369     cInterpreter fr = new cInterpreter(iframe);
       
   370     return fr.stackBase();
       
   371   }
       
   372 
       
   373   public int getInterpreterFrameExpressionStackDirection() { return -1; }
       
   374 
       
   375   // top of expression stack
       
   376   public Address addressOfInterpreterFrameTOS() {
       
   377     if (iframe == null) {
       
   378       throw new RuntimeException("Not an Interpreter frame");
       
   379     }
       
   380     cInterpreter fr = new cInterpreter(iframe);
       
   381     // tos always points to first free element in c++ interpreter not tos
       
   382     return fr.stackBase().addOffsetTo(VM.getVM().getAddressSize());
       
   383   }
       
   384 
       
   385   /** Expression stack from top down */
       
   386   public Address addressOfInterpreterFrameTOSAt(int slot) {
       
   387     return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize());
       
   388   }
       
   389 
       
   390   public Address getInterpreterFrameSenderSP() {
       
   391     if (Assert.ASSERTS_ENABLED) {
       
   392       Assert.that(isInterpretedFrame(), "interpreted frame expected");
       
   393     }
       
   394     throw new RuntimeException("getInterpreterFrameSenderSP NYI");
       
   395   }
       
   396 
       
   397   // Monitors
       
   398   public BasicObjectLock interpreterFrameMonitorBegin() {
       
   399     if (iframe == null) {
       
   400       throw new RuntimeException("Not an Interpreter frame");
       
   401     }
       
   402     cInterpreter fr = new cInterpreter(iframe);
       
   403     return new BasicObjectLock(fr.monitorBase());
       
   404   }
       
   405 
       
   406   public BasicObjectLock interpreterFrameMonitorEnd() {
       
   407     if (iframe == null) {
       
   408       throw new RuntimeException("Not an Interpreter frame");
       
   409     }
       
   410     cInterpreter fr = new cInterpreter(iframe);
       
   411     // Monitors end is just above stack base (2 slots per monitor)
       
   412     Address result = fr.stackBase().addOffsetTo(2 * VM.getVM().getAddressSize());
       
   413     /*
       
   414     if (Assert.ASSERTS_ENABLED) {
       
   415       // make sure the pointer points inside the frame
       
   416       Assert.that(AddressOps.gt(getFP(), result), "result must <  than frame pointer");
       
   417       Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer");
       
   418     }
       
   419     */
       
   420     return new BasicObjectLock(result);
       
   421   }
       
   422 
       
   423   public int interpreterFrameMonitorSize() {
       
   424     return BasicObjectLock.size();
       
   425   }
       
   426 
       
   427   // Method
       
   428   public Address addressOfInterpreterFrameMethod() {
       
   429     if (iframe == null) {
       
   430       throw new RuntimeException("Not an Interpreter frame");
       
   431     }
       
   432     cInterpreter fr = new cInterpreter(iframe);
       
   433     return fr.methodAddr();
       
   434   }
       
   435 
       
   436   // Constant pool cache
       
   437   public Address addressOfInterpreterFrameCPCache() {
       
   438     if (iframe == null) {
       
   439       throw new RuntimeException("Not an Interpreter frame");
       
   440     }
       
   441     cInterpreter fr = new cInterpreter(iframe);
       
   442     return fr.constantsAddr();
       
   443   }
       
   444 
       
   445   // Entry frames
       
   446   public JavaCallWrapper getEntryFrameCallWrapper() {
       
   447     throw new RuntimeException("getEntryFrameCallWrapper NYI");
       
   448   }
       
   449 
       
   450   protected Address addressOfSavedOopResult() {
       
   451     throw new RuntimeException("public boolean isInterpretedFrame() NYI");
       
   452     /*
       
   453     // offset is 2 for compiler2 and 3 for compiler1
       
   454     return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) *
       
   455                                VM.getVM().getAddressSize());
       
   456     */
       
   457   }
       
   458 
       
   459   protected Address addressOfSavedReceiver() {
       
   460     throw new RuntimeException("getEntryFrameCallWrapper NYI");
       
   461     // return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize());
       
   462   }
       
   463 
       
   464   private void dumpStack() {
       
   465     /*
       
   466     if (getFP() != null) {
       
   467       for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
       
   468            AddressOps.lte(addr, getFP().addOffsetTo(5 * VM.getVM().getAddressSize()));
       
   469            addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
       
   470         System.out.println(addr + ": " + addr.getAddressAt(0));
       
   471       }
       
   472     } else {
       
   473       for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
       
   474            AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize()));
       
   475            addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
       
   476         System.out.println(addr + ": " + addr.getAddressAt(0));
       
   477       }
       
   478     }
       
   479     */
       
   480   }
       
   481 }