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 package jdk.vm.ci.hotspot; 24 25 import static jdk.vm.ci.hotspot.HotSpotCompressedNullConstant.*; 26 27 import java.lang.reflect.*; 28 29 import jdk.vm.ci.code.*; 30 import jdk.vm.ci.code.CompilationResult.*; 31 import jdk.vm.ci.code.DataSection.*; 32 import jdk.vm.ci.common.*; 33 import jdk.vm.ci.meta.*; 34 35 /** 36 * HotSpot implementation of {@link CodeCacheProvider}. 37 */ 38 public class HotSpotCodeCacheProvider implements CodeCacheProvider { 39 40 protected final HotSpotJVMCIRuntimeProvider runtime; 41 public final HotSpotVMConfig config; 42 protected final TargetDescription target; 43 protected final RegisterConfig regConfig; 44 45 public HotSpotCodeCacheProvider(HotSpotJVMCIRuntimeProvider runtime, HotSpotVMConfig config, TargetDescription target, RegisterConfig regConfig) { 46 this.runtime = runtime; 47 this.config = config; 48 this.target = target; 49 this.regConfig = regConfig; 50 } 51 52 @Override 53 public String getMarkName(Mark mark) { 81 if (address.equals(call.target)) { 82 return f.getName() + ":0x" + Long.toHexString((Long) address); 83 } 84 } catch (Exception e) { 85 } 86 } 87 } 88 return CodeCacheProvider.super.getTargetName(call); 89 } 90 91 @Override 92 public RegisterConfig getRegisterConfig() { 93 return regConfig; 94 } 95 96 @Override 97 public int getMinimumOutgoingSize() { 98 return runtime.getConfig().runtimeCallStackSize; 99 } 100 101 public InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) { 102 HotSpotJVMCIRuntime.runtime().notifyInstall(this, installedCode, compResult); 103 return installedCode; 104 } 105 106 private InstalledCode installCode(CompilationResult compResult, HotSpotCompiledNmethod compiledCode, InstalledCode installedCode, SpeculationLog log) { 107 int result = runtime.getCompilerToVM().installCode(target, compiledCode, installedCode, log); 108 if (result != config.codeInstallResultOk) { 109 String msg = compiledCode.getInstallationFailureMessage(); 110 String resultDesc = config.getCodeInstallResultDescription(result); 111 if (msg != null) { 112 msg = String.format("Code installation failed: %s%n%s", resultDesc, msg); 113 } else { 114 msg = String.format("Code installation failed: %s", resultDesc); 115 } 116 if (result == config.codeInstallResultDependenciesInvalid) { 117 throw new AssertionError(resultDesc + " " + msg); 118 } 119 throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg); 120 } 121 return logOrDump(installedCode, compResult); 122 } 123 124 public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv, boolean isDefault) { 125 if (compResult.getId() == -1) { 126 compResult.setId(method.allocateCompileId(compResult.getEntryBCI())); 127 } 128 HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), isDefault); 129 HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(method, compResult, jvmciEnv); 130 return installCode(compResult, compiledCode, installedCode, method.getSpeculationLog()); 131 } 132 133 @Override 134 public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode predefinedInstalledCode) { 135 HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; 136 if (compResult.getId() == -1) { 137 compResult.setId(hotspotMethod.allocateCompileId(compResult.getEntryBCI())); 138 } 139 InstalledCode installedCode = predefinedInstalledCode; 140 if (installedCode == null) { 141 HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false); 142 installedCode = code; 143 } 144 HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(hotspotMethod, compResult); 145 return installCode(compResult, compiledCode, installedCode, log); 146 } 147 148 @Override 149 public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) { 150 HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; 151 return installMethod(hotspotMethod, compResult, 0L, true); 152 } 153 154 public HotSpotNmethod addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) { 155 HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method; 156 if (compResult.getId() == -1) { 157 compResult.setId(javaMethod.allocateCompileId(compResult.getEntryBCI())); 158 } 159 HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true); 160 HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, compResult); 161 CompilerToVM vm = runtime.getCompilerToVM(); 162 int result = vm.installCode(target, compiled, code, null); 163 if (result != runtime.getConfig().codeInstallResultOk) { 164 return null; 165 } 166 return code; 167 } 168 169 public boolean needsDataPatch(JavaConstant constant) { 170 return constant instanceof HotSpotMetaspaceConstant; 171 } 172 173 private Data createSingleDataItem(Constant constant) { 174 int size; 175 DataBuilder builder; 176 if (constant instanceof VMConstant) { 177 VMConstant vmConstant = (VMConstant) constant; 178 boolean compressed; 179 long raw; 180 if (constant instanceof HotSpotObjectConstant) { 181 HotSpotObjectConstant c = (HotSpotObjectConstant) vmConstant; 182 compressed = c.isCompressed(); 183 raw = 0xDEADDEADDEADDEADL; 184 } else if (constant instanceof HotSpotMetaspaceConstant) { 185 HotSpotMetaspaceConstant meta = (HotSpotMetaspaceConstant) constant; 186 compressed = meta.isCompressed(); 187 raw = meta.rawValue(); 188 } else { 189 throw new JVMCIError(String.valueOf(constant)); 190 } 191 192 size = target.getSizeInBytes(compressed ? JavaKind.Int : target.wordKind); 193 if (size == 4) { 194 builder = (buffer, patch) -> { 195 patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant))); 196 buffer.putInt((int) raw); 197 }; 198 } else { 199 assert size == 8; 200 builder = (buffer, patch) -> { 201 patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant))); 202 buffer.putLong(raw); 203 }; 204 } 205 } else if (JavaConstant.isNull(constant)) { 206 boolean compressed = COMPRESSED_NULL.equals(constant); 207 size = target.getSizeInBytes(compressed ? JavaKind.Int : target.wordKind); 208 builder = DataBuilder.zero(size); 209 } else if (constant instanceof SerializableConstant) { 210 SerializableConstant s = (SerializableConstant) constant; 211 size = s.getSerializedSize(); 212 builder = DataBuilder.serializable(s); 213 } else { 214 throw new JVMCIError(String.valueOf(constant)); 215 } 216 217 return new Data(size, size, builder); 218 } 219 220 public Data createDataItem(Constant... constants) { 221 assert constants.length > 0; 222 if (constants.length == 1) { 223 return createSingleDataItem(constants[0]); 224 } else { 225 DataBuilder[] builders = new DataBuilder[constants.length]; 226 int size = 0; 227 int alignment = 1; 233 234 builders[i] = data.getBuilder(); 235 size += data.getSize(); 236 } 237 DataBuilder ret = (buffer, patches) -> { 238 for (DataBuilder b : builders) { 239 b.emit(buffer, patches); 240 } 241 }; 242 return new Data(alignment, size, ret); 243 } 244 } 245 246 @Override 247 public TargetDescription getTarget() { 248 return target; 249 } 250 251 public String disassemble(InstalledCode code) { 252 if (code.isValid()) { 253 long codeBlob = code.getAddress(); 254 return runtime.getCompilerToVM().disassembleCodeBlob(codeBlob); 255 } 256 return null; 257 } 258 259 public SpeculationLog createSpeculationLog() { 260 return new HotSpotSpeculationLog(); 261 } 262 } | 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 package jdk.vm.ci.hotspot; 24 25 import static jdk.vm.ci.hotspot.HotSpotCompressedNullConstant.COMPRESSED_NULL; 26 27 import java.lang.reflect.Field; 28 29 import jdk.vm.ci.code.BailoutException; 30 import jdk.vm.ci.code.CodeCacheProvider; 31 import jdk.vm.ci.code.CompilationRequest; 32 import jdk.vm.ci.code.CompilationResult; 33 import jdk.vm.ci.code.CompilationResult.Call; 34 import jdk.vm.ci.code.CompilationResult.ConstantReference; 35 import jdk.vm.ci.code.CompilationResult.DataPatch; 36 import jdk.vm.ci.code.CompilationResult.Mark; 37 import jdk.vm.ci.code.DataSection; 38 import jdk.vm.ci.code.DataSection.Data; 39 import jdk.vm.ci.code.DataSection.DataBuilder; 40 import jdk.vm.ci.code.InstalledCode; 41 import jdk.vm.ci.code.RegisterConfig; 42 import jdk.vm.ci.code.TargetDescription; 43 import jdk.vm.ci.common.JVMCIError; 44 import jdk.vm.ci.meta.Constant; 45 import jdk.vm.ci.meta.JavaConstant; 46 import jdk.vm.ci.meta.SerializableConstant; 47 import jdk.vm.ci.meta.SpeculationLog; 48 import jdk.vm.ci.meta.VMConstant; 49 50 /** 51 * HotSpot implementation of {@link CodeCacheProvider}. 52 */ 53 public class HotSpotCodeCacheProvider implements CodeCacheProvider { 54 55 protected final HotSpotJVMCIRuntimeProvider runtime; 56 public final HotSpotVMConfig config; 57 protected final TargetDescription target; 58 protected final RegisterConfig regConfig; 59 60 public HotSpotCodeCacheProvider(HotSpotJVMCIRuntimeProvider runtime, HotSpotVMConfig config, TargetDescription target, RegisterConfig regConfig) { 61 this.runtime = runtime; 62 this.config = config; 63 this.target = target; 64 this.regConfig = regConfig; 65 } 66 67 @Override 68 public String getMarkName(Mark mark) { 96 if (address.equals(call.target)) { 97 return f.getName() + ":0x" + Long.toHexString((Long) address); 98 } 99 } catch (Exception e) { 100 } 101 } 102 } 103 return CodeCacheProvider.super.getTargetName(call); 104 } 105 106 @Override 107 public RegisterConfig getRegisterConfig() { 108 return regConfig; 109 } 110 111 @Override 112 public int getMinimumOutgoingSize() { 113 return runtime.getConfig().runtimeCallStackSize; 114 } 115 116 private InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) { 117 ((HotSpotJVMCIRuntime) runtime).notifyInstall(this, installedCode, compResult); 118 return installedCode; 119 } 120 121 public InstalledCode installCode(CompilationRequest compRequest, CompilationResult compResult, InstalledCode installedCode, SpeculationLog log, boolean isDefault) { 122 HotSpotResolvedJavaMethod method = compRequest != null ? (HotSpotResolvedJavaMethod) compRequest.getMethod() : null; 123 InstalledCode resultInstalledCode; 124 if (installedCode == null) { 125 if (method == null) { 126 // Must be a stub 127 resultInstalledCode = new HotSpotRuntimeStub(compResult.getName()); 128 } else { 129 resultInstalledCode = new HotSpotNmethod(method, compResult.getName(), isDefault); 130 } 131 } else { 132 resultInstalledCode = installedCode; 133 } 134 HotSpotCompiledCode compiledCode; 135 if (method != null) { 136 final int id; 137 final long jvmciEnv; 138 if (compRequest instanceof HotSpotCompilationRequest) { 139 HotSpotCompilationRequest hsCompRequest = (HotSpotCompilationRequest) compRequest; 140 id = hsCompRequest.getId(); 141 jvmciEnv = hsCompRequest.getJvmciEnv(); 142 } else { 143 id = method.allocateCompileId(compRequest.getEntryBCI()); 144 jvmciEnv = 0L; 145 } 146 compiledCode = new HotSpotCompiledNmethod(method, compResult, id, jvmciEnv); 147 } else { 148 compiledCode = new HotSpotCompiledCode(compResult); 149 } 150 int result = runtime.getCompilerToVM().installCode(target, compiledCode, resultInstalledCode, (HotSpotSpeculationLog) log); 151 if (result != config.codeInstallResultOk) { 152 String resultDesc = config.getCodeInstallResultDescription(result); 153 if (compiledCode instanceof HotSpotCompiledNmethod) { 154 HotSpotCompiledNmethod compiledNmethod = (HotSpotCompiledNmethod) compiledCode; 155 String msg = compiledNmethod.getInstallationFailureMessage(); 156 if (msg != null) { 157 msg = String.format("Code installation failed: %s%n%s", resultDesc, msg); 158 } else { 159 msg = String.format("Code installation failed: %s", resultDesc); 160 } 161 if (result == config.codeInstallResultDependenciesInvalid) { 162 throw new AssertionError(resultDesc + " " + msg); 163 } 164 throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg); 165 } else { 166 throw new BailoutException("Error installing %s: %s", compResult.getName(), resultDesc); 167 } 168 } 169 return logOrDump(resultInstalledCode, compResult); 170 } 171 172 public void invalidateInstalledCode(InstalledCode installedCode) { 173 runtime.getCompilerToVM().invalidateInstalledCode(installedCode); 174 } 175 176 public boolean needsDataPatch(JavaConstant constant) { 177 return constant instanceof HotSpotMetaspaceConstant; 178 } 179 180 private Data createSingleDataItem(Constant constant) { 181 int size; 182 DataBuilder builder; 183 if (constant instanceof VMConstant) { 184 VMConstant vmConstant = (VMConstant) constant; 185 boolean compressed; 186 if (constant instanceof HotSpotConstant) { 187 HotSpotConstant c = (HotSpotConstant) vmConstant; 188 compressed = c.isCompressed(); 189 } else { 190 throw new JVMCIError(String.valueOf(constant)); 191 } 192 193 size = compressed ? 4 : target.wordSize; 194 if (size == 4) { 195 builder = (buffer, patch) -> { 196 patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant))); 197 buffer.putInt(0xDEADDEAD); 198 }; 199 } else { 200 assert size == 8; 201 builder = (buffer, patch) -> { 202 patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant))); 203 buffer.putLong(0xDEADDEADDEADDEADL); 204 }; 205 } 206 } else if (JavaConstant.isNull(constant)) { 207 boolean compressed = COMPRESSED_NULL.equals(constant); 208 size = compressed ? 4 : target.wordSize; 209 builder = DataBuilder.zero(size); 210 } else if (constant instanceof SerializableConstant) { 211 SerializableConstant s = (SerializableConstant) constant; 212 size = s.getSerializedSize(); 213 builder = DataBuilder.serializable(s); 214 } else { 215 throw new JVMCIError(String.valueOf(constant)); 216 } 217 218 return new Data(size, size, builder); 219 } 220 221 public Data createDataItem(Constant... constants) { 222 assert constants.length > 0; 223 if (constants.length == 1) { 224 return createSingleDataItem(constants[0]); 225 } else { 226 DataBuilder[] builders = new DataBuilder[constants.length]; 227 int size = 0; 228 int alignment = 1; 234 235 builders[i] = data.getBuilder(); 236 size += data.getSize(); 237 } 238 DataBuilder ret = (buffer, patches) -> { 239 for (DataBuilder b : builders) { 240 b.emit(buffer, patches); 241 } 242 }; 243 return new Data(alignment, size, ret); 244 } 245 } 246 247 @Override 248 public TargetDescription getTarget() { 249 return target; 250 } 251 252 public String disassemble(InstalledCode code) { 253 if (code.isValid()) { 254 return runtime.getCompilerToVM().disassembleCodeBlob(code); 255 } 256 return null; 257 } 258 259 public SpeculationLog createSpeculationLog() { 260 return new HotSpotSpeculationLog(); 261 } 262 263 public long getMaxCallTargetOffset(long address) { 264 return runtime.getCompilerToVM().getMaxCallTargetOffset(address); 265 } 266 267 public boolean shouldDebugNonSafepoints() { 268 return runtime.getCompilerToVM().shouldDebugNonSafepoints(); 269 } 270 271 /** 272 * Notifies the VM of statistics for a completed compilation. 273 * 274 * @param id the identifier of the compilation 275 * @param method the method compiled 276 * @param osr specifies if the compilation was for on-stack-replacement 277 * @param processedBytecodes the number of bytecodes processed during the compilation, including 278 * the bytecodes of all inlined methods 279 * @param time the amount time spent compiling {@code method} 280 * @param timeUnitsPerSecond the granularity of the units for the {@code time} value 281 * @param installedCode the nmethod installed as a result of the compilation 282 */ 283 public void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond, InstalledCode installedCode) { 284 runtime.getCompilerToVM().notifyCompilationStatistics(id, (HotSpotResolvedJavaMethodImpl) method, osr, processedBytecodes, time, timeUnitsPerSecond, installedCode); 285 } 286 287 /** 288 * Resets all compilation statistics. 289 */ 290 public void resetCompilationStatistics() { 291 runtime.getCompilerToVM().resetCompilationStatistics(); 292 } 293 } |