001/* 002 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.hotspot; 024 025import static jdk.internal.jvmci.hotspot.HotSpotCompressedNullConstant.*; 026 027import java.lang.reflect.*; 028 029import jdk.internal.jvmci.code.*; 030import jdk.internal.jvmci.code.CompilationResult.*; 031import jdk.internal.jvmci.code.DataSection.*; 032import jdk.internal.jvmci.common.*; 033import jdk.internal.jvmci.meta.*; 034 035/** 036 * HotSpot implementation of {@link CodeCacheProvider}. 037 */ 038public class HotSpotCodeCacheProvider implements CodeCacheProvider { 039 040 protected final HotSpotJVMCIRuntimeProvider runtime; 041 public final HotSpotVMConfig config; 042 protected final TargetDescription target; 043 protected final RegisterConfig regConfig; 044 045 public HotSpotCodeCacheProvider(HotSpotJVMCIRuntimeProvider runtime, HotSpotVMConfig config, TargetDescription target, RegisterConfig regConfig) { 046 this.runtime = runtime; 047 this.config = config; 048 this.target = target; 049 this.regConfig = regConfig; 050 } 051 052 @Override 053 public String getMarkName(Mark mark) { 054 int markId = (int) mark.id; 055 Field[] fields = runtime.getConfig().getClass().getDeclaredFields(); 056 for (Field f : fields) { 057 if (f.getName().startsWith("MARKID_")) { 058 f.setAccessible(true); 059 try { 060 if (f.getInt(runtime.getConfig()) == markId) { 061 return f.getName(); 062 } 063 } catch (Exception e) { 064 } 065 } 066 } 067 return CodeCacheProvider.super.getMarkName(mark); 068 } 069 070 /** 071 * Decodes a call target to a mnemonic if possible. 072 */ 073 @Override 074 public String getTargetName(Call call) { 075 Field[] fields = runtime.getConfig().getClass().getDeclaredFields(); 076 for (Field f : fields) { 077 if (f.getName().endsWith("Stub")) { 078 f.setAccessible(true); 079 try { 080 Object address = f.get(runtime.getConfig()); 081 if (address.equals(call.target)) { 082 return f.getName() + ":0x" + Long.toHexString((Long) address); 083 } 084 } catch (Exception e) { 085 } 086 } 087 } 088 return CodeCacheProvider.super.getTargetName(call); 089 } 090 091 @Override 092 public RegisterConfig getRegisterConfig() { 093 return regConfig; 094 } 095 096 @Override 097 public int getMinimumOutgoingSize() { 098 return runtime.getConfig().runtimeCallStackSize; 099 } 100 101 public InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) { 102 HotSpotJVMCIRuntime.runtime().notifyInstall(this, installedCode, compResult); 103 return installedCode; 104 } 105 106 public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv, boolean isDefault) { 107 if (compResult.getId() == -1) { 108 compResult.setId(method.allocateCompileId(compResult.getEntryBCI())); 109 } 110 HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), isDefault); 111 runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, compResult, jvmciEnv), installedCode, method.getSpeculationLog()); 112 return logOrDump(installedCode, compResult); 113 } 114 115 @Override 116 public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode predefinedInstalledCode) { 117 HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; 118 if (compResult.getId() == -1) { 119 compResult.setId(hotspotMethod.allocateCompileId(compResult.getEntryBCI())); 120 } 121 InstalledCode installedCode = predefinedInstalledCode; 122 if (installedCode == null) { 123 HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false); 124 installedCode = code; 125 } 126 HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(hotspotMethod, compResult); 127 int result = runtime.getCompilerToVM().installCode(compiledCode, installedCode, log); 128 if (result != config.codeInstallResultOk) { 129 String msg = compiledCode.getInstallationFailureMessage(); 130 String resultDesc = config.getCodeInstallResultDescription(result); 131 if (msg != null) { 132 msg = String.format("Code installation failed: %s%n%s", resultDesc, msg); 133 } else { 134 msg = String.format("Code installation failed: %s", resultDesc); 135 } 136 if (result == config.codeInstallResultDependenciesInvalid) { 137 throw new AssertionError(resultDesc + " " + msg); 138 } 139 throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg); 140 } 141 return logOrDump(installedCode, compResult); 142 } 143 144 @Override 145 public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) { 146 HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; 147 return installMethod(hotspotMethod, compResult, 0L, true); 148 } 149 150 public HotSpotNmethod addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) { 151 HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method; 152 if (compResult.getId() == -1) { 153 compResult.setId(javaMethod.allocateCompileId(compResult.getEntryBCI())); 154 } 155 HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true); 156 HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, compResult); 157 CompilerToVM vm = runtime.getCompilerToVM(); 158 int result = vm.installCode(compiled, code, null); 159 if (result != runtime.getConfig().codeInstallResultOk) { 160 return null; 161 } 162 return code; 163 } 164 165 public boolean needsDataPatch(JavaConstant constant) { 166 return constant instanceof HotSpotMetaspaceConstant; 167 } 168 169 public Data createDataItem(Constant constant) { 170 int size; 171 DataBuilder builder; 172 if (constant instanceof VMConstant) { 173 VMConstant vmConstant = (VMConstant) constant; 174 boolean compressed; 175 long raw; 176 if (constant instanceof HotSpotObjectConstant) { 177 HotSpotObjectConstant c = (HotSpotObjectConstant) vmConstant; 178 compressed = c.isCompressed(); 179 raw = 0xDEADDEADDEADDEADL; 180 } else if (constant instanceof HotSpotMetaspaceConstant) { 181 HotSpotMetaspaceConstant meta = (HotSpotMetaspaceConstant) constant; 182 compressed = meta.isCompressed(); 183 raw = meta.rawValue(); 184 } else { 185 throw new JVMCIError(String.valueOf(constant)); 186 } 187 188 size = target.getSizeInBytes(compressed ? Kind.Int : target.wordKind); 189 if (size == 4) { 190 builder = (buffer, patch) -> { 191 patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant))); 192 buffer.putInt((int) raw); 193 }; 194 } else { 195 assert size == 8; 196 builder = (buffer, patch) -> { 197 patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant))); 198 buffer.putLong(raw); 199 }; 200 } 201 } else if (JavaConstant.isNull(constant)) { 202 boolean compressed = COMPRESSED_NULL.equals(constant); 203 size = target.getSizeInBytes(compressed ? Kind.Int : target.wordKind); 204 builder = DataBuilder.zero(size); 205 } else if (constant instanceof SerializableConstant) { 206 SerializableConstant s = (SerializableConstant) constant; 207 size = s.getSerializedSize(); 208 builder = DataBuilder.serializable(s); 209 } else { 210 throw new JVMCIError(String.valueOf(constant)); 211 } 212 213 return new Data(size, size, builder); 214 } 215 216 @Override 217 public TargetDescription getTarget() { 218 return target; 219 } 220 221 public String disassemble(InstalledCode code) { 222 if (code.isValid()) { 223 long codeBlob = code.getAddress(); 224 return runtime.getCompilerToVM().disassembleCodeBlob(codeBlob); 225 } 226 return null; 227 } 228 229 public SpeculationLog createSpeculationLog() { 230 return new HotSpotSpeculationLog(); 231 } 232}