1 /* 2 * Copyright 2000-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any 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 instructionsOffsetField; 42 private static CIntegerField frameCompleteOffsetField; 43 private static CIntegerField dataOffsetField; 44 private static CIntegerField oopsOffsetField; 45 private static CIntegerField oopsLengthField; 46 private static CIntegerField frameSizeField; 47 private static AddressField oopMapsField; 48 49 // Only used by server compiler on x86; computed over in SA rather 50 // than relying on computation in target VM 51 private static final int NOT_YET_COMPUTED = -2; 52 private static final int UNDEFINED = -1; 53 private int linkOffset = NOT_YET_COMPUTED; 54 private static int matcherInterpreterFramePointerReg; 55 56 static { 57 VM.registerVMInitializedObserver(new Observer() { 58 public void update(Observable o, Object data) { 59 initialize(VM.getVM().getTypeDataBase()); 60 } 61 }); 62 } 63 64 private static void initialize(TypeDataBase db) { 65 Type type = db.lookupType("CodeBlob"); 66 67 nameField = type.getAddressField("_name"); 68 sizeField = type.getCIntegerField("_size"); 69 headerSizeField = type.getCIntegerField("_header_size"); 70 relocationSizeField = type.getCIntegerField("_relocation_size"); 71 frameCompleteOffsetField = type.getCIntegerField("_frame_complete_offset"); 72 instructionsOffsetField = type.getCIntegerField("_instructions_offset"); 73 dataOffsetField = type.getCIntegerField("_data_offset"); 74 oopsOffsetField = type.getCIntegerField("_oops_offset"); 75 oopsLengthField = type.getCIntegerField("_oops_length"); 76 frameSizeField = type.getCIntegerField("_frame_size"); 77 oopMapsField = type.getAddressField("_oop_maps"); 78 79 if (VM.getVM().isServerCompiler()) { 80 matcherInterpreterFramePointerReg = 81 db.lookupIntConstant("Matcher::interpreter_frame_pointer_reg").intValue(); 82 } 83 } 84 85 public CodeBlob(Address addr) { 86 super(addr); 87 } 88 89 // Typing 90 public boolean isBufferBlob() { return false; } 91 public boolean isNMethod() { return false; } 92 public boolean isRuntimeStub() { return false; } 93 public boolean isDeoptimizationStub() { return false; } 94 public boolean isUncommonTrapStub() { return false; } 95 public boolean isExceptionStub() { return false; } 96 public boolean isSafepointStub() { return false; } 97 98 // Fine grain nmethod support: isNmethod() == isJavaMethod() || isNativeMethod() || isOSRMethod() 99 public boolean isJavaMethod() { return false; } 100 public boolean isNativeMethod() { return false; } 101 /** On-Stack Replacement method */ 102 public boolean isOSRMethod() { return false; } 103 104 // Boundaries 105 public Address headerBegin() { 106 return addr; 107 } 108 109 public Address headerEnd() { 110 return addr.addOffsetTo(headerSizeField.getValue(addr)); 111 } 112 113 // FIXME: add RelocInfo 114 // public RelocInfo relocationBegin(); 115 // public RelocInfo relocationEnd(); 116 117 public Address instructionsBegin() { 118 return headerBegin().addOffsetTo(instructionsOffsetField.getValue(addr)); 119 } 120 121 public Address instructionsEnd() { 122 return headerBegin().addOffsetTo(dataOffsetField.getValue(addr)); 123 } 124 125 public Address dataBegin() { 126 return headerBegin().addOffsetTo(dataOffsetField.getValue(addr)); 127 } 128 129 public Address dataEnd() { 130 return headerBegin().addOffsetTo(sizeField.getValue(addr)); 131 } 132 133 public Address oopsBegin() { 134 return headerBegin().addOffsetTo(oopsOffsetField.getValue(addr)); 135 } 136 137 public Address oopsEnd() { 138 return oopsBegin().addOffsetTo(getOopsLength()); 139 } 140 141 // Offsets 142 public int getRelocationOffset() { return (int) headerSizeField.getValue(addr); } 143 public int getInstructionsOffset() { return (int) instructionsOffsetField.getValue(addr); } 144 public int getDataOffset() { return (int) dataOffsetField.getValue(addr); } 145 public int getOopsOffset() { return (int) oopsOffsetField.getValue(addr); } 146 147 // Sizes 148 public int getSize() { return (int) sizeField.getValue(addr); } 149 public int getHeaderSize() { return (int) headerSizeField.getValue(addr); } 150 // FIXME: add getRelocationSize() 151 public int getInstructionsSize() { return (int) instructionsEnd().minus(instructionsBegin()); } 152 public int getDataSize() { return (int) dataEnd().minus(dataBegin()); } 153 154 // Containment 155 public boolean blobContains(Address addr) { return headerBegin().lessThanOrEqual(addr) && dataEnd().greaterThan(addr); } 156 // FIXME: add relocationContains 157 public boolean instructionsContains(Address addr) { return instructionsBegin().lessThanOrEqual(addr) && instructionsEnd().greaterThan(addr); } 158 public boolean dataContains(Address addr) { return dataBegin().lessThanOrEqual(addr) && dataEnd().greaterThan(addr); } 159 public boolean oopsContains(Address addr) { return oopsBegin().lessThanOrEqual(addr) && oopsEnd().greaterThan(addr); } 160 public boolean contains(Address addr) { return instructionsContains(addr); } 161 public boolean isFrameCompleteAt(Address a) { return instructionsContains(a) && a.minus(instructionsBegin()) >= frameCompleteOffsetField.getValue(addr); } 162 163 /** Support for oops in scopes and relocs. Note: index 0 is reserved for null. */ 164 public OopHandle getOopAt(int index) { 165 if (index == 0) return null; 166 if (Assert.ASSERTS_ENABLED) { 167 Assert.that(index > 0 && index <= getOopsLength(), "must be a valid non-zero index"); 168 } 169 return oopsBegin().getOopHandleAt((index - 1) * VM.getVM().getOopSize()); 170 } 171 172 // Reclamation support (really only used by the nmethods, but in order to get asserts to work 173 // in the CodeCache they are defined virtual here) 174 public boolean isZombie() { return false; } 175 public boolean isLockedByVM() { return false; } 176 177 /** OopMap for frame; can return null if none available */ 178 public OopMapSet getOopMaps() { 179 Address oopMapsAddr = oopMapsField.getValue(addr); 180 if (oopMapsAddr == null) { 181 return null; 182 } 183 return new OopMapSet(oopMapsAddr); 184 } 185 // FIXME: not yet implementable 186 // void set_oop_maps(OopMapSet* p); 187 188 public OopMap getOopMapForReturnAddress(Address returnAddress, boolean debugging) { 189 Address pc = returnAddress; 190 if (Assert.ASSERTS_ENABLED) { 191 Assert.that(getOopMaps() != null, "nope"); 192 } 193 return getOopMaps().findMapAtOffset(pc.minus(instructionsBegin()), debugging); 194 } 195 196 // virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, void f(oop*)) { ShouldNotReachHere(); } 197 // FIXME; 198 199 /** NOTE: this returns a size in BYTES in this system! */ 200 public long getFrameSize() { 201 return VM.getVM().getAddressSize() * frameSizeField.getValue(addr); 202 } 203 204 // Returns true, if the next frame is responsible for GC'ing oops passed as arguments 205 public boolean callerMustGCArguments(JavaThread thread) { return false; } 206 207 public String getName() { 208 return CStringUtilities.getString(nameField.getValue(addr)); 209 } 210 211 // FIXME: NOT FINISHED 212 213 // FIXME: add more accessors 214 215 public void print() { 216 printOn(System.out); 217 } 218 219 public void printOn(PrintStream tty) { 220 tty.print(getName()); 221 printComponentsOn(tty); 222 } 223 224 protected void printComponentsOn(PrintStream tty) { 225 // FIXME: add relocation information 226 tty.println(" instructions: [" + instructionsBegin() + ", " + instructionsEnd() + "), " + 227 " data: [" + dataBegin() + ", " + dataEnd() + "), " + 228 " oops: [" + oopsBegin() + ", " + oopsEnd() + "), " + 229 " frame size: " + getFrameSize()); 230 } 231 232 //-------------------------------------------------------------------------------- 233 // Internals only below this point 234 // 235 236 private int getOopsLength() { 237 return (int) oopsLengthField.getValue(addr); 238 } 239 }