27 import java.util.ArrayList;
28
29 import jdk.internal.vm.compiler.collections.EconomicSet;
30 import org.graalvm.compiler.asm.Assembler;
31 import org.graalvm.compiler.code.CompilationResult;
32 import org.graalvm.compiler.core.common.CompilationIdentifier;
33 import org.graalvm.compiler.core.common.LIRKind;
34 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
35 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
36 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
37 import org.graalvm.compiler.debug.DebugContext;
38 import org.graalvm.compiler.lir.LIR;
39 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
40 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
41 import org.graalvm.compiler.lir.framemap.FrameMap;
42 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
43 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
44 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
45 import org.graalvm.compiler.nodes.StructuredGraph;
46 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
47 import org.graalvm.compiler.phases.tiers.SuitesProvider;
48 import org.graalvm.compiler.phases.tiers.TargetProvider;
49 import org.graalvm.compiler.phases.util.Providers;
50
51 import jdk.vm.ci.code.BailoutException;
52 import jdk.vm.ci.code.CodeCacheProvider;
53 import jdk.vm.ci.code.CompilationRequest;
54 import jdk.vm.ci.code.CompiledCode;
55 import jdk.vm.ci.code.InstalledCode;
56 import jdk.vm.ci.code.Register;
57 import jdk.vm.ci.code.RegisterConfig;
58 import jdk.vm.ci.code.TargetDescription;
59 import jdk.vm.ci.code.ValueKindFactory;
60 import jdk.vm.ci.meta.ConstantReflectionProvider;
61 import jdk.vm.ci.meta.JavaKind;
62 import jdk.vm.ci.meta.MetaAccessProvider;
63 import jdk.vm.ci.meta.ResolvedJavaMethod;
64 import jdk.vm.ci.meta.SpeculationLog;
65
66 /**
136 public abstract LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph,
137 Object stub);
138
139 public abstract NodeLIRBuilderTool newNodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool lirGen);
140
141 /**
142 * Creates the assembler used to emit the machine code.
143 */
144 protected abstract Assembler createAssembler(FrameMap frameMap);
145
146 /**
147 * Creates the object used to fill in the details of a given compilation result.
148 */
149 public abstract CompilationResultBuilder newCompilationResultBuilder(LIRGenerationResult lirGenResult, FrameMap frameMap, CompilationResult compilationResult,
150 CompilationResultBuilderFactory factory);
151
152 /**
153 * Turns a Graal {@link CompilationResult} into a {@link CompiledCode} object that can be passed
154 * to the VM for code installation.
155 */
156 protected abstract CompiledCode createCompiledCode(ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult);
157
158 /**
159 * @see #createInstalledCode(DebugContext, ResolvedJavaMethod, CompilationRequest,
160 * CompilationResult, SpeculationLog, InstalledCode, boolean, Object[])
161 */
162 public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationResult compilationResult,
163 SpeculationLog speculationLog, InstalledCode predefinedInstalledCode, boolean isDefault) {
164 return createInstalledCode(debug, method, null, compilationResult, speculationLog, predefinedInstalledCode, isDefault, null);
165 }
166
167 /**
168 * @see #createInstalledCode(DebugContext, ResolvedJavaMethod, CompilationRequest,
169 * CompilationResult, SpeculationLog, InstalledCode, boolean, Object[])
170 */
171 @SuppressWarnings("try")
172 public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult,
173 SpeculationLog speculationLog, InstalledCode predefinedInstalledCode, boolean isDefault) {
174 return createInstalledCode(debug, method, compilationRequest, compilationResult, speculationLog, predefinedInstalledCode, isDefault, null);
175 }
176
177 /**
178 * Installs code based on a given compilation result.
179 *
180 * @param method the method compiled to produce {@code compiledCode} or {@code null} if the
181 * input to {@code compResult} was not a {@link ResolvedJavaMethod}
182 * @param compilationRequest the compilation request or {@code null}
183 * @param compilationResult the code to be installed
184 * @param predefinedInstalledCode a pre-allocated {@link InstalledCode} object to use as a
185 * reference to the installed code. If {@code null}, a new {@link InstalledCode}
186 * object will be created.
187 * @param speculationLog the speculation log to be used
188 * @param isDefault specifies if the installed code should be made the default implementation of
189 * {@code compRequest.getMethod()}. The default implementation for a method is the
190 * code executed for standard calls to the method. This argument is ignored if
191 * {@code compRequest == null}.
192 * @param context a custom debug context to use for the code installation
193 * @return a reference to the compiled and ready-to-run installed code
194 * @throws BailoutException if the code installation failed
195 */
196 @SuppressWarnings("try")
197 public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult,
198 SpeculationLog speculationLog, InstalledCode predefinedInstalledCode, boolean isDefault, Object[] context) {
199 Object[] debugContext = context != null ? context : new Object[]{getProviders().getCodeCache(), method, compilationResult};
200 CodeInstallationTask[] tasks;
201 synchronized (this) {
202 tasks = new CodeInstallationTask[codeInstallationTaskFactories.size()];
203 for (int i = 0; i < codeInstallationTaskFactories.size(); i++) {
204 tasks[i] = codeInstallationTaskFactories.get(i).create();
205 }
206 }
207 try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext);
208 DebugContext.Activation a = debug.activate()) {
209
210 InstalledCode installedCode;
211 try {
212 preCodeInstallationTasks(tasks, compilationResult, predefinedInstalledCode);
213 CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
214 installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
215 assert predefinedInstalledCode == null || installedCode == predefinedInstalledCode;
216 } catch (Throwable t) {
217 failCodeInstallationTasks(tasks, t);
218 throw t;
219 }
220
221 postCodeInstallationTasks(tasks, installedCode);
222
223 return installedCode;
224 } catch (Throwable e) {
225 throw debug.handle(e);
226 }
227 }
228
229 private static void failCodeInstallationTasks(CodeInstallationTask[] tasks, Throwable t) {
230 for (CodeInstallationTask task : tasks) {
231 task.installFailed(t);
232 }
233 }
234
235 private static void preCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult, InstalledCode predefinedInstalledCode) {
236 for (CodeInstallationTask task : tasks) {
237 task.preProcess(compilationResult, predefinedInstalledCode);
238 }
239 }
240
241 private static void postCodeInstallationTasks(CodeInstallationTask[] tasks, InstalledCode installedCode) {
242 try {
243 for (CodeInstallationTask task : tasks) {
244 task.postProcess(installedCode);
245 }
246 } catch (Throwable t) {
247 installedCode.invalidate();
248 throw t;
249 }
250 }
251
252 /**
253 * Installs code based on a given compilation result.
254 *
255 * @param method the method compiled to produce {@code compiledCode} or {@code null} if the
256 * input to {@code compResult} was not a {@link ResolvedJavaMethod}
257 * @param compilationRequest the request or {@code null}
258 * @param compilationResult the code to be compiled
259 * @return a reference to the compiled and ready-to-run installed code
260 * @throws BailoutException if the code installation failed
261 */
262 public InstalledCode addInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult) {
263 return createInstalledCode(debug, method, compilationRequest, compilationResult, null, null, false);
264 }
293 public abstract EconomicSet<Register> translateToCallerRegisters(EconomicSet<Register> calleeRegisters);
294
295 /**
296 * Gets the compilation id for a given {@link ResolvedJavaMethod}. Returns
297 * {@code CompilationIdentifier#INVALID_COMPILATION_ID} in case there is no such id.
298 *
299 * @param resolvedJavaMethod
300 */
301 public CompilationIdentifier getCompilationIdentifier(ResolvedJavaMethod resolvedJavaMethod) {
302 return CompilationIdentifier.INVALID_COMPILATION_ID;
303 }
304
305 /**
306 * Encapsulates custom tasks done before and after code installation.
307 */
308 public abstract static class CodeInstallationTask {
309 /**
310 * Task to run before code installation.
311 *
312 * @param compilationResult the code about to be installed
313 * @param predefinedInstalledCode a pre-allocated {@link InstalledCode} object that will be
314 * used as a reference to the installed code. May be {@code null}.
315 *
316 */
317 public void preProcess(CompilationResult compilationResult, InstalledCode predefinedInstalledCode) {
318 }
319
320 /**
321 * Task to run after the code is installed.
322 *
323 * @param installedCode a reference to the installed code
324 */
325 public void postProcess(InstalledCode installedCode) {
326 }
327
328 /**
329 * Invoked after {@link #preProcess} when code installation fails.
330 *
331 * @param cause the cause of the installation failure
332 */
333 public void installFailed(Throwable cause) {
334 }
335 }
336
337 /**
338 * Creates code installation tasks.
339 */
340 public abstract static class CodeInstallationTaskFactory {
341 public abstract CodeInstallationTask create();
342 }
343 }
|
27 import java.util.ArrayList;
28
29 import jdk.internal.vm.compiler.collections.EconomicSet;
30 import org.graalvm.compiler.asm.Assembler;
31 import org.graalvm.compiler.code.CompilationResult;
32 import org.graalvm.compiler.core.common.CompilationIdentifier;
33 import org.graalvm.compiler.core.common.LIRKind;
34 import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
35 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
36 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
37 import org.graalvm.compiler.debug.DebugContext;
38 import org.graalvm.compiler.lir.LIR;
39 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
40 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
41 import org.graalvm.compiler.lir.framemap.FrameMap;
42 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
43 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
44 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
45 import org.graalvm.compiler.nodes.StructuredGraph;
46 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
47 import org.graalvm.compiler.options.OptionValues;
48 import org.graalvm.compiler.phases.tiers.SuitesProvider;
49 import org.graalvm.compiler.phases.tiers.TargetProvider;
50 import org.graalvm.compiler.phases.util.Providers;
51
52 import jdk.vm.ci.code.BailoutException;
53 import jdk.vm.ci.code.CodeCacheProvider;
54 import jdk.vm.ci.code.CompilationRequest;
55 import jdk.vm.ci.code.CompiledCode;
56 import jdk.vm.ci.code.InstalledCode;
57 import jdk.vm.ci.code.Register;
58 import jdk.vm.ci.code.RegisterConfig;
59 import jdk.vm.ci.code.TargetDescription;
60 import jdk.vm.ci.code.ValueKindFactory;
61 import jdk.vm.ci.meta.ConstantReflectionProvider;
62 import jdk.vm.ci.meta.JavaKind;
63 import jdk.vm.ci.meta.MetaAccessProvider;
64 import jdk.vm.ci.meta.ResolvedJavaMethod;
65 import jdk.vm.ci.meta.SpeculationLog;
66
67 /**
137 public abstract LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, FrameMapBuilder frameMapBuilder, StructuredGraph graph,
138 Object stub);
139
140 public abstract NodeLIRBuilderTool newNodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool lirGen);
141
142 /**
143 * Creates the assembler used to emit the machine code.
144 */
145 protected abstract Assembler createAssembler(FrameMap frameMap);
146
147 /**
148 * Creates the object used to fill in the details of a given compilation result.
149 */
150 public abstract CompilationResultBuilder newCompilationResultBuilder(LIRGenerationResult lirGenResult, FrameMap frameMap, CompilationResult compilationResult,
151 CompilationResultBuilderFactory factory);
152
153 /**
154 * Turns a Graal {@link CompilationResult} into a {@link CompiledCode} object that can be passed
155 * to the VM for code installation.
156 */
157 protected abstract CompiledCode createCompiledCode(ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult, boolean isDefault, OptionValues options);
158
159 /**
160 * @see #createInstalledCode(DebugContext, ResolvedJavaMethod, CompilationRequest,
161 * CompilationResult, SpeculationLog, InstalledCode, boolean, Object[])
162 */
163 public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationResult compilationResult,
164 SpeculationLog speculationLog, InstalledCode predefinedInstalledCode, boolean isDefault) {
165 return createInstalledCode(debug, method, null, compilationResult, speculationLog, predefinedInstalledCode, isDefault, null);
166 }
167
168 /**
169 * @see #createInstalledCode(DebugContext, ResolvedJavaMethod, CompilationRequest,
170 * CompilationResult, SpeculationLog, InstalledCode, boolean, Object[])
171 */
172 @SuppressWarnings("try")
173 public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult,
174 SpeculationLog speculationLog, InstalledCode predefinedInstalledCode, boolean isDefault) {
175 return createInstalledCode(debug, method, compilationRequest, compilationResult, speculationLog, predefinedInstalledCode, isDefault, null);
176 }
177
178 /**
179 * Installs code based on a given compilation result.
180 *
181 * @param method the method compiled to produce {@code compiledCode} or {@code null} if the
182 * input to {@code compResult} was not a {@link ResolvedJavaMethod}
183 * @param compilationRequest the compilation request or {@code null}
184 * @param compilationResult the code to be installed
185 * @param predefinedInstalledCode a pre-allocated {@link InstalledCode} object to use as a
186 * reference to the installed code. If {@code null}, a new {@link InstalledCode}
187 * object will be created.
188 * @param speculationLog the speculation log to be used
189 * @param isDefault specifies if the installed code should be made the default implementation of
190 * {@code compRequest.getMethod()}. The default implementation for a method is the
191 * code executed for standard calls to the method. This argument is ignored if
192 * {@code compRequest == null}.
193 * @param context a custom debug context to use for the code installation
194 * @return a reference to the compiled and ready-to-run installed code
195 * @throws BailoutException if the code installation failed
196 * @throws IllegalArgumentException if {@code installedCode != null} and this platform does not
197 * {@linkplain CodeCacheProvider#installCode support} a predefined
198 * {@link InstalledCode} object
199 */
200 @SuppressWarnings("try")
201 public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult,
202 SpeculationLog speculationLog, InstalledCode predefinedInstalledCode, boolean isDefault, Object[] context) {
203 Object[] debugContext = context != null ? context : new Object[]{getProviders().getCodeCache(), method, compilationResult};
204 CodeInstallationTask[] tasks;
205 synchronized (this) {
206 tasks = new CodeInstallationTask[codeInstallationTaskFactories.size()];
207 for (int i = 0; i < codeInstallationTaskFactories.size(); i++) {
208 tasks[i] = codeInstallationTaskFactories.get(i).create();
209 }
210 }
211 try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext);
212 DebugContext.Activation a = debug.activate()) {
213
214 InstalledCode installedCode;
215 try {
216 preCodeInstallationTasks(tasks, compilationResult);
217 CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult, isDefault, debug.getOptions());
218 installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
219 assert predefinedInstalledCode == null || installedCode == predefinedInstalledCode;
220 } catch (Throwable t) {
221 failCodeInstallationTasks(tasks, t);
222 throw t;
223 }
224
225 postCodeInstallationTasks(tasks, compilationResult, installedCode);
226
227 return installedCode;
228 } catch (Throwable e) {
229 throw debug.handle(e);
230 }
231 }
232
233 private static void failCodeInstallationTasks(CodeInstallationTask[] tasks, Throwable t) {
234 for (CodeInstallationTask task : tasks) {
235 task.installFailed(t);
236 }
237 }
238
239 private static void preCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult) {
240 for (CodeInstallationTask task : tasks) {
241 task.preProcess(compilationResult);
242 }
243 }
244
245 private static void postCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult, InstalledCode installedCode) {
246 try {
247 for (CodeInstallationTask task : tasks) {
248 task.postProcess(compilationResult, installedCode);
249 }
250 } catch (Throwable t) {
251 installedCode.invalidate();
252 throw t;
253 }
254 }
255
256 /**
257 * Installs code based on a given compilation result.
258 *
259 * @param method the method compiled to produce {@code compiledCode} or {@code null} if the
260 * input to {@code compResult} was not a {@link ResolvedJavaMethod}
261 * @param compilationRequest the request or {@code null}
262 * @param compilationResult the code to be compiled
263 * @return a reference to the compiled and ready-to-run installed code
264 * @throws BailoutException if the code installation failed
265 */
266 public InstalledCode addInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult) {
267 return createInstalledCode(debug, method, compilationRequest, compilationResult, null, null, false);
268 }
297 public abstract EconomicSet<Register> translateToCallerRegisters(EconomicSet<Register> calleeRegisters);
298
299 /**
300 * Gets the compilation id for a given {@link ResolvedJavaMethod}. Returns
301 * {@code CompilationIdentifier#INVALID_COMPILATION_ID} in case there is no such id.
302 *
303 * @param resolvedJavaMethod
304 */
305 public CompilationIdentifier getCompilationIdentifier(ResolvedJavaMethod resolvedJavaMethod) {
306 return CompilationIdentifier.INVALID_COMPILATION_ID;
307 }
308
309 /**
310 * Encapsulates custom tasks done before and after code installation.
311 */
312 public abstract static class CodeInstallationTask {
313 /**
314 * Task to run before code installation.
315 *
316 * @param compilationResult the code about to be installed
317 *
318 */
319 public void preProcess(CompilationResult compilationResult) {
320 }
321
322 /**
323 * Task to run after the code is installed.
324 *
325 * @param compilationResult the code about to be installed
326 * @param installedCode a reference to the installed code
327 */
328 public void postProcess(CompilationResult compilationResult, InstalledCode installedCode) {
329 }
330
331 /**
332 * Invoked after {@link #preProcess} when code installation fails.
333 *
334 * @param cause the cause of the installation failure
335 */
336 public void installFailed(Throwable cause) {
337 }
338 }
339
340 /**
341 * Creates code installation tasks.
342 */
343 public abstract static class CodeInstallationTaskFactory {
344 public abstract CodeInstallationTask create();
345 }
346 }
|