comparison jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java @ 22672:1bbd4a7c274b

Rename jdk.internal.jvmci to jdk.vm.ci
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 08 Oct 2015 17:28:41 -0700
parents jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCodeCacheProvider.java@456800cd1a17
children ea58bbafd5b9
comparison
equal deleted inserted replaced
22671:97f30e4d0e95 22672:1bbd4a7c274b
1 /*
2 * Copyright (c) 2013, 2015, 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 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) {
69 int markId = (int) mark.id;
70 Field[] fields = runtime.getConfig().getClass().getDeclaredFields();
71 for (Field f : fields) {
72 if (f.getName().startsWith("MARKID_")) {
73 f.setAccessible(true);
74 try {
75 if (f.getInt(runtime.getConfig()) == markId) {
76 return f.getName();
77 }
78 } catch (Exception e) {
79 }
80 }
81 }
82 return CodeCacheProvider.super.getMarkName(mark);
83 }
84
85 /**
86 * Decodes a call target to a mnemonic if possible.
87 */
88 @Override
89 public String getTargetName(Call call) {
90 Field[] fields = runtime.getConfig().getClass().getDeclaredFields();
91 for (Field f : fields) {
92 if (f.getName().endsWith("Stub")) {
93 f.setAccessible(true);
94 try {
95 Object address = f.get(runtime.getConfig());
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, 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;
229 for (int i = 0; i < constants.length; i++) {
230 Data data = createSingleDataItem(constants[i]);
231
232 assert size % data.getAlignment() == 0 : "invalid alignment in packed constants";
233 alignment = DataSection.lcm(alignment, data.getAlignment());
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 }