View Javadoc
1   /*
2    * Copyright (c) 2000, 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.code;
26  
27  import java.io.*;
28  import java.util.*;
29  
30  import sun.jvm.hotspot.compiler.*;
31  import sun.jvm.hotspot.debugger.*;
32  import sun.jvm.hotspot.runtime.*;
33  import sun.jvm.hotspot.types.*;
34  import sun.jvm.hotspot.utilities.*;
35  
36  public class CodeBlob extends VMObject {
37    private static AddressField  nameField;
38    private static CIntegerField sizeField;
39    private static CIntegerField headerSizeField;
40    private static CIntegerField relocationSizeField;
41    private static CIntegerField contentOffsetField;
42    private static CIntegerField codeOffsetField;
43    private static CIntegerField frameCompleteOffsetField;
44    private static CIntegerField dataOffsetField;
45    private static CIntegerField frameSizeField;
46    private static AddressField  oopMapsField;
47  
48    // Only used by server compiler on x86; computed over in SA rather
49    // than relying on computation in target VM
50    private static final int     NOT_YET_COMPUTED = -2;
51    private static final int     UNDEFINED        = -1;
52    private              int     linkOffset       = NOT_YET_COMPUTED;
53    private static       int     matcherInterpreterFramePointerReg;
54  
55    static {
56      VM.registerVMInitializedObserver(new Observer() {
57          public void update(Observable o, Object data) {
58            initialize(VM.getVM().getTypeDataBase());
59          }
60        });
61    }
62  
63    private static void initialize(TypeDataBase db) {
64      Type type = db.lookupType("CodeBlob");
65  
66      nameField                = type.getAddressField("_name");
67      sizeField                = type.getCIntegerField("_size");
68      headerSizeField          = type.getCIntegerField("_header_size");
69      relocationSizeField      = type.getCIntegerField("_relocation_size");
70      frameCompleteOffsetField = type.getCIntegerField("_frame_complete_offset");
71      contentOffsetField       = type.getCIntegerField("_content_offset");
72      codeOffsetField          = type.getCIntegerField("_code_offset");
73      dataOffsetField          = type.getCIntegerField("_data_offset");
74      frameSizeField           = type.getCIntegerField("_frame_size");
75      oopMapsField             = type.getAddressField("_oop_maps");
76  
77      if (VM.getVM().isServerCompiler()) {
78        matcherInterpreterFramePointerReg =
79          db.lookupIntConstant("Matcher::interpreter_frame_pointer_reg").intValue();
80      }
81    }
82  
83    public CodeBlob(Address addr) {
84      super(addr);
85    }
86  
87    // Typing
88    public boolean isBufferBlob()         { return false; }
89    public boolean isNMethod()            { return false; }
90    public boolean isRuntimeStub()        { return false; }
91    public boolean isDeoptimizationStub() { return false; }
92    public boolean isUncommonTrapStub()   { return false; }
93    public boolean isExceptionStub()      { return false; }
94    public boolean isSafepointStub()      { return false; }
95    public boolean isAdapterBlob()        { return false; }
96  
97    // Fine grain nmethod support: isNmethod() == isJavaMethod() || isNativeMethod() || isOSRMethod()
98    public boolean isJavaMethod()         { return false; }
99    public boolean isNativeMethod()       { return false; }
100   /** On-Stack Replacement method */
101   public boolean isOSRMethod()          { return false; }
102 
103   public NMethod asNMethodOrNull() {
104     if (isNMethod()) return (NMethod)this;
105     return null;
106   }
107 
108   // Boundaries
109   public Address headerBegin() {
110     return addr;
111   }
112 
113   public Address headerEnd() {
114     return addr.addOffsetTo(headerSizeField.getValue(addr));
115   }
116 
117   // FIXME: add RelocInfo
118   //  public RelocInfo relocationBegin();
119   //  public RelocInfo relocationEnd();
120 
121   public Address contentBegin() {
122     return headerBegin().addOffsetTo(contentOffsetField.getValue(addr));
123   }
124 
125   public Address contentEnd() {
126     return headerBegin().addOffsetTo(dataOffsetField.getValue(addr));
127   }
128 
129   public Address codeBegin() {
130     return headerBegin().addOffsetTo(contentOffsetField.getValue(addr));
131   }
132 
133   public Address codeEnd() {
134     return headerBegin().addOffsetTo(dataOffsetField.getValue(addr));
135   }
136 
137   public Address dataBegin() {
138     return headerBegin().addOffsetTo(dataOffsetField.getValue(addr));
139   }
140 
141   public Address dataEnd() {
142     return headerBegin().addOffsetTo(sizeField.getValue(addr));
143   }
144 
145   // Offsets
146   public int getRelocationOffset() { return (int) headerSizeField   .getValue(addr); }
147   public int getContentOffset()    { return (int) contentOffsetField.getValue(addr); }
148   public int getCodeOffset()       { return (int) codeOffsetField   .getValue(addr); }
149   public int getDataOffset()       { return (int) dataOffsetField   .getValue(addr); }
150 
151   // Sizes
152   public int getSize()             { return (int) sizeField      .getValue(addr);     }
153   public int getHeaderSize()       { return (int) headerSizeField.getValue(addr);     }
154   // FIXME: add getRelocationSize()
155   public int getContentSize()      { return (int) contentEnd().minus(contentBegin()); }
156   public int getCodeSize()         { return (int) codeEnd()   .minus(codeBegin());    }
157   public int getDataSize()         { return (int) dataEnd()   .minus(dataBegin());    }
158 
159   // Containment
160   public boolean blobContains(Address addr)    { return headerBegin() .lessThanOrEqual(addr) && dataEnd()   .greaterThan(addr); }
161   // FIXME: add relocationContains
162   public boolean contentContains(Address addr) { return contentBegin().lessThanOrEqual(addr) && contentEnd().greaterThan(addr); }
163   public boolean codeContains(Address addr)    { return codeBegin()   .lessThanOrEqual(addr) && codeEnd()   .greaterThan(addr); }
164   public boolean dataContains(Address addr)    { return dataBegin()   .lessThanOrEqual(addr) && dataEnd()   .greaterThan(addr); }
165   public boolean contains(Address addr)        { return contentContains(addr);                                                  }
166   public boolean isFrameCompleteAt(Address a)  { return codeContains(a) && a.minus(codeBegin()) >= frameCompleteOffsetField.getValue(addr); }
167 
168   // Reclamation support (really only used by the nmethods, but in order to get asserts to work
169   // in the CodeCache they are defined virtual here)
170   public boolean isZombie()             { return false; }
171   public boolean isLockedByVM()         { return false; }
172 
173   /** OopMap for frame; can return null if none available */
174   public OopMapSet getOopMaps() {
175     Address oopMapsAddr = oopMapsField.getValue(addr);
176     if (oopMapsAddr == null) {
177       return null;
178     }
179     return new OopMapSet(oopMapsAddr);
180   }
181   // FIXME: not yet implementable
182   //  void set_oop_maps(OopMapSet* p);
183 
184   public OopMap getOopMapForReturnAddress(Address returnAddress, boolean debugging) {
185     Address pc = returnAddress;
186     if (Assert.ASSERTS_ENABLED) {
187       Assert.that(getOopMaps() != null, "nope");
188     }
189     return getOopMaps().findMapAtOffset(pc.minus(codeBegin()), debugging);
190   }
191 
192   //  virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, void f(oop*)) { ShouldNotReachHere(); }
193   //  FIXME;
194 
195   /** NOTE: this returns a size in BYTES in this system! */
196   public long getFrameSize() {
197     return VM.getVM().getAddressSize() * frameSizeField.getValue(addr);
198   }
199 
200   // Returns true, if the next frame is responsible for GC'ing oops passed as arguments
201   public boolean callerMustGCArguments() { return false; }
202 
203   public String getName() {
204     return CStringUtilities.getString(nameField.getValue(addr));
205   }
206 
207   // FIXME: NOT FINISHED
208 
209   // FIXME: add more accessors
210 
211   public void print() {
212     printOn(System.out);
213   }
214 
215   public void printOn(PrintStream tty) {
216     tty.print(getName());
217     printComponentsOn(tty);
218   }
219 
220   protected void printComponentsOn(PrintStream tty) {
221     tty.println(" content: [" + contentBegin() + ", " + contentEnd() + "), " +
222                 " code: [" + codeBegin() + ", " + codeEnd() + "), " +
223                 " data: [" + dataBegin() + ", " + dataEnd() + "), " +
224                 " frame size: " + getFrameSize());
225   }
226 }