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